diff options
author | Ulrich-Matthias Schäfer <ulima.ums@googlemail.com> | 2018-12-01 17:24:04 +0100 |
---|---|---|
committer | Ulrich-Matthias Schäfer <ulima.ums@googlemail.com> | 2018-12-01 17:24:04 +0100 |
commit | 51dafe62e02c4298859ac8f1c5945899241fac23 (patch) | |
tree | 864908d07b63337611f67364838245037b7fe85b | |
parent | 9546418c5ed9b1876132b43dff1ae690c3ec4e24 (diff) | |
download | svg.js-51dafe62e02c4298859ac8f1c5945899241fac23.tar.gz svg.js-51dafe62e02c4298859ac8f1c5945899241fac23.zip |
fix playgrounds, delete unneeded files
-rw-r--r-- | CHANGELOG.md | 3 | ||||
-rw-r--r-- | LICENSE.txt | 2 | ||||
-rw-r--r-- | dirty.html | 520 | ||||
-rw-r--r-- | playgrounds/colors/index.html | 2 | ||||
-rw-r--r-- | playgrounds/colors/main.js | 2 | ||||
-rw-r--r-- | playgrounds/matrix/drag.js | 2 | ||||
-rw-r--r-- | playgrounds/matrix/index.html | 2 | ||||
-rw-r--r-- | playgrounds/transforms/index.html | 2 | ||||
-rw-r--r-- | spec/SpecRunner.html | 10 | ||||
-rw-r--r-- | src/modules/core/event.js | 28 | ||||
-rw-r--r-- | src/utils/adopter.js | 2 | ||||
-rw-r--r-- | todo.md | 107 | ||||
-rw-r--r-- | useCases.md | 330 |
13 files changed, 31 insertions, 981 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index ceb62a2..e564245 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,8 @@ The document follows the conventions described in [“Keep a CHANGELOG”](http: - added possibility to pass in additional attribues to element creators e.g. `canvas.rect({x:100})` or `canvas.rect(100, 100, {x:100})` (#796) - added `SVG.List` (#645) - added `words()` and `element()` to `Dom` because of (#935) +- added lab, lch, hsl and cmyk color spaces (#790) +- added `random()` method on `SVG.Color` to create random colors of different kinds (#939) ### Removed - removed `SVG.Array.split()` function @@ -41,7 +43,6 @@ The document follows the conventions described in [“Keep a CHANGELOG”](http: - removed `SVG.Nested` (#809) - removed `show()` from `SVG.A` to avoid name clash (#802) - removed `size()` from `SVG.Text` to avoid name clash (#799) -- removed `move(), dmove()` etc for groups to avoid inconsistencies, we will expect users to use transforms to move around groups as they should (especially since they are much simpler now). - removed `native()` function - removed `Bare` in favour of `Dom` (#935) diff --git a/LICENSE.txt b/LICENSE.txt index 148b70a..41b1b10 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,4 +1,4 @@ -Copyright (c) 2012-2017 Wout Fierens +Copyright (c) 2012-2018 Wout Fierens https://svgdotjs.github.io/ Permission is hereby granted, free of charge, to any person obtaining diff --git a/dirty.html b/dirty.html deleted file mode 100644 index 900c738..0000000 --- a/dirty.html +++ /dev/null @@ -1,520 +0,0 @@ - -<!DOCTYPE html> -<html lang="en" dir="ltr"> -<head> - <meta charset="utf-8"> - <title></title> - <script type="text/javascript" src="dist/polyfills.js"></script> - <script type="text/javascript" src="dist/polyfillsIE.js"></script> - <script type="text/javascript" src="dist/svg.min.js"></script> - - - - - - -</head> -<body style="background-color: #c7c7ff"> - -<!-- <div id="absolute"><label>Absolute: <input type="range" min="0" max="1" step="0.01"></slider></label><span></span></div> -<div id="position"><label>Position: <input type="range" min="0" max="5" step="0.01"></slider></label><span></span></div> --> - -<button name="back1000">Back 1000</button> -<button name="back100">Back 100</button> -<button name="forth100">Forth 100</button> -<button name="forth1000">Forth 1000</button> -<button name="speed2">Speed x2</button> -<button name="speed05">Speed x0.5</button> -<button name="stop">Stop</button> -<button name="finish">Finish</button> -<button name="pause">Pause</button> -<button name="play">Play</button> -<button name="reverse">Reverse</button> -<span id="displayText"></span> -<br> - -<!-- Making the svg --> -<svg width=1000px height=500px id="canvas"> - <rect x=50 y=100 width=200 height=100 stroke=none stroke-width=2 /> -</svg> - -<!-- Modifying the svg --> -<script type="text/javascript"> - -// import SVG from './src/svg.js' -// -// window.SVG = SVG - -var rect = SVG('rect').hide() -var sin = Math.sin -var pi = Math.PI -var round = Math.round - -function getColor(t) { - var a = round(80 * sin(2 * pi * t / 0.5 + 0.01) + 150) - var b = round(50 * sin(2 * pi * t / 0.5 + 4.6) + 200) - var c = round(100 * sin(2 * pi * t / 0.5 + 2.3) + 150) - var color = 'rgb('+ a +','+ b +','+ c +')' - return color -} - -// var rect1 = SVG('<rect>').addTo('svg').size(50, 50).move(100, 100) -// var rect2 = SVG('<rect>').addTo('svg').size(50, 50).move(100, 200) -// -// var anim1 = new SVG.Runner(1000).element(rect1).loop(5, true, 1000).move(200, 100) -// var anim2 = new SVG.Runner(1000).element(rect2).loop(5, true, 1000).move(200, 200) -// -// SVG('#absolute').on('input slide', function (e) { -// var val = e.target.value -// document.querySelector('#absolute span').textContent = val -// anim1.absolute(val) -// }) -// -// SVG('#position').on('input slide', function (e) { -// var val = e.target.value -// document.querySelector('#position span').textContent = val -// anim2.position(val) -// }) - - -// rect.animate(4000) -// .during(t => rect.transform({scale: sqrt(1 + t), rotate: 720 * t})) -// .after(500, ()=> {rect.attr('stroke', 'white')}) -// .queue(() => rect.attr('fill', getColor(0))) -// .animate(1500, 500, true) -// .queue(()=> {}, t => rect.attr('fill', getColor(t))) -// .animate(1000, true) -// .move(200, 200) -// .size(300, 300) - -// SVG.Animator.timeout(()=> { rect.animate().pause() }, 1000 - 10) -// SVG.Animator.timeout(()=> { rect.animate().play() }, 2000 - 10) - - - -// SVG('rect') -// .clone().show() -// .animate() -// .move(300, 200) - -// -// for (let i = 0 ; i < 15; i++) { -// for (let j = 0 ; j < 10; j++) { -// -// // Make the rect -// let o = i + j -// let rect = SVG('rect').clone().show() -// .width(40).height(40) -// .x(50 * i).y(50 * j) -// .attr('fill', getColor(o * 0.1)) -// -// // Move the rect -// let {cx, cy} = rect.bbox() -// -// // Animate the rect -// rect.animate(3000, Math.random() * 2000) -// // .during(t => rect.transform({rotate: 700 * t, origin: [cx, cy]})) -// .transform({rotate: 720}, true) -// // .during(t => rect.attr('transform', `rotate(${700 * t})`)) -// .during(t => rect.attr('fill', getColor(o * 0.1 + t))) -// } -// } - -var canvas = SVG('#canvas') - -canvas.attr('viewBox', null) - -SVG.defaults.timeline.ease = '-' - -var r = new SVG.Runner(1000) -var t = new SVG.Timeline().persist(true) - -r.schedule(t, 200) - .animate(500).loop(5, true, 100) - .animate(600, 200, 'absolute') - .animate(600, 300) - .animate(600, 300, 'now') - .animate(1000, 0, 'absolute').loop(6, true) - -var schedule = t.schedule() - -schedule.forEach(function (s, i) { - var rect = canvas.rect(s.duration / 10, 25) - .move(100 + s.start/10, 100 + i*30) - .attr('fill', '#000') - - s.runner.element(rect) - .attr('fill', getColor(i*0.1)) - - // if (i===0) - // s.runner.during(console.log) -}) - -// t.play() - -var mover = canvas.line(100, 100, 100, 300).attr('stroke', 'black') -mover.clone().insertAfter(mover) -canvas.line(100, 300, 800, 300).attr('stroke', 'black') - -var text = SVG('#displayText') - -t.on('time', function (e) { - mover.x(100 + e.detail/10) - text.node.textContent = e.detail -}) - -t.on('finished', function (e) { - console.log('finished') -}) - -SVG('button[name="back100"]').on('click', function (e) { - t.seek(-100) -}) -SVG('button[name="back1000"]').on('click', function (e) { - t.seek(-1000) -}) -SVG('button[name="forth100"]').on('click', function (e) { - t.seek(100) -}) -SVG('button[name="forth1000"]').on('click', function (e) { - t.seek(1000) -}) - -SVG('button[name="speed2"]').on('click', function (e) { - t.speed(2) -}) - -SVG('button[name="speed05"]').on('click', function (e) { - t.speed(0.5) -}) - -SVG('button[name="pause"]').on('click', function (e) { - t.pause() -}) - -SVG('button[name="play"]').on('click', function (e) { - t.play() -}) - -SVG('button[name="stop"]').on('click', function (e) { - t.stop() -}) - -SVG('button[name="finish"]').on('click', function (e) { - t.finish() -}) - -SVG('button[name="reverse"]').on('click', function (e) { - t.reverse() -}) - - -canvas.rect(100, 100).on('click', function (e) { - e.target.instance.animate() - .move(Math.random()*1000, Math.random()*750) - .timeline().on('finished', function (e) { - console.log('rect finished') - }) -}) - -console.log(schedule) - - - - - - - - - - - - - - - - -// var bla = SVG('<rect>').size(0, 0).move(200, 200).addTo('svg') -// bla.animate().size(220, 200).queue(null, console.log) - -// var randPoint = (x = 50, y = 50) => [ -// Math.random() * 100 - 50 + x, -// Math.random() * 100 - 50 + y -// ] -// -// var poly = SVG('<polygon>').plot([ -// randPoint(), -// randPoint(), -// randPoint(), -// randPoint(), -// randPoint() -// ]).attr({fill: 'none', stroke: 'black'}).addTo('svg') -// var polyAni = poly.animate(new SVG.Spring(3000, 0)) -// -// SVG.on(document, 'click', function (e) { -// polyAni.plot([ -// randPoint(e.pageX-50, e.pageY-50), -// randPoint(e.pageX+50, e.pageY-50), -// randPoint(e.pageX+50, e.pageY), -// randPoint(e.pageX+50, e.pageY+50), -// randPoint(e.pageX-50, e.pageY+50) -// ]) -// }) - -// var mover = SVG('<ellipse>').size(50, 50).center(100, 100).addTo('svg') -// var anim = mover.animate(new SVG.Spring(500, 10)) -// -// let date = +new Date -// SVG.on(document, 'mousemove', function (e) { -// // if (+new Date - date > 50) { -// // date = +new Date -// // } else { -// // return -// // } -// -// //var p = mover.point(e.pageX, e.pageY) -// var p = mover.doc().point(e.clientX, e.clientY) -// //var p = {x: e.pageX, y: e.pageY} -// //console.log(p) -// anim.transform({px: p.x - 100, py: p.y - 100}) -// //anim.center(p.x, p.y) -// }) -/* -let canvas = SVG('#canvas') - -let rectangle = canvas.rect(100, 200).move(100, 0) - -let bbox = rectangle.bbox() - -var timer = 0 -rectangle.timeline().source(() => { - timer += 2 - document.querySelector('#absolute span').textContent = timer - return timer -}) -rectangle.animate().transform({ - rotate: 90, - origin: [bbox.cx, bbox.cy] -})*/ - -// - - -// SVG('#absolute').on('input slide', function (e) { -// var val = e.target.value -// -// canvas.clear() - // canvas.ellipse(20, 20) - // let re = canvas.rect(300, 150).move(100, 150).attr('opacity', 0.5) - // re.clone() - // .transform({rotate: 45, skew: 30}, true) - // - // re.clone() - // .transform({ - // rotate: 45, skew: 30, /*translate: [150, 140], */ - // }, true) - // .transform({rotate: val, origin: 'bottom-right'}, true) - // - // re.clone() - // .transform({rotate: 45, skew: 30}, true) - // .transform({rotate: val, origin: 'bottom-right'}, true) - // .transform({skew}, true) -// let a = canvas.rect(200, 400).move(500, 400) -// .attr('opacity', 0.3) -// .addClass('pink') -// //.transform({ px: 100, py: 500, origin: 'top-left' }) -// -// -// var timer = 0 -// a.timeline().source(() => { -// timer += 1 -// document.querySelector('#absolute span').textContent = timer -// return timer -// }) -// -// let obj = { rotate: val * 180, origin: 'top-left' } -// let obj2 = { rotate: val * 280, origin: 'center' } -// -// a.clone() // startPosition -// a.clone().transform(obj, true).transform(obj2, true) // endPosition -// }) - - -// let a = canvas.rect(200, 400).move(500, 400) -// -// a.animate(1000, 500).move(100, 100).animate(1000, 500).move(500, 400) - - - - -/* FUZZYMS PLANETS!! */ -// let canvas = SVG('#canvas') -// let gradient = canvas.gradient('radial', function(gradient) { -// gradient.stop(0, '#f00') -// gradient.stop(1, '#ff0') -// }) -// -// let gradientEarth = canvas.gradient('linear', function(gradient) { -// gradient.stop(0, '#00f') -// gradient.stop(1, '#0f0') -// }) -// -// let sun = canvas.circle(200).center(500, 300).attr({ fill: gradient }) -// -// let earth = canvas.circle(100).center(1000, 300).attr({fill: gradientEarth}) -// -// let moon = canvas.circle(50).center(1200, 300).attr({fill: '#ffa'}) -// -// earth.animate(10000).loop().ease('-') -// .transform({rotate: 360, origin: [500, 300]}, true) -// .transform({rotate: 720, origin: 'center'}, true) -// .on('step', (e) => { -// // console.log(e) -// }) -// -// moon.animate(10000).loop().ease('-') -// .transform({rotate: 360, origin: [500, 300]}, true) -// .transform({rotate: 3600, origin: [1000, 300]}, true) - - - - - - - - - - - - - - -/** - * FUZZYS EXAMPLE - */ -// let a = canvas.rect(200, 400).move(500, 400) -// .attr('opacity', 0.3) -// .addClass('pink') -// .transform({ tx: 300, ty: 500, origin: 'top-left' }) -// -// let obj = { rotate: 100, origin: 'top-left'} -// let obj2 = { rotate: 280, origin: 'center' } -// let obj3 = { rotate: 1000, origin: 'center', translate: [300, 200]} -// -// -// var c = a.clone() -// -// c.animate(3000) -// .transform(obj) -// .transform(obj2, true) // animation -// -// a.clone().attr('fill', 'blue') -// .transform(obj) -// .transform(obj2, true) // endPosition - - -// SAIVANS EXAMPLE - - -// canvas.ellipse(20, 20).center(100, 100) -// let r = canvas.rect(200, 400).move(100, 100) -// .attr('opacity', 0.3) -// //.transform({ tx: 300, ty: 500, origin: 'top-left' }) -// -// // Normal usage -// let wait = 3000 -// let rAnim = r.clone().attr('fill', '#f00').animate(wait).attr('fill', '#0f0') -// let rDecl = r.clone().attr('fill', 'blue').animate(new SVG.Spring(wait, 15)) -// //let rDecl = r.clone().attr('fill', 'blue').animate(new SVG.PID(0.01, 0.001, 1, 10)) -// -// // var timer = 0 -// // rDecl.timeline().source(() => { -// // timer += 100 -// // return timer -// // }) -// -// let runTransformation = (transform) => { -// return () => { -// //transform = new SVG.Matrix(transform) -// let relative = true -// let affine = true -// r.transform(transform, relative) -// rAnim.animate(wait).transform(transform, relative, affine) -// rDecl.transform(transform, relative, affine) -// } -// } -// -// setTimeout(runTransformation({ -// origin: 'top-left', -// translate: [530, 250], -// rotate: 300, -// scale: 2, -// shear: 1, -// }), 0.1 * wait ) -// -// -// -// setTimeout(runTransformation({ -// origin: 'top-left', -// translate: [530, 250], -// rotate: 100, -// scale: 2, -// shear: 1, -// }), 0.4 * wait) -// -// setTimeout(runTransformation({ -// origin: 'top-left', -// translate: [530, 250], -// rotate: 100, -// scale: 2, -// shear: 1, -// }), 0.6 * wait) - - -// canvas.circle(50).center(100, 0).attr('fill', 'gray') -// -// setTimeout(runTransformation({ -// rotate: 360, -// origin: [100, 0] -// }), 0.1 * wait ) -// -// -// setTimeout(runTransformation({ -// rotate: 360, -// }), 0.4 * wait) - -// const getConsole = (time) => { -// return () => { -// console.group(time) -// console.log(0, rAnim.element()._transformationRunners[0] && rAnim.element()._transformationRunners[0].transforms.decompose().rotate) -// console.log(1, rAnim.element()._transformationRunners[1] && rAnim.element()._transformationRunners[1].transforms.decompose().rotate) -// console.log(2, rAnim.element()._transformationRunners[2] && rAnim.element()._transformationRunners[2].transforms.decompose().rotate) -// console.log(3, rAnim.element()._transformationRunners[3] && rAnim.element()._transformationRunners[3].transforms.decompose().rotate) -// console.log(4, rAnim.element()._transformationRunners[4] && rAnim.element()._transformationRunners[4].transforms.decompose().rotate) -// console.groupEnd(time) -// } -// } -// -// logCall = (time) => { -// setTimeout(getConsole(time), time) -// } -// -// logCall(0.2 * wait) -// logCall(0.3 * wait) -// logCall(0.4 * wait) -// logCall(0.5 * wait) -// logCall(0.6 * wait) -// logCall(0.7 * wait) -// logCall(0.8 * wait) -// logCall(0.9 * wait) -// logCall(1 * wait) -// logCall(1.1 * wait) -// logCall(1.2 * wait) -// logCall(1.3 * wait) -// logCall(1.4 * wait) -// logCall(1.5 * wait) - -</script> - -</body> -</html> diff --git a/playgrounds/colors/index.html b/playgrounds/colors/index.html index 301dd3a..cb0b688 100644 --- a/playgrounds/colors/index.html +++ b/playgrounds/colors/index.html @@ -21,6 +21,6 @@ </body> <script src="../../dist/svg.js" charset="utf-8"></script> - <script src="bundle.js" charset="utf-8"></script> + <script src="main.js" charset="utf-8"></script> </html> diff --git a/playgrounds/colors/main.js b/playgrounds/colors/main.js index fda3ce2..d81bb47 100644 --- a/playgrounds/colors/main.js +++ b/playgrounds/colors/main.js @@ -12,7 +12,7 @@ function rectangles ( method='Vibrant') { // Add the squares for ( let i = 0; i < 20; i++ ) { - let color = SVG.Color.random( method.toLowerCase() ).hex() + let color = SVG.Color.random( method.toLowerCase() ).toHex() let rect = group.rect(100, 100) .x( 20 + 100 * i ) .fill( color ) diff --git a/playgrounds/matrix/drag.js b/playgrounds/matrix/drag.js index 2dd6cac..7609404 100644 --- a/playgrounds/matrix/drag.js +++ b/playgrounds/matrix/drag.js @@ -35,7 +35,7 @@ function reactToDrag(element, onDrag, beforeDrag) { } // Bind the drag tracker to this element directly - let parent = element.doc() + let parent = element.root() let point = new SVG.Point() element.mousedown(startDrag).touchstart(startDrag) } diff --git a/playgrounds/matrix/index.html b/playgrounds/matrix/index.html index cd34b7d..e815ed5 100644 --- a/playgrounds/matrix/index.html +++ b/playgrounds/matrix/index.html @@ -5,7 +5,7 @@ <head> <meta charset="utf-8"> <title>SVG Playground</title> - <link rel="stylesheet" href="../playground.css"> + <link rel="stylesheet" href="style.css"> </head> <body> diff --git a/playgrounds/transforms/index.html b/playgrounds/transforms/index.html index a165dd9..8e1f804 100644 --- a/playgrounds/transforms/index.html +++ b/playgrounds/transforms/index.html @@ -5,7 +5,7 @@ <head> <meta charset="utf-8"> <title>SVG Playground</title> - <link rel="stylesheet" href="../playground.css"> + <link rel="stylesheet" href="style.css"> </head> <body> diff --git a/spec/SpecRunner.html b/spec/SpecRunner.html index 1f8dae8..da55e82 100644 --- a/spec/SpecRunner.html +++ b/spec/SpecRunner.html @@ -17,7 +17,7 @@ <!-- include source files here... --> <script src="../dist/polyfills.js" charset="utf-8"></script> <script src="../dist/polyfillsIE.js" charset="utf-8"></script> - <script src="../dist/svg.min.js" charset="utf-8"></script> + <script src="../dist/svg.js" charset="utf-8"></script> </head> @@ -58,15 +58,15 @@ <!--<script src="es5TestBundle.js"></script>--> - <!-- <script src="spec/adopter.js"></script> + <script src="spec/adopter.js"></script> <script src="spec/arrange.js"></script> <script src="spec/array.js"></script> <script src="spec/bare.js"></script> <script src="spec/boxes.js"></script> <script src="spec/circle.js"></script> - <script src="spec/clip.js"></script> --> + <script src="spec/clip.js"></script> <script src="spec/color.js"></script> - <!-- <script src="spec/container.js"></script> + <script src="spec/container.js"></script> <script src="spec/defs.js"></script> <script src="spec/doc.js"></script> <script src="spec/easing.js"></script> @@ -104,6 +104,6 @@ <script src="spec/morphing.js"></script> <script src="spec/animator.js"></script> <script src="spec/runner.js"></script> - <script src="spec/queue.js"></script> --> + <script src="spec/queue.js"></script> </body> </html> diff --git a/src/modules/core/event.js b/src/modules/core/event.js index 507e91f..d9b4f46 100644 --- a/src/modules/core/event.js +++ b/src/modules/core/event.js @@ -3,27 +3,32 @@ import { makeInstance } from '../../utils/adopter.js' import { globals } from '../../utils/window.js' let listenerId = 0 +let windowEvents = {} -function getEvents (node) { - const n = makeInstance(node).getEventHolder() +function getEvents (instance) { + let n = instance.getEventHolder() + + // We dont want to save events in global space + if (n === globals.window) n = windowEvents if (!n.events) n.events = {} return n.events } -function getEventTarget (node) { - return makeInstance(node).getEventTarget() +function getEventTarget (instance) { + return instance.getEventTarget() } -function clearEvents (node) { - const n = makeInstance(node).getEventHolder() +function clearEvents (instance) { + const n = instance.getEventHolder() if (n.events) n.events = {} } // Add event binder in the SVG namespace export function on (node, events, listener, binding, options) { var l = listener.bind(binding || node) - var bag = getEvents(node) - var n = getEventTarget(node) + var instance = makeInstance(node) + var bag = getEvents(instance) + var n = getEventTarget(instance) // events can be an array of events or a string of events events = Array.isArray(events) ? events : events.split(delimiter) @@ -51,8 +56,9 @@ export function on (node, events, listener, binding, options) { // Add event unbinder in the SVG namespace export function off (node, events, listener, options) { - var bag = getEvents(node) - var n = getEventTarget(node) + var instance = makeInstance(node) + var bag = getEvents(instance) + var n = getEventTarget(instance) // listener can be a function or a number if (typeof listener === 'function') { @@ -109,7 +115,7 @@ export function off (node, events, listener, options) { off(n, event) } - clearEvents(node) + clearEvents(instance) } }) } diff --git a/src/utils/adopter.js b/src/utils/adopter.js index 3e86d8a..34b853e 100644 --- a/src/utils/adopter.js +++ b/src/utils/adopter.js @@ -51,7 +51,7 @@ export function adopt (node) { if (node.instance instanceof Base) return node.instance // initialize variables - var className = capitalize(node.nodeName) + var className = capitalize(node.nodeName || 'Dom') // Make sure that gradients are adopted correctly if (className === 'LinearGradient' || className === 'RadialGradient') { diff --git a/todo.md b/todo.md deleted file mode 100644 index bb71762..0000000 --- a/todo.md +++ /dev/null @@ -1,107 +0,0 @@ -# tests to write -- sugar.js - - insertBefore - - insertAfter - - after - - before - - ax, ay, amove -- Path.js - - targets -- Element.js - - svg -- attr.js -- Style.js - - -# Where We Left Off - -Saivan -====== - - -Ulima -===== -- Use runners[runnerid] = {startTime, runner, persist} -timeline.persist('monkey-in', Infinity) -- folding transformations -- testing direct non affine morph -- why cant i use current? -- handle null values - -Both -==== -- We discussed that matrices should always be applied from the left for animation, so we have: - - If we have C R x where C is the current Matrix and R is the relative matrix that we want to apply - - It could be animated by instead left multiplying (C R inv(C)) so that we have (C R inv(C)) C R - - This allows us to always left multiply (which greatly simplifies things) - => Conclusion: We dont do this. We apply transformations left or right whatever is necessary - -Latest -====== -- Runners would call an element.mergeMatrix() function that requests a native animation frame. Each runner would cancel the call made by the last runner, so that the function only runs once per frame. --https://en.wikipedia.org/wiki/Change_of_basis#Change_of_coordinates_of_a_vector - - - -# Timeline Description - -- [T] Timeline constructors - - [T] timeline () - Returns the timeline context to the user - -- [T] Time Management - - [T] play () - Lets the timeline keep playing from here - - [T] pause () - Pauses the timeline where it currently is - - [T] stop () - Pauses the timeline and sets time = 0 - - [T] finish () - Moves the time to the final time for the final animation, forces declaratives to snap to their final positions - - [T] speed (newSpeed) - Sets the playback speed - - [T] seek (dt) - Scrubs the timeline time forward or backward by dt - - [T] time (t) - Sets the absolute time to t - - [T] backwards (back) - Sets the speed to (back ? speed : -speed) - - [T] position (p) - sets the position in range [0, 1] - - [T] loop (times, swing, waits) - -- [T] Runner Management - - [T] remove(tagOrRunner, end) - Removes all runners with tag from the timeline - - [T] reset () - Deletes all of the runners and resets the timeline - - [T] persist (tag, lifetime) - how long to keep a reference to an animation after it is completed - - [T] schedule (tag, time, when) - move the start time of the runner to time otherwise, returns all of the scheduled runners start and end times. - -- [T] Hidden Methods - - [x] `_step (dt)` - - [x] `_continue ()` - - -# Runner - -- [x] Constructors - - [x] animate (duration, delay, when) - Makes a new runner and returns the timeline context to the user with the new runner active. - - [x] loop (duration, times, swing) - Makes a new runner with the looping set as described by the parameters, returns timeline - - [x] delay (by, when) - Makes a new runner to start <by> ms after the last active runner is complete - -- [x] Runner Methods - - [x] element (svgElement) - Given an element, you can bind it directly - - [x] animate (args) - Calls animate if we have an element set - - [x] loop (args) - Calls loop with arguments if we have an element - - [x] delay (args) - calls delay if we have an element - -- [x] Runner Events - - [x] on (eventName, fn) - Binds a function to an event - - [x] off (eventName) - Unbinds all function from that event - - [x] fire () - Fires an event - -- [x] Basic Functionality - - [x] queue (initFn, runFn, alwaysInitialise) - Given two functions, the runner will run initFn once, and run runFn on every step. If alwaysInitialise is true, it will always run the initialisation as well. - - [x] during (runFn) - The function to run on each frame - -- [x] Runner Animation Methods - - [x] time (time) - Sets the time to the given time and runs the runner - - [x] step (dt) - Runs the runner method if - - [x] finish () - runs step with dT = Infinity - - [x] reverse () - Makes non-declarative runners play backwards - - [x] ease (fn) - Sets the easing function, can not be used to convert a non-declarative to a declarative animation. - - [x] active (activated) - Activates or deactivates a runner - - [x] loop (o) - Activates a loop sequence - -- [x] Runner Management - - [x] tag (name) - Name a runner or act as a getter - - [x] untag () diff --git a/useCases.md b/useCases.md deleted file mode 100644 index d6acdcb..0000000 --- a/useCases.md +++ /dev/null @@ -1,330 +0,0 @@ - - -# Tagged Animations - -The user can tag and control the runner for any animation - -```js - -var animation = element - .loop(300, true) - .tag('first') - .rotate(360) - .translate(50) - .animate(300, 200) - .tag('second') - .scale(3) - -element.timeline.finish() -element.timeline.pause() -element.timeline.stop() -element.timeline.play() - -``` - - -# Absolute Timeline Times - -The user can specify their time which is relative to the timelines time. - - -```js - -var animation = element.animate(2000).move(200, 200) - -// after 1000 ms -animation.animate(1000, 500, 'absolute').scale(2) - - -var runner = elemenet.move(0, 0).animate(1000) - -// after 500ms -runner.move(200, 200) - -``` - -This block of code would: -- Spend the first 1000ms moving the element -- At this time, it will snap the scale to 1.5 (halfway to 2) -- After this time, the scale and the move should go together - - -# Rotating While Scaling - -The user may want to run multiple animations concurrently and have -control over each animation that they define. - -```js - -let animationA = element.loop(300, ">").rotate(360) -let animationB = element.loop(200, "><").scale(2) - -// Maybe they want to disable a runner - which acts like pausing -animationB.active(false) - -// Maybe they want to remove an animation matching a tag -animationB.tag('B') -element.timeline().remove('B') - -// They can move around a runner as well -element.timeline() - .schedule('B', 300, 'absolute') // Moves a runner to start at 300 - // time(currentAbsolute - newAbsolute) - .shift('B', 300) // Shifts the runner start time by 300 - // which is sugar to - .schedule('B', 300, 'relative') - // seek(shiftTime) - -``` - -Lets demonstrate the difference between the schedule and shift - -``` -Given this: - - -------- - -------------- - ---------------- - -Schedule: - -------- - -------------- - ---------------- - -Shift: - -------- - -------------- - ---------------- -``` - - - -# A Sequenced Animation - -The user might want to be able to run a long sequenced animation that they have -predesigned as they please. - -```js - -let timeline = element.loop(300, "><").scale(2) - .animate(300).rotate(30) - .animate(300, 200).fill(blue) - -// They might want to move forwards or backwards -timeline.seek(-300) - -// They might want to set a specific time -timeline.time(200) - -// Or a specific position -timeline.position(0.3) - -// Maybe they want to clear the timeline -timeline.reset() - -``` - - -# User wants to Loop Something - -If the user wants to loop something, they should be able to call the loop -method at any time, and it will just change the behaviour of the current -runner. If we are running declaratively, we will throw an error. - -## Correct Usages - -They can invoke this from the timeline - -```js -element.loop(duration, times, swing) -``` - -If they want to work with absolute times, they should animate first - -```js -element.animate(300, 200, true) - .loop(Infinity, true) -``` - -Or alternatively, they could equivalently do this: - -```js -element.loop({ - now: true, - times: Infinity, - delay: 200, - duration: 300, - swing: true, - wait: [200, 300] -}) -``` - -## Error Case - - - -# Declarative Animations - -The user might want to have something chase their mouse around. This would -require a declarative animation. - -```js - -el.animate((curr, target, dt, ctx) => { - - // Find the error and the value - let error = target - current - ctx.speed = (ctx.error - error) / dt - ctx.error = error - return newPos - -}) - -SVG.on(document, 'mousemove', (ev) => { - - el.timeline(controller) - .move(ev.pageX, ev.pageY) - -}) - -``` - - -## Springy Mouse Chaser - -Pretend we gave the user a springy controller that basically springs to a -target in 300ms for example. They might be constantly changing the target with: - -```js - -el.animate(Spring(500), 200) - .tag('declarative') - .persist() - .move(10, 10) - -el.animate('declarative') - .move(300, 200) - - - -SVG.on(document, 'mousemove', function (ev) { - - el.animate(springy, 200) - .tag('declarative') - .move(ev.pageX, ev.pageY) - -}) - -``` - - -# Repeated Animations - -The user might want to duplicate an animation and have it rerun a few times - -```js - -// User makes two copies of an animation -let animA = el.animate(300, 300, 'now')...(animation)... -let animB = animA.clone() // Deep copy - -// Now let the user attach and reschedule their animations -el.timeline() - .schedule(animA, 500, 'absolute') - .schedule(animB, 2000, 'absolute') - -``` - -Then the user can loop the timeline, by changing its play mode - -```js -el.timeline() - .loop(times, swing, waits) -``` - - -# Advanced Animations - -The user can create their own runners and then attach it to the timeline -themselves if they like. - -```js - -// They declare their animation -let rotation = () => new SVG.Runner().rotate(500) - -// They attach an element, and schedule the runner -let leftAnimation = rotation().element(leftSquare).reverse() - -// They might want to animate another -let rightAnimation = rotation().element(rightSquare) - -// They can schedule these two runners to a master element -timelineElement.timeline() - .schedule(leftAnimation, 300, 'absolute') - .schedule(rightAnimation, 500, 'now') - .schedule(rightAnimation, 300, 'end') - -// Or they can schedule it to a timeline as well -let timeline = new SVG.Timeline() - .schedule(leftAnimation, 300, 'absolute') - .schedule(rightAnimation, 500, 'now') - -``` - - -# Modifying Controller Parameters - -Some user might want to change the speed of a controller, or how the controller -works in the middle of an animation. For example, they might do: - -```js - -var pid = PID(30, 20, 40) -let animation = el.animate(pid).move(.., ..) - - -// Some time later, the user slides a slider, and they can do: -slider1.onSlide( v => pid.p(v) ) - -``` - - -# Bidirectional Scheduling **(TODO)** - -We would like to schedule a runner to a timeline, or to do the opposite - -```js - -// If we have a runner and a timeline -let timeline = new Timeline()... -let runner = new Runner()... - -// Since the user can schedule a runner onto a timeline -timeline.schedule(runner, ...rest) - -// It should be possible to do the opposite -runner.schedule(timeline, ...rest) - -// It could be Implemented like this -runner.schedule = (t, duration, delay, now) { - this._timeline.remove(this) // Should work even if its not scheduled - t.schedule(this, duration, delay, now) - return this -} - -// The benefit would be that they could call animate afterwards: eg: -runner.schedule(timeline, ...rest) - .animate()... - -``` - -# Binding Events - -The user might want to react to some events that the runner might emit. We will -emit the following events from the runner: -- start - when a runner first initialises -- finish - when a runner finishes -- step - on every step - -Maybe they also want to react to timeline events as well |