From 8ddc84d039a2fbef4b54160dfb99327e867c6dcf Mon Sep 17 00:00:00 2001 From: Eduardo San Martin Morote Date: Sun, 1 Jul 2018 19:15:35 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20support=20new=20values=20in=20ar?= =?UTF-8?q?rays?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #14 --- src/Motion.js | 42 ++- test/specs/Motion.spec.js | 549 +++++++++++++++++++++++--------------- 2 files changed, 347 insertions(+), 244 deletions(-) diff --git a/src/Motion.js b/src/Motion.js index 071dc33..85f34a0 100644 --- a/src/Motion.js +++ b/src/Motion.js @@ -27,21 +27,15 @@ export default { computed: { springConfig () { - return typeof this.spring === 'string' - ? presets[this.spring] - : this.spring + return typeof this.spring === 'string' ? presets[this.spring] : this.spring }, realValues () { - return this.value != null - ? { value: this.value } - : this.values + return this.value != null ? { value: this.value } : this.values }, }, render (h) { - return h(this.tag, [ - this.$scopedSlots.default(this.currentValues), - ]) + return h(this.tag, [this.$scopedSlots.default(this.currentValues)]) }, watch: { @@ -109,11 +103,7 @@ export default { animate () { this.animationId = raf(() => { - if (shouldStopAnimation( - this.currentValues, - this.realValues, - this.currentVelocities - )) { + if (shouldStopAnimation(this.currentValues, this.realValues, this.currentVelocities)) { if (this.wasAnimating) this.$emit('motion-end') // reset everything for next animation @@ -145,7 +135,8 @@ export default { } const currentFrameCompletion = - (this.accumulatedTime - Math.floor(this.accumulatedTime / msPerFrame) * msPerFrame) / msPerFrame + (this.accumulatedTime - Math.floor(this.accumulatedTime / msPerFrame) * msPerFrame) / + msPerFrame const framesToCatchUp = Math.floor(this.accumulatedTime / msPerFrame) const springConfig = this.springConfig @@ -185,6 +176,16 @@ export default { if (!Object.prototype.hasOwnProperty.call(realValues, key)) continue if (isArray(realValues[key]) || isObject(realValues[key])) { + // the value may have been added + if (!idealValues[key]) { + const ideal = this.defineInitialValues(this.realValues[key], null) + const current = this.defineInitialValues(this.realValues[key], null) + this.$set(idealValues, key, ideal.values) + this.$set(idealVelocities, key, ideal.velocities) + this.$set(currentValues, key, current.values) + this.$set(currentVelocities, key, current.velocities) + } + this.animateValues({ framesToCatchUp, currentFrameCompletion, @@ -228,11 +229,9 @@ export default { ) currentValues[key] = - newIdealValue + - (nextIdealValue - newIdealValue) * currentFrameCompletion + newIdealValue + (nextIdealValue - newIdealValue) * currentFrameCompletion currentVelocities[key] = - newIdealVelocity + - (nextIdealVelocity - newIdealVelocity) * currentFrameCompletion + newIdealVelocity + (nextIdealVelocity - newIdealVelocity) * currentFrameCompletion idealValues[key] = newIdealValue idealVelocities[key] = newIdealVelocity } @@ -246,10 +245,7 @@ function shouldStopAnimation (currentValues, values, currentVelocities) { if (!Object.prototype.hasOwnProperty.call(values, key)) continue if (isArray(values[key]) || isObject(values[key])) { - if (!shouldStopAnimation( - currentValues[key], - values[key], - currentVelocities[key])) { + if (!shouldStopAnimation(currentValues[key], values[key], currentVelocities[key])) { return false } // skip the other checks diff --git a/test/specs/Motion.spec.js b/test/specs/Motion.spec.js index e519388..943384f 100644 --- a/test/specs/Motion.spec.js +++ b/test/specs/Motion.spec.js @@ -1,13 +1,7 @@ import MotionInjector from 'inject-loader!src/Motion' import presets from 'src/presets' -import { - isArray, - isObject, -} from 'src/utils' -import { - createVM, - nextTick, -} from '../helpers' +import { isArray, isObject } from 'src/utils' +import { createVM, nextTick } from '../helpers' const msPerFrame = 1000 / 60 @@ -34,7 +28,7 @@ describe('Motion', function () { if (count >= maxCount) throw new Error('Too many calls') } this.timeSlowdown = 1 - this.now = sinon.spy(() => now += this.timeSlowdown * msPerFrame) // eslint-disable-line no-return-assign + this.now = sinon.spy(() => (now += this.timeSlowdown * msPerFrame)) // eslint-disable-line no-return-assign Motion = MotionInjector({ './utils': { raf: this.raf, @@ -46,90 +40,113 @@ describe('Motion', function () { }) it('works with perfect time', function (done) { - const vm = createVM(this, ` + const vm = createVM( + this, + ` -`, { - data: { - n: 0, - config: { - stiffness: 170, - damping: 26, - precision: 0.01, +`, + { + data: { + n: 0, + config: { + stiffness: 170, + damping: 26, + precision: 0.01, + }, }, - }, - components: { Motion }, - }) + components: { Motion }, + } + ) vm.$('pre').should.have.text('0') vm.n = 10 - nextTick().then(() => { - this.step() - }).then(() => { - vm.$('pre').should.have.text('0.4722222222222221') - this.step() - }).then(() => { - vm.$('pre').should.have.text('1.1897376543209877') - this.stepUntil(() => vm.$('pre').text === '10') - }).then(done) + nextTick() + .then(() => { + this.step() + }) + .then(() => { + vm.$('pre').should.have.text('0.4722222222222221') + this.step() + }) + .then(() => { + vm.$('pre').should.have.text('1.1897376543209877') + this.stepUntil(() => vm.$('pre').text === '10') + }) + .then(done) }) it('works with imperfect time', function (done) { this.timeSlowdown = 11 - const vm = createVM(this, ` + const vm = createVM( + this, + ` -`, { - data: { - n: 0, - config: { - stiffness: 170, - damping: 26, - precision: 0.01, +`, + { + data: { + n: 0, + config: { + stiffness: 170, + damping: 26, + precision: 0.01, + }, }, - }, - components: { Motion }, - }) + components: { Motion }, + } + ) vm.$('pre').should.have.text('0') vm.n = 10 - nextTick().then(() => { - this.step() - }).then(() => { - vm.$('pre').should.have.text('0') - this.timeSlowdown = 0.01 - this.step() - }).then(() => { - vm.$('pre').should.have.text('0.0047222222222211485') - this.step() - }).then(() => { - vm.$('pre').should.have.text('0.009444444444442297') - }).then(done) + nextTick() + .then(() => { + this.step() + }) + .then(() => { + vm.$('pre').should.have.text('0') + this.timeSlowdown = 0.01 + this.step() + }) + .then(() => { + vm.$('pre').should.have.text('0.0047222222222211485') + this.step() + }) + .then(() => { + vm.$('pre').should.have.text('0.009444444444442297') + }) + .then(done) }) it('accepts a string as the spring', function (done) { - const vm = createVM(this, ` + const vm = createVM( + this, + ` -`, { - data: { - n: 0, - spring: 'noWobble', - }, - components: { Motion }, - }) +`, + { + data: { + n: 0, + spring: 'noWobble', + }, + components: { Motion }, + } + ) vm.$refs.motion.springConfig.should.eql(presets.noWobble) vm.spring = 'gentle' - nextTick().then(() => { - vm.$refs.motion.springConfig.should.eql(presets.gentle) - }).then(done) + nextTick() + .then(() => { + vm.$refs.motion.springConfig.should.eql(presets.gentle) + }) + .then(done) }) it('can define custom presets for springs', function (done) { @@ -139,115 +156,143 @@ describe('Motion', function () { precision: 0.03, } - const vm = createVM(this, ` + const vm = createVM( + this, + ` -`, { - data: { - n: 0, - spring: 'noWobble', - }, - components: { Motion }, - }) +`, + { + data: { + n: 0, + spring: 'noWobble', + }, + components: { Motion }, + } + ) vm.$refs.motion.springConfig.should.eql(presets.noWobble) vm.spring = 'custom' - nextTick().then(() => { - vm.$refs.motion.springConfig.should.eql(presets.custom) + nextTick() + .then(() => { + vm.$refs.motion.springConfig.should.eql(presets.custom) - delete presets.custom - }).then(done) + delete presets.custom + }) + .then(done) }) it('uses noWobble by default as the spring', function () { - const vm = createVM(this, ` + const vm = createVM( + this, + ` -`, { - data: { n: 0 }, - components: { Motion }, - }) +`, + { + data: { n: 0 }, + components: { Motion }, + } + ) vm.$refs.motion.springConfig.should.eql(presets.noWobble) }) it('supports array syntax', function (done) { - const vm = createVM(this, ` + const vm = createVM( + this, + ` -`, { - data: { - values: [0, -10], - config: { - stiffness: 170, - damping: 26, - precision: 0.01, +`, + { + data: { + values: [0, -10], + config: { + stiffness: 170, + damping: 26, + precision: 0.01, + }, }, - }, - components: { Motion }, - }) + components: { Motion }, + } + ) vm.$('.a').should.have.text('0') vm.values[0] = 10 - nextTick().then(() => { - this.step() - vm.values[1] = 0 - }).then(() => { - vm.$('.a').should.have.text('0.4722222222222222') - this.step() - }).then(() => { - vm.$('.a').should.have.text('1.1897376543209877') - vm.$('.b').should.have.text('-9.527777777777779') - this.stepUntil(() => vm.$('.a').text === '10') - }).then(done) + nextTick() + .then(() => { + this.step() + vm.values[1] = 0 + }) + .then(() => { + vm.$('.a').should.have.text('0.4722222222222222') + this.step() + }) + .then(() => { + vm.$('.a').should.have.text('1.1897376543209877') + vm.$('.b').should.have.text('-9.527777777777779') + this.stepUntil(() => vm.$('.a').text === '10') + }) + .then(done) }) it('supports object syntax', function (done) { - const vm = createVM(this, ` + const vm = createVM( + this, + ` -`, { - data: { - values: { - a: 0, - b: -10, +`, + { + data: { + values: { + a: 0, + b: -10, + }, + config: { + stiffness: 170, + damping: 26, + precision: 0.01, + }, }, - config: { - stiffness: 170, - damping: 26, - precision: 0.01, - }, - }, - components: { Motion }, - }) + components: { Motion }, + } + ) vm.$('.a').should.have.text('0') vm.values.a = 10 - nextTick().then(() => { - this.step() - vm.values.b = 0 - }).then(() => { - vm.$('.a').should.have.text('0.4722222222222222') - this.step() - }).then(() => { - vm.$('.a').should.have.text('1.1897376543209877') - vm.$('.b').should.have.text('-9.527777777777779') - this.stepUntil(() => vm.$('.a').text === '10') - }).then(done) + nextTick() + .then(() => { + this.step() + vm.values.b = 0 + }) + .then(() => { + vm.$('.a').should.have.text('0.4722222222222222') + this.step() + }) + .then(() => { + vm.$('.a').should.have.text('1.1897376543209877') + vm.$('.b').should.have.text('-9.527777777777779') + this.stepUntil(() => vm.$('.a').text === '10') + }) + .then(done) }) it('supports nested arrays', function (done) { - const vm = createVM(this, ` + const vm = createVM( + this, + ` -`, { - data: { - values: [[0, -10], [-10, 0]], - config: { - stiffness: 170, - damping: 26, - precision: 0.01, +`, + { + data: { + values: [[0, -10], [-10, 0]], + config: { + stiffness: 170, + damping: 26, + precision: 0.01, + }, }, - }, - components: { Motion }, - }) + components: { Motion }, + } + ) vm.$('.v00').should.have.text('0') vm.values[0][0] = 10 - nextTick().then(() => { - this.step() - vm.values[1][0] = 0 - }).then(() => { - vm.$('.v00').should.have.text('0.4722222222222222') - this.step() - }).then(() => { - vm.$('.v00').should.have.text('1.1897376543209877') - vm.$('.v10').should.have.text('-9.527777777777779') - this.stepUntil(() => vm.$('.v00').text === '10') - }).then(done) + nextTick() + .then(() => { + this.step() + vm.values[1][0] = 0 + }) + .then(() => { + vm.$('.v00').should.have.text('0.4722222222222222') + this.step() + }) + .then(() => { + vm.$('.v00').should.have.text('1.1897376543209877') + vm.$('.v10').should.have.text('-9.527777777777779') + this.stepUntil(() => vm.$('.v00').text === '10') + }) + .then(done) + }) + + it.skip('supports pushing new elements to arrays', function (done) { + const vm = createVM( + this, + ` + +
+ {{ v }} +
+
+`, + { + data: { + values: [10], + }, + components: { Motion }, + } + ) + // vm.$('span').should.have.text('10 ') + vm.values = [10, 20] + nextTick() + .then(() => { + this.step() + }) + .then(() => { + vm.$('.container').should.have.text('10 20 ') + vm.values[1] = 0 + // vm.$('.container').should.have.text('10 20') + // this.stepUntil(() => vm.$('.container').text === '10 20 ') + }) + .then(done) }) it('supports nested objects', function (done) { - const vm = createVM(this, ` + const vm = createVM( + this, + ` -`, { - data: { - values: { - a: { a: 0, b: -10 }, - b: { a: -10, b: 0 }, - }, - config: { - stiffness: 170, - damping: 26, - precision: 0.01, +`, + { + data: { + values: { + a: { a: 0, b: -10 }, + b: { a: -10, b: 0 }, + }, + config: { + stiffness: 170, + damping: 26, + precision: 0.01, + }, }, - }, - components: { Motion }, - }) + components: { Motion }, + } + ) vm.$('.vaa').should.have.text('0') vm.values.a.a = 10 - nextTick().then(() => { - this.step() - vm.values.b.a = 0 - }).then(() => { - vm.$('.vaa').should.have.text('0.4722222222222222') - this.step() - }).then(() => { - vm.$('.vaa').should.have.text('1.1897376543209877') - vm.$('.vba').should.have.text('-9.527777777777779') - this.stepUntil(() => vm.$('.vaa').text === '10') - }).then(done) + nextTick() + .then(() => { + this.step() + vm.values.b.a = 0 + }) + .then(() => { + vm.$('.vaa').should.have.text('0.4722222222222222') + this.step() + }) + .then(() => { + vm.$('.vaa').should.have.text('1.1897376543209877') + vm.$('.vba').should.have.text('-9.527777777777779') + this.stepUntil(() => vm.$('.vaa').text === '10') + }) + .then(done) }) it('supports nested objects in arrays', function (done) { - const vm = createVM(this, ` + const vm = createVM( + this, + ` -`, { - data: { - values: [{ a: 0, b: -10 }, { a: -10, b: 0 }], - config: { - stiffness: 170, - damping: 26, - precision: 0.01, +`, + { + data: { + values: [{ a: 0, b: -10 }, { a: -10, b: 0 }], + config: { + stiffness: 170, + damping: 26, + precision: 0.01, + }, }, - }, - components: { Motion }, - }) + components: { Motion }, + } + ) vm.$('.v0a').should.have.text('0') vm.values[0].a = 10 - nextTick().then(() => { - this.step() - vm.values[1].a = 0 - }).then(() => { - vm.$('.v0a').should.have.text('0.4722222222222222') - this.step() - }).then(() => { - vm.$('.v0a').should.have.text('1.1897376543209877') - vm.$('.v1a').should.have.text('-9.527777777777779') - this.stepUntil(() => vm.$('.v0a').text === '10') - }).then(done) + nextTick() + .then(() => { + this.step() + vm.values[1].a = 0 + }) + .then(() => { + vm.$('.v0a').should.have.text('0.4722222222222222') + this.step() + }) + .then(() => { + vm.$('.v0a').should.have.text('1.1897376543209877') + vm.$('.v1a').should.have.text('-9.527777777777779') + this.stepUntil(() => vm.$('.v0a').text === '10') + }) + .then(done) }) it('supports nested arrays in objects', function (done) { - const vm = createVM(this, ` + const vm = createVM( + this, + ` -`, { - data: { - values: { - a: [0, -10], - b: [-10, 0], - }, - config: { - stiffness: 170, - damping: 26, - precision: 0.01, +`, + { + data: { + values: { + a: [0, -10], + b: [-10, 0], + }, + config: { + stiffness: 170, + damping: 26, + precision: 0.01, + }, }, - }, - components: { Motion }, - }) + components: { Motion }, + } + ) vm.$('.va0').should.have.text('0') vm.values.a[0] = 10 - nextTick().then(() => { - this.step() - vm.values.b[0] = 0 - }).then(() => { - vm.$('.va0').should.have.text('0.4722222222222222') - this.step() - }).then(() => { - vm.$('.va0').should.have.text('1.1897376543209877') - vm.$('.vb0').should.have.text('-9.527777777777779') - this.stepUntil(() => vm.$('.va0').text === '10') - }).then(done) + nextTick() + .then(() => { + this.step() + vm.values.b[0] = 0 + }) + .then(() => { + vm.$('.va0').should.have.text('0.4722222222222222') + this.step() + }) + .then(() => { + vm.$('.va0').should.have.text('1.1897376543209877') + vm.$('.vb0').should.have.text('-9.527777777777779') + this.stepUntil(() => vm.$('.va0').text === '10') + }) + .then(done) }) })