</head>
<body style="background-color: #c7c7ff">
-<div id="absolute"><label>Absolute: <input type="range" min="0" max="90" step="0.01"></slider></label><span></span></div>
+<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>
<!-- Making the svg -->
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}, true)
- .transform({rotate: val}, true)
+ // 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: 'center', translate: [300 * val, 0] }
+ let obj2 = { rotate: -val * 180, origin: 'center' }
+
+ a.clone() // startPosition
+ a.clone().transform(obj, true).transform(obj2, true) // endPosition
})
// .addClass('green')
// Make the pink rectangle
-// 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: 180, shear:2, origin: [600, 600], translate: [200, 100] }
-// let obj2 = { rotate: 180, shear:2, origin: [600, 600], translate: [200, 100] }
-//
-// a.clone() // startPosition
-// a.clone().transform(obj, true).transform(obj2, true) // endPosition
-// //a.animate(new SVG.Spring(50, 30)).transform(obj) // animation
-// a.animate(300).transform(obj, true).transform(obj2, true) // animation
-//
+let a = canvas.rect(200, 400).move(500, 400)
+ .attr('opacity', 0.3)
+ .addClass('pink')
+ .transform({ tx: 100, ty: 500, origin: 'top-left' })
+
+canvas.ellipse(20, 20).center(700, 1100)
+
+
+var timer = 0
+a.timeline().source(() => {
+ timer += 1
+ document.querySelector('#absolute span').textContent = timer
+ return timer
+})
+
+
+let el = canvas.ellipse(20, 20)
+window.moveit = function (x, y) {
+ el.move(x, y)
+}
+
+
+let obj = { rotate: 180, origin: 'center', translate: [300, 0] }
+let obj2 = { rotate: -180, origin: 'center' }
+
+a.clone() // startPosition
+a.clone().transform(obj, true).transform(obj2, true) // endPosition
+//a.animate(new SVG.Spring(50, 30)).transform(obj) // animation
+a.animate(300).transform(obj, true).transform(obj2, true) // animation
+
//
// // Put an ellipse where we expect the object to be
// canvas.ellipse(30, 30).center(100, 500)
.reduce((last, curr) => last.lmultiply(curr))
this.transform(netTransform)
+ this._currentMatrix = runners[0]
+
// Merge any two transformations in a row that are done
let lastRunner = null
runners.forEach((runner, i) => {
-
if (lastRunner && runner.done && lastRunner.done) {
- console.log(lastRunner, runner)
delete runners[runner.id+1]
runners[lastRunner.id+1] = {
transforms: runner.transforms.lmultiply(lastRunner.transforms),
lastRunner = runner
})
+
+ if (!lastRunner) {
+ this._frameId = null
+ }
}
SVG.extend(SVG.Element, {
})
}
-
delete arr[i]
}
})
},
+ _currentTransform (current) {
+ return this._transformationRunners
+ .filter((runner) => runner.id <= current.id)
+ .map(runner => runner.transforms)
+ .reduce((last, curr) => last.lmultiply(curr))
+ },
+
addRunner: function (runner) {
this._transformationRunners[runner.id+1] = runner
// - true, true with ObjectBag
var morpher
var origin
+ var startTransform
var current
+ var element
if(relative && !isMatrix) {
morpher = new SVG.Morphable().type(SVG.Morphable.ObjectBag)
.stepper(this._stepper)
this.queue(function() {
if (origin == null) {
- origin = getOrigin (transforms, this.element())
- transforms.origin = origin
+ element = this.element()
+ let transformedOrigin = getOrigin (transforms, element)
+ origin = new SVG.Point(transformedOrigin)
+ .transform(new SVG.Matrix(element).inverse())
+
+ transforms.origin = [origin.x, origin.y]
morpher.to(formatTransforms(transforms))
}
let from = current || {origin}
-
morpher.from(formatTransforms(from))
-
this.element().addRunner(this)
+
}, function (pos) {
+
+ let currentMatrix = element._currentTransform(this)
+ //origin = getOrigin (transforms, element)
+ let {x, y} = origin.transform(currentMatrix)
+
+moveit(x, y)
+
+// console.log(currentMatrix.decompose(origin[0], origin[1]));
+
+
+ /*
+
+
+ 1. Transform the origin by figuring out the delta
+
+ - At the start, we had:
+
+ let Sinv = new SVG.Matrix(element).inverse()
+ let origin = getOrigin(element)
+
+ - At a particular frame we have:
+
+ let C = Matrix(element)
+ let newOrigin = origin.transform(S.inv).transform(C)
+
+ */
+
+ let index = morpher._from.indexOf('ox')
+ morpher._from.splice(index, 4, 'ox', x, 'oy', y)
+ morpher._to.splice(index, 4, 'ox', x, 'oy', y)
+
current = morpher.at(pos).valueOf()
let matrix = new SVG.Matrix(current)
this.addTransform(matrix)
morpher.to(transforms)
this.queue(function() {
- let element = this.element()
+ element = this.element()
element.addRunner(this)
if (!origin && affine) {