Famo.us how to select the surfaces in a scrollView that were not clicked on? - famo.us

I have a scrollView that contains 5 surfaces. If I click on a surface, I would like the others to be either faded out, z-indexed far behind or translated off the screen. The problem is, I do not know how to implement the selection of the other surfaces.
Famo.us Code:
Famous.Engine = famous.core.Engine;
Famous.Surface = famous.core.Surface;
Famous.RenderNode = famous.core.RenderNode;
Famous.Transform = famous.core.Transform;
Famous.Modifier = famous.core.Modifier;
Famous.EventHandler = famous.core.EventHandler;
Famous.ContainerSurface = famous.surfaces.ContainerSurface;
Famous.ScrollView = famous.views.Scrollview;
Famous.Transitionable = famous.transitions.Transitionable;
Famous.SnapTransition = famous.transitions.SnapTransition;
Famous.Easing = famous.transitions.Easing;
Famous.TransitionableTransform = famous.transitions.TransitionableTransform;
Famous.StateModifier = famous.modifiers.StateModifier;
var projectsList = document.getElementById('projects-list');
var mainContext = Famous.Engine.createContext(projectsList);
var scrollView = new Famous.ScrollView({
direction: 0
});
Famous.Transitionable.registerMethod('snap', Famous.SnapTransition);
var snap = { method: 'snap', period: 600, dampingRatio: 0.6 }
var surfaces = [];
for (var i = 0; i < 5; i++) {
var surface = new Famous.Surface({
size: [undefined, undefined],
properties: {
backgroundColor: "#fff", // "hsl(" + (i * 360 / 40) + ", 100%, 50%)",
textAlign: "center"
}
});
surface.open = false;
surface.state = new Famous.Modifier();
surface.trans = new Famous.Transitionable(500);
surface.state.sizeFrom(function(){
return [this.trans.get(), undefined];
}.bind(surface));
surface.node = new Famous.RenderNode();
surface.node.add(surface.state).add(surface);
surface.pipe(scrollView);
surface.on('click',function(event){
if (this.open) {
this.trans.halt();
this.trans.set(500, snap);
/* place code to reverse the animation that placed the other surfaces off-screen here */
} else {
this.trans.halt();
this.trans.set($(window).width(), snap);
/* how to implement the selection of the other surfaces that were not clicked */
}
this.open = !this.open;
}.bind(surface));
surfaces.push(surface.node);
// sequenceFrom method sets the collection of renderables under the Scrollview instance's control. You can pass array of items or ViewSequence object.
scrollView.sequenceFrom(surfaces);
}
mainContext.add(scrollView);
An example Surface HTML Generated:
<div class="famous-surface" style="background-color: rgb(255, 255, 255); text-align: center; width: 500px; height: 662px; opacity: 0.999999; transform-origin: 0% 0% 0px; transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);">
<div class="surface-content-wrapper">
<div class="container-fluid">
<section class="row project-preview">
<article class="col-lg-12">
<img class="img-responsive" src="/images/project_name_header.png">
<h1>A Surface</h1>
<div class="project-stats">
</article>
</section>
</div>
</div>
</div>
All the surfaces in the scrollView have the same class attributes. So if I click on the first surface, how do I tell famo.us to do something with the remaining four surfaces?
When I click on the specific surface the console logs for this and event.currentTarget are:
this: Surface { _matrix=[16], _opacity=1, _origin=[2], more...}
project...875d127 (line 116)
event: <div class="famous-surface" style="background-color: rgb(255, 255, 255); text-align: center; width: 500px; height: 662px; opacity: 0.999999; transform-origin: 0% 0% 0px; transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);">

You can use the scrollview's backing array directly.
surfaces
Once you get here, you'll have access to the nodes that are in your surfaces array. From there, it's a matter of excluding the surface that was returned as this from the array and interacting with the properties that you placed on your surface object, which you can do using underscore.
_(surfaces).each(function(node) {
surface = node._child;
if (surface != clickedSurface) {
//Do whatever you want to do to the node or surfaces
}
});
Your instinct that you should avoid using the siblings relationship is right. Further, I'd bet that you'd run into same nasty bugs in the future if you tried to manipulate your layout at all. You should stick to your famo.us objects whenever possible.

UPDATE: Please see answer given by #obsidian06 for proper solution.
For now, I'm going with Underscore's each() block that animates the surface's opacity on the click event.
var $otherSurfacesNotClicked = $(event.currentTarget).siblings();
_.each($otherSurfacesNotClicked, function(surface){
console.log("surface in each loop: ", surface);
$(surface).animate({opacity: 0});
});
There's a performance hit on mobile. Most likely the problem is using the jQuery animate(). Need to find the native Famo.us way of performing the same task.

Related

Using XTK or AMI.js to display Freesurfer while/pial objects on T1.mgz

I'd like to recreate a web version of FreeSurfer pial/white surfaces overlaid on T1.mgz similar to the first freeview image at https://surfer.nmr.mgh.harvard.edu/fswiki/FsTutorial/PialEdits_freeview. Using XTK I can get something that hints at that using advice from Othographic Projection in XTK. The code I used to create the image (along with kruft from multiple attempts) is below the image.
Is this possible with XTK or should I switch over to AMI.js (which has freesurfer surfaces and MGZ file formats on their roadmap but are not implemented)?
In either case, pointers to how to accomplish this would be appreciated.
Thanks.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>FS XTK test</title>
</head>
<body>
<script type="text/javascript" src="/Xdevel/lib/google-closure-library/closure/goog/base.js"></script>
<script type="text/javascript" src="/Xdevel/xtk-deps.js"></script>
<script type="text/javascript" src="/Xdevel/xtk_xdat.gui.js"></script>
<script type="text/javascript">
var view2D_X = null;
var view2D_Y = null;
var view2D_Z = null;
var view3D = null;
var volume3D = null;
var meshes = new Array(6);
var meshFiles = new Array(6);
var t1File = 'T1.mgz';
meshFiles[0]='lh.orig';
meshFiles[1]='rh.orig';
meshFiles[2]='lh.pial';
meshFiles[3]='rh.pial';
meshFiles[4]='lh.white.pial';
meshFiles[5]='rh.white.pial';
var colors = [ //Matlab jet(28)
[ 0, 1, 0],
[ 0, 1, 0],
[ 1, 0, 0],
[ 1, 0, 0],
[ 0, 0, 1],
[ 0, 0, 1]
];
function setView(pos)
{
switch(pos)
{
case 1:
camPos=[ 0, 0, -1, 0,
-1, 0, -0, 0,
0, 1, 0, 0,
1, 0, -1, 1];
break;
case 2:
camPos=[-1, 0, 0, 0,
0, 0, 1, 0,
0, 1, -0, 0,
0, -1, -1, 1];
break;
default: //Case 3
camPos=[-1, 0, -0, 0,
-0, 1, -0, 0,
0, 0, 1, 0,
0, -0, -1, 1];
break;
}
camPos[14] = 200*camPos[14]; //zoomout
view3D.camera.view=new Float32Array(camPos);
}
// include all used X-classes here
// this is only required when using the xtk-deps.js file
goog.require('X.renderer2D');
goog.require('X.renderer3D');
goog.require('X.mesh');
function addLoadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function() {
if (oldonload) {
oldonload();
}
func();
}
}
}
</script>
<div id="view3D_div" style="background-color: #000; width: 399px; height: 399px;"></div>
<script type="text/javascript">
function loadMeshes()
{
for (var a = 0; a < 6; a++)
{
try
{
meshes[a] = new X.mesh();
meshes[a].file=meshFiles[a];
meshes[a].color = colors[a];
meshes[a].visible=true;
view3D.add(meshes[a]);
}
catch(err)
{
console.log('failed to load: '+meshFiles[a]);
console.log(err.message);
}
}
}
var _meshConfig = {
'width' : 399,
'height' : 399,
'unknown' : 180.5,
'diff' : 0.3
};
function setMainSlice()
{
// console.log('height: ' + height + ' width: ' + width);
console.log('X: ' + volume3D.indexX + 'Y: ' + volume3D.indexY + 'Z: ' + volume3D.indexZ);
_meshConfig.unknown=volume3D.indexZ+92.5;
console.log('width: '+_meshConfig.width + ' height: ' + _meshConfig.height + ' unknown: ' + _meshConfig.unknown);
view3D.camera._perspective=X.matrix.makeOrtho(X.matrix.identity(), -(_meshConfig.width/2), (_meshConfig.width/2), -(_meshConfig.height/2), (_meshConfig.height/2), _meshConfig.unknown+_meshConfig.diff, _meshConfig.unknown-_meshConfig.diff);
// view3D.camera._perspective=goog.vec.Mat4.createFromValues(1,0,0,0,0,1,0,0,0,0,1,0,volume3D.indexX,volume3D.indexY,volume3D.indexZ,1);
// view3D.camera._perspective=goog.vec.Mat4.createFromValues(0.005,0,0,0, 0,0.005,0,0, 0,0,3,0, 0,0,256+(volume3D.indexZ*2),1);
}
addLoadEvent(function () {
view3D = new X.renderer3D();
view3D.container = 'view3D_div';
view3D.init();
volume3D = new X.volume();
volume3D.file = t1File;
// volume3D.labelmap.file='all.white.mgz';
view3D.add(volume3D);
loadMeshes();
setView(3);
// view3D.camera.position=[-0, 0, 90];
// view3D.camera.view[14] = -200;
view3D.render();
view3D.onShowtime = function () {
view2D_X.onScroll = setMainSlice;
view2D_X.add(volume3D);
view2D_X.render();
view2D_Y.onScroll = setMainSlice;
view2D_Y.add(volume3D);
view2D_Y.render();
view2D_Z.onScroll = setMainSlice;
view2D_Z.add(volume3D);
view2D_Z.render();
setView(3);
};
var gui = new dat.GUI();
var anat_folder = gui.addFolder('T1');
anat_folder.add(volume3D,'visible');
anat_folder.add(volume3D,'opacity',0,1);
anat_folder.add(volume3D,'indexX');
anat_folder.add(volume3D,'indexY');
anat_folder.add(volume3D,'indexZ',0,256);
anat_folder.open();
var lh_orig_folder = gui.addFolder('Freesurfer lh.orig');
lh_orig_folder.add(meshes[0],'visible');
lh_orig_folder.add(meshes[0],'opacity',0,1);
lh_orig_folder.addColor(meshes[0],'color');
// lh_orig_folder.open();
var rh_orig_folder = gui.addFolder('Freesurfer rh.orig');
rh_orig_folder.add(meshes[1],'visible');
rh_orig_folder.add(meshes[1],'opacity',0,1);
rh_orig_folder.addColor(meshes[1],'color');
// rh_orig_folder.open();
var lh_pial_folder = gui.addFolder('Freesurfer lh.pial');
lh_pial_folder.add(meshes[2],'visible');
lh_pial_folder.add(meshes[2],'opacity',0,1);
lh_pial_folder.addColor(meshes[2],'color');
// lh_pial_folder.open();
var rh_pial_folder = gui.addFolder('Freesurfer rh.pial');
rh_pial_folder.add(meshes[3],'visible');
rh_pial_folder.add(meshes[3],'opacity',0,1);
rh_pial_folder.addColor(meshes[3],'color');
// rh_pial_folder.open();
var lh_white_folder = gui.addFolder('Freesurfer lh.white');
lh_white_folder.add(meshes[4],'visible');
lh_white_folder.add(meshes[4],'opacity',0,1);
lh_white_folder.addColor(meshes[4],'color');
// lh_white_folder.open();
var rh_white_folder = gui.addFolder('Freesurfer rh.white');
rh_white_folder.add(meshes[5],'visible');
rh_white_folder.add(meshes[5],'opacity',0,1);
rh_white_folder.addColor(meshes[5],'color');
// rh_white_folder.open();
var mesh_folder = gui.addFolder('Mesh');
mesh_folder.add(_meshConfig,'height');
mesh_folder.add(_meshConfig,'width');
mesh_folder.add(_meshConfig,'unknown');
mesh_folder.open();
for (c in gui.__controllers)
{
gui.__controllers[c].onFinishChange(update);
}
});
</script>
<table style="border-collapse: collapse">
<tr>
<td style="background-color: red;">
<div id="view2D_X_div" style="background-color: #000; width: 131px; height: 131px;"></div>
<script type="text/javascript">
addLoadEvent(function () {
view2D_X = new X.renderer2D();
view2D_X.container = 'view2D_X_div';
view2D_X.orientation = 'X';
view2D_X.init();
});
</script>
</td>
<td style="background-color: green;">
<div id="view2D_Y_div" style="background-color: #000; width: 131px; height: 131px;"></div>
<script type="text/javascript">
addLoadEvent(function () {
view2D_Y = new X.renderer2D();
view2D_Y.container = 'view2D_Y_div';
view2D_Y.orientation = 'Y';
view2D_Y.init();
});
</script>
</td>
<td style="background-color: blue;">
<div id="view2D_Z_div" style="background-color: #000; width: 131px; height: 131px;"></div>
<script type="text/javascript">
addLoadEvent(function () {
view2D_Z = new X.renderer2D();
view2D_Z.container = 'view2D_Z_div';
view2D_Z.orientation = 'Z';
view2D_Z.init();
});
</script>
</td>
</tr>
<tr>
<td style="background-color: red;">
<!-- <button onClick="setView([-90,0,0]);">Set View</button>-->
<button onClick="setView(1);">Set View</button>
</td>
<td style="background-color: green;">
<!-- <button onClick="setView([0,90,0]);">Set View</button>-->
<button onClick="setView(2);">Set View</button>
</td>
<td style="background-color: blue;">
<!-- <button onClick="setView([0,0,90]);">Set View</button>-->
<button onClick="setView(3);">Set View</button>
</td>
</tr>
</table>
Green is orig<br>
Red is pial<br>
Blue is white<br>
</body>
</html>
You can now do it in AMI (thanks to your PR: https://fnndsc.github.io/ami/#viewers_quadview)
Display intersection between a mesh and a plane
Post process the intersection to display the contours.
There are different techniques to display mesh/plane intersection:
With a stencil buffer (https://github.com/daign/clipping-with-caps)
Playing the the mesh opacity (https://github.com/FNNDSC/ami/tree/dev/examples/viewers_quadview)
All those techniques are computationally expensive at it requires 3 renders pass to display contours of 1 mesh and there may be a better approach but not sure what would be the best alternative.
HTH

nnnick chart.js - Custom Tooltip on Line Chart

We are using nnnick chart.js (open source chart) in our application for reporting purpose.There is a requirement to show the Custom tool-tip in the line chart.
As of now , Normal chart tooltip is showing based on the X-axis and Y axis dataset values. But Here we want to show the Dynamic additional data in the Tooltip.
For Example ,
Let us take a Student Enrollment .
here
X Axis Value - Enrollment Month (Jan,Feb,Mar....etc)
Y Axis Value - Number of Enrollments (10,20,30...ect)
After the Line chart is plotted , Now it is displaying (Jan ,10) in the tooltip.
We have to show the Number of Male & Female student details in the tool tip On mouse over the data point Jan 10 (i.e) (Jan,10, Male:5 , Female 5 ).
If you see the above screen shot , Green color is toop-tip is the normal one which is a built-in option. Red Color highlighted tool-tip is the one we are expecting.
Please provide any suggestion on this .
So you can achieve this using the custom tool tip function in the newer (not sure when it was included) version of chart js. You can have it display anything you want in place of a normal tooltip so in this case i have added a tooltip and a tooltip-overview.
The really annoying thing is though in this function you are not told which index you are currently showing a tooltip for. Two ways to solve this, override the showToolTip function so it actually passes this information or do a quick little hack to extract the label from the tooltip text and get the index from the labels array (hacky but quicker so i went for this one in the example)
So here is a quick example based upon the samples in chartjs samples folder. This is just a quick example so you would prob need to play around with the positioning and stuff until its what you need.
Chart.defaults.global.pointHitDetectionRadius = 1;
Chart.defaults.global.customTooltips = function(tooltip) {
// Tooltip Element
var tooltipEl = $('#chartjs-tooltip');
var tooltipOverviewEl = $('#chartjs-tooltip-overview');
// Hide if no tooltip
if (!tooltip) {
tooltipEl.css({
opacity: 0
});
tooltipOverviewEl.css({
opacity: 0
});
return;
}
//really annoyingly we don;t get told which index this comes from so going to have
//to extract the label from the text :( and then find the index based on that
//other option here is to override the the whole showTooltip in chartjs and have the index passed
var label = tooltip.text.substr(0, tooltip.text.indexOf(':'));
var labelIndex = labels.indexOf(label);
var maleEnrolmentNumber = maleEnrolments[labelIndex];
var femaleEnrolmentNumber = FemaleEnrolments[labelIndex];
// Set caret Position
tooltipEl.removeClass('above below');
tooltipEl.addClass(tooltip.yAlign);
// Set Text
tooltipEl.html(tooltip.text);
//quick an ddirty could use an actualy template here
var tooltipOverviewElHtml = "<div> Overall : " + (maleEnrolmentNumber + femaleEnrolmentNumber) + "</div>";
tooltipOverviewElHtml += "<div> Male : " + (maleEnrolmentNumber) + "</div>";
tooltipOverviewElHtml += "<div> Female : " + (femaleEnrolmentNumber) + "</div>";
tooltipOverviewEl.html(tooltipOverviewElHtml);
// Find Y Location on page
var top;
if (tooltip.yAlign == 'above') {
top = tooltip.y - tooltip.caretHeight - tooltip.caretPadding;
} else {
top = tooltip.y + tooltip.caretHeight + tooltip.caretPadding;
}
// Display, position, and set styles for font
tooltipEl.css({
opacity: 1,
left: tooltip.chart.canvas.offsetLeft + tooltip.x + 'px',
top: tooltip.chart.canvas.offsetTop + top + 'px',
fontFamily: tooltip.fontFamily,
fontSize: tooltip.fontSize,
fontStyle: tooltip.fontStyle,
});
tooltipOverviewEl.css({
opacity: 1,
fontFamily: tooltip.fontFamily,
fontSize: tooltip.fontSize,
fontStyle: tooltip.fontStyle,
});
};
var maleEnrolments = [5, 20, 15, 20, 20, 30, 50]; // Integer array for male each value is corresponding to each month
var FemaleEnrolments = [5, 0, 15, 20, 30, 30, 20]; // Integer array for Female each value is corresponding to each month
var labels = ["Jan", "February", "March", "April", "May", "June", "July"]; //Enrollment by Month
var lineChartData = {
labels: labels,
datasets: [{
label: "Student Details",
fillColor: "rgba(151,187,205,0.2)",
strokeColor: "rgba(151,187,205,1)",
pointColor: "rgba(151,187,205,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(151,187,205,1)",
data: [10, 20, 30, 40, 50, 60, 70], //enrollement Details overall (Male + Female)
}]
};
var ctx2 = document.getElementById("chart2").getContext("2d");
window.myLine = new Chart(ctx2).Line(lineChartData, {
responsive: true
});
#canvas-holder1 {
width: 300px;
margin: 20px auto;
}
#canvas-holder2 {
width: 50%;
margin: 20px 25%;
position:relative;
}
#chartjs-tooltip-overview {
opacity: 0;
position: absolute;
background: rgba(0, 0, 0, .7);
color: white;
padding: 3px;
border-radius: 3px;
-webkit-transition: all .1s ease;
transition: all .1s ease;
pointer-events: none;
-webkit-transform: translate(-50%, 0);
transform: translate(-50%, 0);
left:200px;
top:0px
}
#chartjs-tooltip {
opacity: 1;
position: absolute;
background: rgba(0, 0, 0, .7);
color: white;
padding: 3px;
border-radius: 3px;
-webkit-transition: all .1s ease;
transition: all .1s ease;
pointer-events: none;
-webkit-transform: translate(-50%, 0);
transform: translate(-50%, 0);
}
.chartjs-tooltip-key {
display:inline-block;
width:10px;
height:10px;
}
<script src="https://raw.githack.com/nnnick/Chart.js/master/Chart.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="canvas-holder2">
<div id="chartjs-tooltip-overview"></div>
<div id="chartjs-tooltip"></div>
<canvas id="chart2" width="600" height="600" />
</div>

Do famo.us layouts like SequentialLayout participate in the render tree?

When using a SequentialLayout in trying to apply StateModifiers to Surface objects that had been added to a layout, it looks like some unexpected behavior happens:
When applying transformations via setTransform on a StateModifier, I expect to see the transformation applied from the origin of the Surface in question.
Instead, the transform is applied from an origin of 0,0 in relation to the parent SequentialLayout
Given the code below, the above behavior seems to make no logical sense (for context, I am working on a sorting algorithms demo, using famo.us):
/* globals define */
define(function(require, exports, module) {
'use strict';
// import dependencies
var Engine = require('famous/core/Engine');
var Modifier = require('famous/core/Modifier');
var Transform = require('famous/core/Transform');
var Surface = require('famous/core/Surface');
var StateModifier = require('famous/modifiers/StateModifier');
var SequentialLayout = require('famous/views/SequentialLayout');
// create the main context
var mainContext = Engine.createContext();
// your app here
var surfaces = [];
// Sorter
var Sort = require('sort');
var arr = [100,25,20,15,30,-20,-10,10,0];
var min = Math.min.apply(null, arr);
var base_dims = [ 50, 50 ];
arr.forEach(function(el) {
surfaces.push(new Surface({
content: el,
size: base_dims.map(function(d) { return d + (el - min); }),
properties: {
backgroundColor: 'rgb(240, 238, 233)',
textAlign: 'center',
padding: '5px',
border: '2px solid rgb(210, 208, 203)',
marginTop: '50px',
marginLeft: '50px'
}
}));
});
var sequentialLayout = new SequentialLayout({
direction: 0,
itemSpacing:20
});
sequentialLayout.sequenceFrom(surfaces);
mainContext.add(sequentialLayout);
var swap_modifiers = [
new StateModifier({}), new StateModifier({})
];
Sort.bubble_sort_iterative(arr, function(first_swap_index, second_swap_index) {
swap_modifiers[0].setTransform(
Transform.translate(300, 0, 0),
{ duration : 750, curve: 'linear' }
);
swap_modifiers[1].setTransform(
Transform.translate(300, 0, 0),
{ duration : 750, curve: 'linear' }
);
mainContext.add(swap_modifiers[0]).add(surfaces[first_swap_index]);
mainContext.add(swap_modifiers[1]).add(surfaces[second_swap_index]);
});
});
A surface has no origin, a (state-)modifier has an origin. Since you don't provide any origin vaue, the default value is set up, which is [0, 0]. See more:
http://famo.us/university/lessons/#/famous-101/positioning/8
Think of your SequentialLayout as a Render Node in your tree. Adding surfaces to SequentialLayout is in essence adding individual nodes to that tree branch. SequentialLayout happens to be adding each item at the same level in the tree.
Sort.bubble_sort_iterative(... changes the location of the surfaces by adding them to the mainContext of your application. This is the same level as the sequentialLayout and makes their origin the same origin as the sequentialLayout. Not what you wanted!
Remember: Adding a modifier to a context will make that context the parent node.
Without knowing the specifics of the above code, we know that we can add a View rather than surfaces to the sequentialLayout and could transition the View's modifiers within each of those items without changing their location in the render tree.
A simple code example of views in the sequential layout:
arr.forEach(function(el) {
var surfSize = base_dims.map(function(d) { return d + (el - min); });
console.log(size);
var view = new View();
view.mod = new StateModifier({ size: surfSize });
view.surface = new Surface({
content: el,
size: [undefined, undefined],
properties: {
backgroundColor: 'rgb(240, 238, 233)',
textAlign: 'center',
padding: '5px',
border: '2px solid rgb(210, 208, 203)',
marginTop: '50px',
marginLeft: '50px'
}
});
view.add(view.mod).add(view.surface);
surfaces.push(view);
});
Trying to swap out the views from one to the other will give you some unexpected results. It would be better to just swap out the options and content values.

translate3d with a transition not being accelerated (being blocked by JS)

I am trying to animate a (100% width) div offscreen by moving it using translate3d(100%,0,0) with a 1s transition. I believe the animation should be fully offloaded to the GPU and not affected by JS, but it is freezing as I do JS computations.
Note that it doesn't freeze when I use a pixel value, e.g. translate3d(500px,0,0)
See this in effect: http://jsfiddle.net/khufzte9/
This is the code I'm using:
CSS:
html, body {
margin: 0;
padding: 0;
}
#blue {
background-color: blue;
width: 100%;
height: 100%;
-webkit-transition: all 1s;
}
HTML:
<div id='blue'></div>
JS:
document.body.addEventListener('click', function () {
var blue = document.querySelector('#blue');
blue.style.transform = 'translate3d(100%,0,0)';
// Do some blocking work after the animation starts
setTimeout(function () {
for (var i = 0; i < 1000000000; i++) {
var j = 5/3;
}
}, 300);
});
Any thoughts or advice would be much appreciated!

Multiple Canvas in ScaleRaphael - circle in 2nd canvas appears in 1st

I just got started with Raphael, but I don't get it right to make multiple canvases in ScaleRaphael
(I#m using this to make the site after responsive > are there alternatives for that?
Multiple ScaleRaphael Canvases: http://jsfiddle.net/karo/gMyP5/13/
or full view: http://jsfiddle.net/karo/gMyP5/13/embedded/result/
A strange thing happens here.
The red circle should be in the 2nd div but if you look in the code with eg. firebug in the fullview then you see that both svgs are in the inside a Why is that?
Do you have any idea for me?
Thanks Kaor
my code:
HTML
<div id="wrapper">
<div id="paper"></div>
<br>
<div id="paper2"></div>
</div>
JavaScript:
var paper = new ScaleRaphael("paper",200,200);
var circle = paper.circle(100, 100, 60).attr({fill:'red'});
var paper2 = new ScaleRaphael("paper2",200,200);
var circle2 = paper2.circle(50, 50, 30).attr({fill:'black'});
function resizePaper(){
var win = $(this);
paper.changeSize(win.width(), win.height(), true, false);
paper2.changeSize(win.width(), win.height(), true, false);
}
resizePaper();
$(window).resize(resizePaper);
CSS
#wrapper
{
position:relative;
}
#paper {
background-color: lightgray;
width:100%;
height:200px;
position:relative!important;
}
#paper2
{
background-color: orange;
width:100%;
height:100px;
position:relative!important;
}
svg
{
position:absolute!important;
top:0;
left:0;
}
ScaleRaphael only supports one canvas. In the code you can see it re-referencing the first existing svggroup or vmlgroup element.
You do not need ScaleRaphael to do what you are doing. Since version 2 Raphael has included Paper.setViewBox and it always included Paper.setSize, which together do this already.
I found an issue and a workaround how it works....
Have a look here: http://jsfiddle.net/karo/r4qvt/12/
I have first the paper div and then the red div
<div id="paper"></div>
<div id="red"></div>
</div>
</div>
And if I make the redpaper for the div "red" and the rectangle in it before I make the paperGrey and "talk to the" first div. THEN IT WORKS
var redpaper = new ScaleRaphael("red",300,200);
redpaper.rect(0, 0, 250, 100).attr({fill:'red'});
var paperGrey = new ScaleRaphael("paper",400,200);
var circle = paperGrey.circle(40, 140, 60).attr({fill:'blue'});
If I do it the OTHER WAY ROUND IT DOESNT WORK
var paperGrey = new ScaleRaphael("paper",400,200);
var circle = paperGrey.circle(40, 140, 60).attr({fill:'blue'});
var redpaper = new ScaleRaphael("red",300,200);
redpaper.rect(0, 0, 250, 100).attr({fill:'red'});
...strange, but I found a solution ;)