| /** |
| * 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); |
| } |
| } |
| } |
| |
| }; |