blob: f7a1891d4af78b07f69a056bda1bf691dea05643 [file] [log] [blame]
/**
* Copyright (c) 2006-2015, JGraph Ltd
* Copyright (c) 2006-2015, Gaudenz Alder
*/
var mxEffects =
{
/**
* Class: mxEffects
*
* Provides animation effects.
*/
/**
* Function: animateChanges
*
* Asynchronous animated move operation. See also: <mxMorphing>.
*
* Example:
*
* (code)
* graph.model.addListener(mxEvent.CHANGE, function(sender, evt)
* {
* var changes = evt.getProperty('edit').changes;
*
* if (changes.length < 10)
* {
* mxEffects.animateChanges(graph, changes);
* }
* });
* (end)
*
* Parameters:
*
* graph - <mxGraph> that received the changes.
* changes - Array of changes to be animated.
* done - Optional function argument that is invoked after the
* last step of the animation.
*/
animateChanges: function(graph, changes, done)
{
var maxStep = 10;
var step = 0;
var animate = function()
{
var isRequired = false;
for (var i = 0; i < changes.length; i++)
{
var change = changes[i];
if (change instanceof mxGeometryChange ||
change instanceof mxTerminalChange ||
change instanceof mxValueChange ||
change instanceof mxChildChange ||
change instanceof mxStyleChange)
{
var state = graph.getView().getState(change.cell || change.child, false);
if (state != null)
{
isRequired = true;
if (change.constructor != mxGeometryChange || graph.model.isEdge(change.cell))
{
mxUtils.setOpacity(state.shape.node, 100 * step / maxStep);
}
else
{
var scale = graph.getView().scale;
var dx = (change.geometry.x - change.previous.x) * scale;
var dy = (change.geometry.y - change.previous.y) * scale;
var sx = (change.geometry.width - change.previous.width) * scale;
var sy = (change.geometry.height - change.previous.height) * scale;
if (step == 0)
{
state.x -= dx;
state.y -= dy;
state.width -= sx;
state.height -= sy;
}
else
{
state.x += dx / maxStep;
state.y += dy / maxStep;
state.width += sx / maxStep;
state.height += sy / maxStep;
}
graph.cellRenderer.redraw(state);
// Fades all connected edges and children
mxEffects.cascadeOpacity(graph, change.cell, 100 * step / maxStep);
}
}
}
}
if (step < maxStep && isRequired)
{
step++;
window.setTimeout(animate, delay);
}
else if (done != null)
{
done();
}
};
var delay = 30;
animate();
},
/**
* Function: cascadeOpacity
*
* Sets the opacity on the given cell and its descendants.
*
* Parameters:
*
* graph - <mxGraph> that contains the cells.
* cell - <mxCell> to set the opacity for.
* opacity - New value for the opacity in %.
*/
cascadeOpacity: function(graph, cell, opacity)
{
// Fades all children
var childCount = graph.model.getChildCount(cell);
for (var i=0; i<childCount; i++)
{
var child = graph.model.getChildAt(cell, i);
var childState = graph.getView().getState(child);
if (childState != null)
{
mxUtils.setOpacity(childState.shape.node, opacity);
mxEffects.cascadeOpacity(graph, child, opacity);
}
}
// Fades all connected edges
var edges = graph.model.getEdges(cell);
if (edges != null)
{
for (var i=0; i<edges.length; i++)
{
var edgeState = graph.getView().getState(edges[i]);
if (edgeState != null)
{
mxUtils.setOpacity(edgeState.shape.node, opacity);
}
}
}
},
/**
* Function: fadeOut
*
* Asynchronous fade-out operation.
*/
fadeOut: function(node, from, remove, step, delay, isEnabled)
{
step = step || 40;
delay = delay || 30;
var opacity = from || 100;
mxUtils.setOpacity(node, opacity);
if (isEnabled || isEnabled == null)
{
var f = function()
{
opacity = Math.max(opacity-step, 0);
mxUtils.setOpacity(node, opacity);
if (opacity > 0)
{
window.setTimeout(f, delay);
}
else
{
node.style.visibility = 'hidden';
if (remove && node.parentNode)
{
node.parentNode.removeChild(node);
}
}
};
window.setTimeout(f, delay);
}
else
{
node.style.visibility = 'hidden';
if (remove && node.parentNode)
{
node.parentNode.removeChild(node);
}
}
}
};