123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546 |
- /**
- * Explore plugin.
- */
- Draw.loadPlugin(function(editorUi)
- {
- // Adds resource for action
- mxResources.parse('animation=Animation...');
- // Adds action
- editorUi.actions.addAction('animation', function()
- {
- if (this.animationWindow == null)
- {
- // LATER: Check outline window for initial placement
- this.animationWindow = new AnimationWindow(editorUi, (document.body.offsetWidth - 480) / 2,
- 120, 640, 480);
- this.animationWindow.window.setVisible(true);
- }
- else
- {
- this.animationWindow.window.setVisible(!this.animationWindow.window.isVisible());
- }
- });
-
- var menu = editorUi.menus.get('extras');
- var oldFunct = menu.funct;
-
- menu.funct = function(menu, parent)
- {
- oldFunct.apply(this, arguments);
-
- editorUi.menus.addMenuItems(menu, ['-', 'animation'], parent);
- };
-
- // For animation and fading
- function getNodesForCells(graph, cells)
- {
- var nodes = [];
-
- for (var i = 0; i < cells.length; i++)
- {
- var state = graph.view.getState(cells[i]);
-
- if (state != null)
- {
- var shapes = graph.cellRenderer.getShapesForState(state);
-
- for (var j = 0; j < shapes.length; j++)
- {
- if (shapes[j] != null && shapes[j].node != null)
- {
- nodes.push(shapes[j].node);
- }
- }
-
- // Adds folding icon
- if (state.control != null && state.control.node != null)
- {
- nodes.push(state.control.node);
- }
- }
- }
-
- return nodes;
- };
-
- function fadeIn(nodes)
- {
- if (nodes != null)
- {
- for (var i = 0; i < nodes.length; i++)
- {
- mxUtils.setPrefixedStyle(nodes[i].style, 'transition', null);
- nodes[i].style.opacity = '0';
- }
-
- window.setTimeout(function()
- {
- for (var i = 0; i < nodes.length; i++)
- {
- mxUtils.setPrefixedStyle(nodes[i].style, 'transition', 'all 1s ease-in-out');
- nodes[i].style.opacity = '1';
- }
- }, 0);
- }
- };
-
- function fadeOut(nodes)
- {
- if (nodes != null)
- {
- for (var i = 0; i < nodes.length; i++)
- {
- mxUtils.setPrefixedStyle(nodes[i].style, 'transition', null);
- nodes[i].style.opacity = '1';
- }
-
- window.setTimeout(function()
- {
- for (var i = 0; i < nodes.length; i++)
- {
- mxUtils.setPrefixedStyle(nodes[i].style, 'transition', 'all 1s ease-in-out');
- nodes[i].style.opacity = '0';
- }
- }, 0);
- }
- };
-
- function createEdgeAnimation(state)
- {
- var pts = state.absolutePoints.slice();
- var segs = state.segments;
- var total = state.length;
- var n = pts.length;
- return {
- execute: function(step, steps)
- {
- if (state.shape != null)
- {
- var pts2 = [pts[0]];
- var dist = total * step / steps;
-
- for (var i = 1; i < n; i++)
- {
- if (dist <= segs[i - 1])
- {
- pts2.push(new mxPoint(pts[i - 1].x + (pts[i].x - pts[i - 1].x) * dist / segs[i - 1],
- pts[i - 1].y + (pts[i].y - pts[i - 1].y) * dist / segs[i - 1]));
-
- break;
- }
- else
- {
- dist -= segs[i - 1];
- pts2.push(pts[i]);
- }
- }
-
- state.shape.points = pts2;
- state.shape.redraw();
- }
- },
- stop: function()
- {
- if (state.shape != null)
- {
- state.shape.points = pts;
- state.shape.redraw();
- }
- }
- };
- };
-
- function createVertexAnimation(state)
- {
- var bds = new mxRectangle.fromRectangle(state.shape.bounds);
- var ttr = null;
-
- if (state.text != null && state.text.node != null && state.text.node.firstChild != null)
- {
- ttr = state.text.node.firstChild.getAttribute('transform');
- }
-
- return {
- execute: function(step, steps)
- {
- if (state.shape != null)
- {
- var f = step / steps;
- state.shape.bounds = new mxRectangle(bds.x, bds.y, bds.width * f, bds.height);
- state.shape.redraw();
-
- // Text is animated using CSS3 transitions
- if (ttr != null)
- {
- state.text.node.firstChild.setAttribute('transform', ttr + ' scale(' + f + ',1)');
- }
- }
- },
- stop: function()
- {
- if (state.shape != null)
- {
- state.shape.bounds = bds;
- state.shape.redraw();
-
- if (ttr != null)
- {
- state.text.node.firstChild.setAttribute('transform', ttr);
- }
- }
- }
- };
- };
- function animateCells(graph, cells, steps, delay)
- {
- steps = (steps != null) ? steps : 30;
- delay = (delay != null) ? delay : 30;
-
- var animations = [];
-
- for (var i = 0; i < cells.length; i++)
- {
- var state = graph.view.getState(cells[i]);
- if (state != null && state.shape != null && graph.model.isEdge(state.cell) &&
- state.absolutePoints != null && state.absolutePoints.length > 1)
- {
- animations.push(createEdgeAnimation(state));
- }
- else if (state != null && graph.model.isVertex(state.cell) &&
- state.shape != null && state.shape.bounds != null)
- {
- animations.push(createVertexAnimation(state));
- // TODO: include descendants
- }
- }
-
- var step = 0;
-
- function animate()
- {
- if (step == steps)
- {
- window.clearInterval(thread);
-
- for (var i = 0; i < animations.length; i++)
- {
- animations[i].stop();
- }
- }
- else
- {
- for (var i = 0; i < animations.length; i++)
- {
- animations[i].execute(step, steps);
- }
-
- step++;
- }
- }
-
- var thread = window.setInterval(animate, delay);
- animate();
- };
-
- function mapCell(cell, clone, mapping)
- {
- mapping = (mapping != null) ? mapping : new Object();
- mapping[cell.id] = clone;
-
- var childCount = cell.getChildCount();
-
- for (var i = 0; i < childCount; i++)
- {
- mapCell(cell.getChildAt(i), clone.getChildAt(i), mapping);
- }
-
- return mapping;
- };
-
- var allowedToRun = false;
- var running = false;
-
- function stop()
- {
- allowedToRun = false;
- };
-
- function run(graph, steps, loop)
- {
- if (!running)
- {
- allowedToRun = true;
- running = true;
- graph.getModel().beginUpdate();
- try
- {
- for (var id in graph.getModel().cells)
- {
- var cell = graph.getModel().cells[id];
-
- if (graph.getModel().isVertex(cell) || graph.getModel().isEdge(cell))
- {
- graph.setCellStyles('opacity', '0', [cell]);
- graph.setCellStyles('noLabel', '1', [cell]);
- }
- }
- }
- finally
- {
- graph.getModel().endUpdate();
- }
-
- var mapping = mapCell(editorUi.editor.graph.getModel().getRoot(), graph.getModel().getRoot());
- var step = 0;
-
- function next()
- {
- if (allowedToRun && step < steps.length)
- {
- var tokens = steps[step].split(' ');
-
- if (tokens.length > 0)
- {
- if (tokens[0] == 'wait' && tokens.length > 1)
- {
- window.setTimeout(function()
- {
- step++;
- next();
- }, parseFloat(tokens[1]));
- }
- else
- {
- if (tokens.length > 1)
- {
- var cell = mapping[tokens[1]];
-
- if (cell != null)
- {
- if (tokens[0] == 'show')
- {
- graph.setCellStyles('opacity', '100', [cell]);
- graph.setCellStyles('noLabel', null, [cell]);
-
- if (tokens.length > 2 && tokens[2] == 'fade')
- {
- fadeIn(getNodesForCells(graph, [cell]));
- }
- else
- {
- animateCells(graph, [cell]);
- }
- }
- else if (tokens[0] == 'hide')
- {
- fadeOut(getNodesForCells(graph, [cell]));
- }
- }
- else
- {
- console.log('cell not found', id, steps[step]);
- }
- }
-
- step++;
- next();
- }
- }
- }
- else
- {
- running = false;
-
- if (loop)
- {
- // Workaround for edge animation
- graph.refresh();
- run(graph, steps, loop);
- }
- }
- };
-
- next();
- }
- };
-
- /**
- *
- */
- var AnimationWindow = function(editorUi, x, y, w, h)
- {
- var table = document.createElement('table');
- table.style.width = '100%';
- table.style.height = '100%';
- var tbody = document.createElement('tbody');
- var tr1 = document.createElement('tr');
- var td11 = document.createElement('td');
- td11.style.width = '140px';
- var td12 = document.createElement('td');
- var tr2 = document.createElement('tr');
- tr2.style.height = '40px';
- var td21 = document.createElement('td');
- td21.setAttribute('colspan', '2');
-
- var list = document.createElement('textarea');
- list.style.overflow = 'auto';
- list.style.width = '100%';
- list.style.height = '100%';
- td11.appendChild(list);
-
- var root = editorUi.editor.graph.getModel().getRoot();
-
- if (root.value != null && typeof(root.value) == 'object')
- {
- list.value = root.value.getAttribute('animation');
- }
-
- var container = document.createElement('div');
- container.style.border = '1px solid lightGray';
- container.style.background = '#ffffff';
- container.style.width = '100%';
- container.style.height = '100%';
- container.style.overflow = 'auto';
-
- mxEvent.disableContextMenu(container);
- td12.appendChild(container);
-
- var graph = new Graph(container);
- graph.setEnabled(false);
- graph.setPanning(true);
- graph.foldingEnabled = false;
- graph.panningHandler.ignoreCell = true;
- graph.panningHandler.useLeftButtonForPanning = true;
- graph.minFitScale = null;
- graph.maxFitScale = null;
- graph.centerZoom = true;
- var fadeInBtn = mxUtils.button('Fade In', function()
- {
- var cells = editorUi.editor.graph.getSelectionCells();
-
- if (cells.length > 0)
- {
- for (var i = 0; i < cells.length; i++)
- {
- list.value = list.value + 'show ' + cells[i].id + ' fade\n';
- }
-
- list.value = list.value + 'wait 1000\n';
- }
- });
- td21.appendChild(fadeInBtn);
-
- var animateBtn = mxUtils.button('Wipe In', function()
- {
- var cells = editorUi.editor.graph.getSelectionCells();
-
- if (cells.length > 0)
- {
- for (var i = 0; i < cells.length; i++)
- {
- list.value = list.value + 'show ' + cells[i].id + '\n';
- }
-
- list.value = list.value + 'wait 1000\n';
- }
- });
- td21.appendChild(animateBtn);
-
- var addBtn = mxUtils.button('Fade Out', function()
- {
- var cells = editorUi.editor.graph.getSelectionCells();
-
- if (cells.length > 0)
- {
- for (var i = 0; i < cells.length; i++)
- {
- list.value = list.value + 'hide ' + cells[i].id + '\n';
- }
- list.value = list.value + 'wait 1000\n';
- }
- });
- td21.appendChild(addBtn);
-
- var waitBtn = mxUtils.button('Wait', function()
- {
- list.value = list.value + 'wait 1000\n';
- });
- td21.appendChild(waitBtn);
-
- var runBtn = mxUtils.button('Preview', function()
- {
- graph.getModel().clear();
- graph.getModel().setRoot(graph.cloneCells([editorUi.editor.graph.getModel().getRoot()])[0]);
- graph.maxFitScale = 1;
- graph.fit(8);
- graph.center();
-
- run(graph, list.value.split('\n'));
- });
- td21.appendChild(runBtn);
-
- var stopBtn = mxUtils.button('Stop', function()
- {
- graph.getModel().clear();
- stop();
- });
- td21.appendChild(stopBtn);
-
- var applyBtn = mxUtils.button('Apply', function()
- {
- editorUi.editor.graph.setAttributeForCell(root, 'animation', list.value);
- });
- td21.appendChild(applyBtn);
-
- tr1.appendChild(td11);
- tr1.appendChild(td12);
- tbody.appendChild(tr1);
- tr2.appendChild(td21);
- tbody.appendChild(tr2);
- table.appendChild(tbody);
- this.window = new mxWindow('Animation', table, x, y, w, h, true, true);
- this.window.destroyOnClose = false;
- this.window.setMaximizable(false);
- this.window.setResizable(true);
- this.window.setClosable(true);
- this.window.setVisible(true);
- };
-
- // Autostart in chromeless mode
- if (editorUi.editor.chromeless)
- {
- function startAnimation()
- {
- var root = editorUi.editor.graph.getModel().getRoot();
- var result = false;
-
- if (root.value != null && typeof(root.value) == 'object')
- {
- var desc = root.value.getAttribute('animation');
-
- if (desc != null)
- {
- run(editorUi.editor.graph, desc.split('\n'), true);
- result = true;
- }
- }
-
- return result;
- };
-
- // Wait for file to be loaded if no animation data is present
- if (!startAnimation())
- {
- editorUi.editor.addListener('fileLoaded', startAnimation);
- }
- }
- });
|