var easing = {} //渐变曲线函数,反应加速度的变化 //currentTime:x轴当前时间(从0-到duration), startY:起始点, duration:总时长, wholeY:路程 (即endY-startY) //参数基本是 x, 0, 1, 1 /* easeOut 基本是y= m * (x-dur)^k + n, 若k为偶数,m<0, 若k为奇数,m>0; (因为偶数的话必须开口向下才能获得斜率递减的递增的那段,而奇数是对称的,单调递增. ) 根据x=0时y=0, x=dur时y=S , 得 n = S,m = -S/(-dur)^k */ easing.getEaseOut = function(k) { // k 是>=2的整数. 越大变化率越大, 相同初始速度所需要时间越久 let easeFun k = Math.round(k) if (k < 2) { k = Math.PI / 2 easeFun = easing.easeOutSine } else { easeFun = function(currentTime, startY, wholeY, duration) { if (k > 2) { console.log(k) } return (-wholeY / Math.pow(-duration, k)) * Math.pow(currentTime - duration, k) + wholeY } } return { k, easeFun } } ;(easing.linearTween = function(currentTime, startY, wholeY, duration) { return (wholeY * currentTime) / duration + startY }), (easing.easeInQuad = function(currentTime, startY, wholeY, duration) { return (currentTime /= duration), wholeY * currentTime * currentTime + startY }), (easing.easeOutQuad = function(currentTime, startY, wholeY, duration) { // 如套上实际的距离S和时长dur, y = - S / dur *(x^2-2x) 当s为1,dur为1时,是 y = -(x-1)^2 + 1 , 在0-1中是斜率递减的递增函数. 导数- S / dur *(2x-2 ) 可求出实时速度 故在0这一时刻,速度为 2S/dur return (currentTime /= duration), -wholeY * currentTime * (currentTime - 2) + startY }), (easing.easeInOutQuad = function(currentTime, startY, wholeY, duration) { return (currentTime /= duration / 2), currentTime < 1 ? (wholeY / 2) * currentTime * currentTime + startY : (currentTime--, (-wholeY / 2) * (currentTime * (currentTime - 2) - 1) + startY) }), (easing.easeInCubic = function(currentTime, startY, wholeY, duration) { return (currentTime /= duration), wholeY * currentTime * currentTime * currentTime + startY }), (easing.easeOutCubic = function(currentTime, startY, wholeY, duration) { // y = S / dur^3 *(x-dur)^3 + S,对称中心是(dur,S),从0-dur是 斜率递减的递增函数,导数为3S/dur^3 * (x-dur)^2, 0时速度为3S/dur return (currentTime /= duration), currentTime--, wholeY * (currentTime * currentTime * currentTime + 1) + startY }), (easing.easeInOutCubic = function(currentTime, startY, wholeY, duration) { return ( (currentTime /= duration / 2), currentTime < 1 ? (wholeY / 2) * currentTime * currentTime * currentTime + startY : ((currentTime -= 2), (wholeY / 2) * (currentTime * currentTime * currentTime + 2) + startY) ) }), (easing.easeInQuart = function(currentTime, startY, wholeY, duration) { return (currentTime /= duration), wholeY * currentTime * currentTime * currentTime * currentTime + startY }), (easing.easeOutQuart = function(currentTime, startY, wholeY, duration) { //根据上面的计算,估计0时速度应该是4S/dur吧…… return (currentTime /= duration), currentTime--, -wholeY * (currentTime * currentTime * currentTime * currentTime - 1) + startY }), (easing.easeInOutQuart = function(currentTime, startY, wholeY, duration) { return ( (currentTime /= duration / 2), currentTime < 1 ? (wholeY / 2) * currentTime * currentTime * currentTime * currentTime + startY : ((currentTime -= 2), (-wholeY / 2) * (currentTime * currentTime * currentTime * currentTime - 2) + startY) ) }), (easing.easeInQuint = function(currentTime, startY, wholeY, duration) { return (currentTime /= duration), wholeY * currentTime * currentTime * currentTime * currentTime * currentTime + startY }), (easing.easeOutQuint = function(currentTime, startY, wholeY, duration) { return (currentTime /= duration), currentTime--, wholeY * (currentTime * currentTime * currentTime * currentTime * currentTime + 1) + startY }), (easing.easeInOutQuint = function(currentTime, startY, wholeY, duration) { return ( (currentTime /= duration / 2), currentTime < 1 ? (wholeY / 2) * currentTime * currentTime * currentTime * currentTime * currentTime + startY : ((currentTime -= 2), (wholeY / 2) * (currentTime * currentTime * currentTime * currentTime * currentTime + 2) + startY) ) }), (easing.easeInSine = function(currentTime, startY, wholeY, duration) { return -wholeY * Math.cos((currentTime / duration) * (Math.PI / 2)) + wholeY + startY }), (easing.easeOutSine = function(currentTime, startY, wholeY, duration) { // y' = S * PI / 2 / dur * cos(PI/2/dur * x) console.log('easeOutSine') return wholeY * Math.sin((currentTime / duration) * (Math.PI / 2)) + startY }), (easing.easeInOutSine = function(currentTime, startY, wholeY, duration) { return (-wholeY / 2) * (Math.cos((Math.PI * currentTime) / duration) - 1) + startY }), (easing.easeInExpo = function(currentTime, startY, wholeY, duration) { return wholeY * Math.pow(2, 10 * (currentTime / duration - 1)) + startY }), (easing.easeOutExpo = function(currentTime, startY, wholeY, duration) { return wholeY * (-Math.pow(2, (-10 * currentTime) / duration) + 1) + startY }), (easing.easeInOutExpo = function(currentTime, startY, wholeY, duration) { return ( (currentTime /= duration / 2), currentTime < 1 ? (wholeY / 2) * Math.pow(2, 10 * (currentTime - 1)) + startY : (currentTime--, (wholeY / 2) * (-Math.pow(2, -10 * currentTime) + 2) + startY) ) }), (easing.easeInCirc = function(currentTime, startY, wholeY, duration) { return (currentTime /= duration), -wholeY * (Math.sqrt(1 - currentTime * currentTime) - 1) + startY }), (easing.easeOutCirc = function(currentTime, startY, wholeY, duration) { return (currentTime /= duration), currentTime--, wholeY * Math.sqrt(1 - currentTime * currentTime) + startY }), (easing.easeInOutCirc = function(currentTime, startY, wholeY, duration) { return ( (currentTime /= duration / 2), currentTime < 1 ? (-wholeY / 2) * (Math.sqrt(1 - currentTime * currentTime) - 1) + startY : ((currentTime -= 2), (wholeY / 2) * (Math.sqrt(1 - currentTime * currentTime) + 1) + startY) ) }), (easing.easeInElastic = function(currentTime, startY, wholeY, duration) { var r = 1.70158, o = 0, a = wholeY return 0 === currentTime ? startY : 1 === (currentTime /= duration) ? startY + wholeY : (o || (o = 0.3 * duration), a < Math.abs(wholeY) ? ((a = wholeY), (r = o / 4)) : (r = (o / (2 * Math.PI)) * Math.asin(wholeY / a)), -(a * Math.pow(2, 10 * (currentTime -= 1)) * Math.sin(((currentTime * duration - r) * (2 * Math.PI)) / o)) + startY) }), (easing.easeOutElastic = function(currentTime, startY, wholeY, duration) { var r = 1.70158, o = 0, a = wholeY return 0 === currentTime ? startY : 1 === (currentTime /= duration) ? startY + wholeY : (o || (o = 0.3 * duration), a < Math.abs(wholeY) ? ((a = wholeY), (r = o / 4)) : (r = (o / (2 * Math.PI)) * Math.asin(wholeY / a)), a * Math.pow(2, -10 * currentTime) * Math.sin(((currentTime * duration - r) * (2 * Math.PI)) / o) + wholeY + startY) }), (easing.easeInOutElastic = function(currentTime, startY, wholeY, duration) { var r = 1.70158, o = 0, a = wholeY return 0 === currentTime ? startY : 2 === (currentTime /= duration / 2) ? startY + wholeY : (o || (o = duration * (0.3 * 1.5)), a < Math.abs(wholeY) ? ((a = wholeY), (r = o / 4)) : (r = (o / (2 * Math.PI)) * Math.asin(wholeY / a)), currentTime < 1 ? -0.5 * (a * Math.pow(2, 10 * (currentTime -= 1)) * Math.sin(((currentTime * duration - r) * (2 * Math.PI)) / o)) + startY : a * Math.pow(2, -10 * (currentTime -= 1)) * Math.sin(((currentTime * duration - r) * (2 * Math.PI)) / o) * 0.5 + wholeY + startY) }), (easing.easeInBack = function(currentTime, startY, wholeY, duration, r) { return void 0 === r && (r = 1.70158), wholeY * (currentTime /= duration) * currentTime * ((r + 1) * currentTime - r) + startY }), (easing.easeOutBack = function(currentTime, startY, wholeY, duration, r) { return void 0 === r && (r = 1.70158), wholeY * ((currentTime = currentTime / duration - 1) * currentTime * ((r + 1) * currentTime + r) + 1) + startY }), (easing.easeInOutBack = function(currentTime, startY, wholeY, duration, r) { return ( void 0 === r && (r = 1.70158), (currentTime /= duration / 2) < 1 ? (wholeY / 2) * (currentTime * currentTime * (((r *= 1.525) + 1) * currentTime - r)) + startY : (wholeY / 2) * ((currentTime -= 2) * currentTime * (((r *= 1.525) + 1) * currentTime + r) + 2) + startY ) }), (easing.easeOutBounce = function(currentTime, startY, wholeY, duration) { return (currentTime /= duration) < 1 / 2.75 ? wholeY * (7.5625 * currentTime * currentTime) + startY : currentTime < 2 / 2.75 ? wholeY * (7.5625 * (currentTime -= 1.5 / 2.75) * currentTime + 0.75) + startY : currentTime < 2.5 / 2.75 ? wholeY * (7.5625 * (currentTime -= 2.25 / 2.75) * currentTime + 0.9375) + startY : wholeY * (7.5625 * (currentTime -= 2.625 / 2.75) * currentTime + 0.984375) + startY }), (easing.easeInBounce = function(currentTime, startY, wholeY, r) { return wholeY - easing.easeOutBounce(r - currentTime, 0, wholeY, r) + startY }), (easing.easeInOutBounce = function(currentTime, startY, wholeY, r) { return currentTime < r / 2 ? 0.5 * easing.easeInBounce(2 * currentTime, 0, wholeY, r) + startY : 0.5 * easing.easeOutBounce(x, 2 * currentTime - r, 0, wholeY, r) + 0.5 * wholeY + startY }) var lerp = { /* vector: function(currentTime, startY, f) {//xzw change, add f var wholeY = currentTime.clone(); return startY = startY.clone(), function(duration) { currentTime.set(wholeY.x * (1 - duration) + startY.x * duration, wholeY.y * (1 - duration) + startY.y * duration, wholeY.z * (1 - duration) + startY.z * duration) f && f(currentTime,duration); } }, quaternion: function(currentTime, startY, f) {//xzw change, add f var wholeY = currentTime.clone(); return function(duration) { currentTime.copy(wholeY).slerp(startY, duration); f && f(currentTime,duration); } }, property: function(currentTime, startY, wholeY, duration) { var r = currentTime[startY]; return function(o) { currentTime[startY] = r * (1 - o) + wholeY * o, duration && duration(currentTime[startY]) } }, uniform: function(currentTime, startY, wholeY) { var duration = currentTime.material.uniforms[startY].value; return function(r) { try{ currentTime.material.uniforms[startY] && (currentTime.material.uniforms[startY].value = duration * (1 - r) + wholeY * r) }catch(currentTime){ console.log(1) } } }, matrix4: function(currentTime, startY) { var wholeY = currentTime.clone(); return function(duration) { for (var r = currentTime.elements, o = wholeY.elements, a = startY.elements, s = 0; s < 16; s++) r[s] = o[s] * (1 - duration) + a[s] * duration } }, allUniforms: function(currentTime, startY, wholeY) { var duration = currentTime.map(function(currentTime) { return this.uniform(currentTime, startY, wholeY) } .bind(this)); return function(currentTime) { duration.forEach(function(startY) { startY(currentTime) }) } } */ vector: function(t, i, f) { //xzw change, add f var n = t.clone() return ( (i = i.clone()), function(e) { t.set(n.x * (1 - e) + i.x * e, n.y * (1 - e) + i.y * e, n.z * (1 - e) + i.z * e) f && f(t, e) } ) }, quaternion: function(t, i, f) { //xzw change, add f var n = t.clone() return function(e) { t.copy(n).slerp(i, e) f && f(t, e) } }, property: function(t, i, n, r) { var o = t[i] return function(e) { ;(t[i] = o * (1 - e) + n * e), r && r(t[i]) } }, uniform: function(t, i, n) { var r = t.material.uniforms[i].value return function(e) { t.material.uniforms[i] && (t.material.uniforms[i].value = r * (1 - e) + n * e) } }, matrix4: function(o, a) { var s = o.clone() return function(e) { for (var t = o.elements, i = s.elements, n = a.elements, r = 0; r < 16; r++) t[r] = i[r] * (1 - e) + n[r] * e } }, allUniforms: function(e, t, i) { var n = e.map( function(e) { return this.uniform(e, t, i) }.bind(this) ) return function(t) { n.forEach(function(e) { e(t) }) } } } /* 渐变 */ var transitions = { globalDone: null, funcs: [], counter: 0, uniqueID: 0, start: function(func, duration, done, delay, ease, name, id, cancelFun) { return ( (delay = delay || 0), this.funcs.push({ func: func, current: -delay * Math.abs(duration), //当前时间 duration: (1 - Math.max(delay, 0)) * Math.abs(duration), //总时长 done: done, easing: ease || easing.linearTween, //渐变曲线 cycling: duration < 0, running: !0, debug: delay < 0, name: name || 'T' + this.counter, id: void 0 === id ? this.counter : id, paused: !1, cancelFun: cancelFun //取消时执行的函数 }), func(0, 16), (this.counter += 1), func ) }, trigger: function(e) { var t = void 0 === e.delayRatio ? 0 : e.delayRatio, u = e.func || function() {}, r = void 0 === e.duration ? 0 : e.duration void 0 !== e.cycling && e.cycling && (r = -Math.abs(r)) var o = e.done || null, a = e.easing || easing.linearTween, s = e.name || 'R' + this.counter, l = void 0 === e.id ? this.counter : e.id return this.start(u, r, o, t, a, s, l) }, setTimeout: function(e, t, u) { var duration = void 0 === u ? this.counter : u return this.trigger({ done: e, duration: void 0 === t ? 0 : t, name: 'O' + this.counter, id: duration }) }, pause: function() { this.paused = !0 }, resume: function() { this.paused = !1 }, update: function(e) { this.funcs.forEach(function(t) { if (!(t.paused || ((t.current += 1e3 * e), t.current < 0))) if (t.current >= t.duration && !t.cycling) { var u = t.easing(1, 0, 1, 1) t.func(u, 1e3 * e), t.done && t.done(), (t.running = !1) } else { var duration = t.easing((t.current % t.duration) / t.duration, 0, 1, 1), r = t.func(duration, 1e3 * e) || !1 r && (t.done && t.done(), (t.running = !1)) } }) var t = this.funcs.length this.funcs = this.funcs.filter(function(e) { return e.running }) var u = this.funcs.length if (t > 0 && 0 === u && this.globalDone) { var duration = this.globalDone ;(this.globalDone = null), duration() } }, adjustSpeed: function(e, t) { for (var u = this.getById(e), duration = 0; duration < u.length; duration++) { var r = u[duration] ;(r.duration /= t), (r.current /= t) } }, getById: function(e) { return this.funcs.filter(function(t) { return e === t.id }) }, get: function(e) { for (var t = 0; t < this.funcs.length; t += 1) if (this.funcs[t].func === e) return this.funcs[t] return null }, isRunning: function(e) { var t = this.get(e) return null !== t && t.running }, countActive: function() { for (var e = 0, t = 0; t < this.funcs.length; t += 1) e += this.funcs[t].running return e }, listActive: function() { for (var e = [], t = 0; t < this.funcs.length; t += 1) this.funcs[t].running && e.push(this.funcs[t].name) return e }, done: function(e) { this.globalDone = e }, cancelById: function(e, dealCancelFun) { //xzw add dealDone var t = void 0 === e ? 0 : e let cancels = [] this.funcs = this.funcs.filter(function(e) { var is = e.id == t if (is && dealCancelFun) { e.cancelFun && cancels.push(e.cancelFun) //e.cancelFun && e.cancelFun() } return !is }) cancels.forEach(e => { e() }) //先从funcs中去除后再执行 }, cancel: function(e) { this.funcs = this.funcs.filter(function(t) { return t.func !== e }) }, getUniqueId: function() { return (this.uniqueID -= 1), this.uniqueID } } export { transitions, lerp, easing }