transitions.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436
  1. var easing = {}
  2. //渐变曲线函数,反应加速度的变化
  3. //currentTime:x轴当前时间(从0-到duration), startY:起始点, duration:总时长, wholeY:路程 (即endY-startY)
  4. //参数基本是 x, 0, 1, 1
  5. /*
  6. easeOut 基本是y= m * (x-dur)^k + n, 若k为偶数,m<0, 若k为奇数,m>0; (因为偶数的话必须开口向下才能获得斜率递减的递增的那段,而奇数是对称的,单调递增. )
  7. 根据x=0时y=0, x=dur时y=S , 得 n = S,m = -S/(-dur)^k
  8. */
  9. easing.getEaseOut = function(k) {
  10. // k 是>=2的整数. 越大变化率越大, 相同初始速度所需要时间越久
  11. let easeFun
  12. k = Math.round(k)
  13. if (k < 2) {
  14. k = Math.PI / 2
  15. easeFun = easing.easeOutSine
  16. } else {
  17. easeFun = function(currentTime, startY, wholeY, duration) {
  18. if (k > 2) {
  19. console.log(k)
  20. }
  21. return (-wholeY / Math.pow(-duration, k)) * Math.pow(currentTime - duration, k) + wholeY
  22. }
  23. }
  24. return {
  25. k,
  26. easeFun
  27. }
  28. }
  29. ;(easing.linearTween = function(currentTime, startY, wholeY, duration) {
  30. return (wholeY * currentTime) / duration + startY
  31. }),
  32. (easing.easeInQuad = function(currentTime, startY, wholeY, duration) {
  33. return (currentTime /= duration), wholeY * currentTime * currentTime + startY
  34. }),
  35. (easing.easeOutQuad = function(currentTime, startY, wholeY, duration) {
  36. // 如套上实际的距离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
  37. return (currentTime /= duration), -wholeY * currentTime * (currentTime - 2) + startY
  38. }),
  39. (easing.easeInOutQuad = function(currentTime, startY, wholeY, duration) {
  40. return (currentTime /= duration / 2), currentTime < 1 ? (wholeY / 2) * currentTime * currentTime + startY : (currentTime--, (-wholeY / 2) * (currentTime * (currentTime - 2) - 1) + startY)
  41. }),
  42. (easing.easeInCubic = function(currentTime, startY, wholeY, duration) {
  43. return (currentTime /= duration), wholeY * currentTime * currentTime * currentTime + startY
  44. }),
  45. (easing.easeOutCubic = function(currentTime, startY, wholeY, duration) {
  46. // y = S / dur^3 *(x-dur)^3 + S,对称中心是(dur,S),从0-dur是 斜率递减的递增函数,导数为3S/dur^3 * (x-dur)^2, 0时速度为3S/dur
  47. return (currentTime /= duration), currentTime--, wholeY * (currentTime * currentTime * currentTime + 1) + startY
  48. }),
  49. (easing.easeInOutCubic = function(currentTime, startY, wholeY, duration) {
  50. return (
  51. (currentTime /= duration / 2),
  52. currentTime < 1 ? (wholeY / 2) * currentTime * currentTime * currentTime + startY : ((currentTime -= 2), (wholeY / 2) * (currentTime * currentTime * currentTime + 2) + startY)
  53. )
  54. }),
  55. (easing.easeInQuart = function(currentTime, startY, wholeY, duration) {
  56. return (currentTime /= duration), wholeY * currentTime * currentTime * currentTime * currentTime + startY
  57. }),
  58. (easing.easeOutQuart = function(currentTime, startY, wholeY, duration) {
  59. //根据上面的计算,估计0时速度应该是4S/dur吧……
  60. return (currentTime /= duration), currentTime--, -wholeY * (currentTime * currentTime * currentTime * currentTime - 1) + startY
  61. }),
  62. (easing.easeInOutQuart = function(currentTime, startY, wholeY, duration) {
  63. return (
  64. (currentTime /= duration / 2),
  65. currentTime < 1
  66. ? (wholeY / 2) * currentTime * currentTime * currentTime * currentTime + startY
  67. : ((currentTime -= 2), (-wholeY / 2) * (currentTime * currentTime * currentTime * currentTime - 2) + startY)
  68. )
  69. }),
  70. (easing.easeInQuint = function(currentTime, startY, wholeY, duration) {
  71. return (currentTime /= duration), wholeY * currentTime * currentTime * currentTime * currentTime * currentTime + startY
  72. }),
  73. (easing.easeOutQuint = function(currentTime, startY, wholeY, duration) {
  74. return (currentTime /= duration), currentTime--, wholeY * (currentTime * currentTime * currentTime * currentTime * currentTime + 1) + startY
  75. }),
  76. (easing.easeInOutQuint = function(currentTime, startY, wholeY, duration) {
  77. return (
  78. (currentTime /= duration / 2),
  79. currentTime < 1
  80. ? (wholeY / 2) * currentTime * currentTime * currentTime * currentTime * currentTime + startY
  81. : ((currentTime -= 2), (wholeY / 2) * (currentTime * currentTime * currentTime * currentTime * currentTime + 2) + startY)
  82. )
  83. }),
  84. (easing.easeInSine = function(currentTime, startY, wholeY, duration) {
  85. return -wholeY * Math.cos((currentTime / duration) * (Math.PI / 2)) + wholeY + startY
  86. }),
  87. (easing.easeOutSine = function(currentTime, startY, wholeY, duration) {
  88. // y' = S * PI / 2 / dur * cos(PI/2/dur * x)
  89. console.log('easeOutSine')
  90. return wholeY * Math.sin((currentTime / duration) * (Math.PI / 2)) + startY
  91. }),
  92. (easing.easeInOutSine = function(currentTime, startY, wholeY, duration) {
  93. return (-wholeY / 2) * (Math.cos((Math.PI * currentTime) / duration) - 1) + startY
  94. }),
  95. (easing.easeInExpo = function(currentTime, startY, wholeY, duration) {
  96. return wholeY * Math.pow(2, 10 * (currentTime / duration - 1)) + startY
  97. }),
  98. (easing.easeOutExpo = function(currentTime, startY, wholeY, duration) {
  99. return wholeY * (-Math.pow(2, (-10 * currentTime) / duration) + 1) + startY
  100. }),
  101. (easing.easeInOutExpo = function(currentTime, startY, wholeY, duration) {
  102. return (
  103. (currentTime /= duration / 2),
  104. currentTime < 1 ? (wholeY / 2) * Math.pow(2, 10 * (currentTime - 1)) + startY : (currentTime--, (wholeY / 2) * (-Math.pow(2, -10 * currentTime) + 2) + startY)
  105. )
  106. }),
  107. (easing.easeInCirc = function(currentTime, startY, wholeY, duration) {
  108. return (currentTime /= duration), -wholeY * (Math.sqrt(1 - currentTime * currentTime) - 1) + startY
  109. }),
  110. (easing.easeOutCirc = function(currentTime, startY, wholeY, duration) {
  111. return (currentTime /= duration), currentTime--, wholeY * Math.sqrt(1 - currentTime * currentTime) + startY
  112. }),
  113. (easing.easeInOutCirc = function(currentTime, startY, wholeY, duration) {
  114. return (
  115. (currentTime /= duration / 2),
  116. currentTime < 1 ? (-wholeY / 2) * (Math.sqrt(1 - currentTime * currentTime) - 1) + startY : ((currentTime -= 2), (wholeY / 2) * (Math.sqrt(1 - currentTime * currentTime) + 1) + startY)
  117. )
  118. }),
  119. (easing.easeInElastic = function(currentTime, startY, wholeY, duration) {
  120. var r = 1.70158,
  121. o = 0,
  122. a = wholeY
  123. return 0 === currentTime
  124. ? startY
  125. : 1 === (currentTime /= duration)
  126. ? startY + wholeY
  127. : (o || (o = 0.3 * duration),
  128. a < Math.abs(wholeY) ? ((a = wholeY), (r = o / 4)) : (r = (o / (2 * Math.PI)) * Math.asin(wholeY / a)),
  129. -(a * Math.pow(2, 10 * (currentTime -= 1)) * Math.sin(((currentTime * duration - r) * (2 * Math.PI)) / o)) + startY)
  130. }),
  131. (easing.easeOutElastic = function(currentTime, startY, wholeY, duration) {
  132. var r = 1.70158,
  133. o = 0,
  134. a = wholeY
  135. return 0 === currentTime
  136. ? startY
  137. : 1 === (currentTime /= duration)
  138. ? startY + wholeY
  139. : (o || (o = 0.3 * duration),
  140. a < Math.abs(wholeY) ? ((a = wholeY), (r = o / 4)) : (r = (o / (2 * Math.PI)) * Math.asin(wholeY / a)),
  141. a * Math.pow(2, -10 * currentTime) * Math.sin(((currentTime * duration - r) * (2 * Math.PI)) / o) + wholeY + startY)
  142. }),
  143. (easing.easeInOutElastic = function(currentTime, startY, wholeY, duration) {
  144. var r = 1.70158,
  145. o = 0,
  146. a = wholeY
  147. return 0 === currentTime
  148. ? startY
  149. : 2 === (currentTime /= duration / 2)
  150. ? startY + wholeY
  151. : (o || (o = duration * (0.3 * 1.5)),
  152. a < Math.abs(wholeY) ? ((a = wholeY), (r = o / 4)) : (r = (o / (2 * Math.PI)) * Math.asin(wholeY / a)),
  153. currentTime < 1
  154. ? -0.5 * (a * Math.pow(2, 10 * (currentTime -= 1)) * Math.sin(((currentTime * duration - r) * (2 * Math.PI)) / o)) + startY
  155. : a * Math.pow(2, -10 * (currentTime -= 1)) * Math.sin(((currentTime * duration - r) * (2 * Math.PI)) / o) * 0.5 + wholeY + startY)
  156. }),
  157. (easing.easeInBack = function(currentTime, startY, wholeY, duration, r) {
  158. return void 0 === r && (r = 1.70158), wholeY * (currentTime /= duration) * currentTime * ((r + 1) * currentTime - r) + startY
  159. }),
  160. (easing.easeOutBack = function(currentTime, startY, wholeY, duration, r) {
  161. return void 0 === r && (r = 1.70158), wholeY * ((currentTime = currentTime / duration - 1) * currentTime * ((r + 1) * currentTime + r) + 1) + startY
  162. }),
  163. (easing.easeInOutBack = function(currentTime, startY, wholeY, duration, r) {
  164. return (
  165. void 0 === r && (r = 1.70158),
  166. (currentTime /= duration / 2) < 1
  167. ? (wholeY / 2) * (currentTime * currentTime * (((r *= 1.525) + 1) * currentTime - r)) + startY
  168. : (wholeY / 2) * ((currentTime -= 2) * currentTime * (((r *= 1.525) + 1) * currentTime + r) + 2) + startY
  169. )
  170. }),
  171. (easing.easeOutBounce = function(currentTime, startY, wholeY, duration) {
  172. return (currentTime /= duration) < 1 / 2.75
  173. ? wholeY * (7.5625 * currentTime * currentTime) + startY
  174. : currentTime < 2 / 2.75
  175. ? wholeY * (7.5625 * (currentTime -= 1.5 / 2.75) * currentTime + 0.75) + startY
  176. : currentTime < 2.5 / 2.75
  177. ? wholeY * (7.5625 * (currentTime -= 2.25 / 2.75) * currentTime + 0.9375) + startY
  178. : wholeY * (7.5625 * (currentTime -= 2.625 / 2.75) * currentTime + 0.984375) + startY
  179. }),
  180. (easing.easeInBounce = function(currentTime, startY, wholeY, r) {
  181. return wholeY - easing.easeOutBounce(r - currentTime, 0, wholeY, r) + startY
  182. }),
  183. (easing.easeInOutBounce = function(currentTime, startY, wholeY, r) {
  184. 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
  185. })
  186. var lerp = {
  187. /* vector: function(currentTime, startY, f) {//xzw change, add f
  188. var wholeY = currentTime.clone();
  189. return startY = startY.clone(),
  190. function(duration) {
  191. currentTime.set(wholeY.x * (1 - duration) + startY.x * duration, wholeY.y * (1 - duration) + startY.y * duration, wholeY.z * (1 - duration) + startY.z * duration)
  192. f && f(currentTime,duration);
  193. }
  194. },
  195. quaternion: function(currentTime, startY, f) {//xzw change, add f
  196. var wholeY = currentTime.clone();
  197. return function(duration) {
  198. currentTime.copy(wholeY).slerp(startY, duration);
  199. f && f(currentTime,duration);
  200. }
  201. },
  202. property: function(currentTime, startY, wholeY, duration) {
  203. var r = currentTime[startY];
  204. return function(o) {
  205. currentTime[startY] = r * (1 - o) + wholeY * o,
  206. duration && duration(currentTime[startY])
  207. }
  208. },
  209. uniform: function(currentTime, startY, wholeY) {
  210. var duration = currentTime.material.uniforms[startY].value;
  211. return function(r) {
  212. try{
  213. currentTime.material.uniforms[startY] && (currentTime.material.uniforms[startY].value = duration * (1 - r) + wholeY * r)
  214. }catch(currentTime){
  215. console.log(1)
  216. }
  217. }
  218. },
  219. matrix4: function(currentTime, startY) {
  220. var wholeY = currentTime.clone();
  221. return function(duration) {
  222. for (var r = currentTime.elements, o = wholeY.elements, a = startY.elements, s = 0; s < 16; s++)
  223. r[s] = o[s] * (1 - duration) + a[s] * duration
  224. }
  225. },
  226. allUniforms: function(currentTime, startY, wholeY) {
  227. var duration = currentTime.map(function(currentTime) {
  228. return this.uniform(currentTime, startY, wholeY)
  229. }
  230. .bind(this));
  231. return function(currentTime) {
  232. duration.forEach(function(startY) {
  233. startY(currentTime)
  234. })
  235. }
  236. } */
  237. vector: function(t, i, f) {
  238. //xzw change, add f
  239. var n = t.clone()
  240. return (
  241. (i = i.clone()),
  242. function(e) {
  243. t.set(n.x * (1 - e) + i.x * e, n.y * (1 - e) + i.y * e, n.z * (1 - e) + i.z * e)
  244. f && f(t, e)
  245. }
  246. )
  247. },
  248. quaternion: function(t, i, f) {
  249. //xzw change, add f
  250. var n = t.clone()
  251. return function(e) {
  252. t.copy(n).slerp(i, e)
  253. f && f(t, e)
  254. }
  255. },
  256. property: function(t, i, n, r) {
  257. var o = t[i]
  258. return function(e) {
  259. ;(t[i] = o * (1 - e) + n * e), r && r(t[i])
  260. }
  261. },
  262. uniform: function(t, i, n) {
  263. var r = t.material.uniforms[i].value
  264. return function(e) {
  265. t.material.uniforms[i] && (t.material.uniforms[i].value = r * (1 - e) + n * e)
  266. }
  267. },
  268. matrix4: function(o, a) {
  269. var s = o.clone()
  270. return function(e) {
  271. 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
  272. }
  273. },
  274. allUniforms: function(e, t, i) {
  275. var n = e.map(
  276. function(e) {
  277. return this.uniform(e, t, i)
  278. }.bind(this)
  279. )
  280. return function(t) {
  281. n.forEach(function(e) {
  282. e(t)
  283. })
  284. }
  285. }
  286. }
  287. /*
  288. 渐变
  289. */
  290. var transitions = {
  291. globalDone: null,
  292. funcs: [],
  293. counter: 0,
  294. uniqueID: 0,
  295. start: function(func, duration, done, delay, ease, name, id, cancelFun) {
  296. return (
  297. (delay = delay || 0),
  298. this.funcs.push({
  299. func: func,
  300. current: -delay * Math.abs(duration), //当前时间
  301. duration: (1 - Math.max(delay, 0)) * Math.abs(duration), //总时长
  302. done: done,
  303. easing: ease || easing.linearTween, //渐变曲线
  304. cycling: duration < 0,
  305. running: !0,
  306. debug: delay < 0,
  307. name: name || 'T' + this.counter,
  308. id: void 0 === id ? this.counter : id,
  309. paused: !1,
  310. cancelFun: cancelFun //取消时执行的函数
  311. }),
  312. func(0, 16),
  313. (this.counter += 1),
  314. func
  315. )
  316. },
  317. trigger: function(e) {
  318. var t = void 0 === e.delayRatio ? 0 : e.delayRatio,
  319. u = e.func || function() {},
  320. r = void 0 === e.duration ? 0 : e.duration
  321. void 0 !== e.cycling && e.cycling && (r = -Math.abs(r))
  322. var o = e.done || null,
  323. a = e.easing || easing.linearTween,
  324. s = e.name || 'R' + this.counter,
  325. l = void 0 === e.id ? this.counter : e.id
  326. return this.start(u, r, o, t, a, s, l)
  327. },
  328. setTimeout: function(e, t, u) {
  329. var duration = void 0 === u ? this.counter : u
  330. return this.trigger({
  331. done: e,
  332. duration: void 0 === t ? 0 : t,
  333. name: 'O' + this.counter,
  334. id: duration
  335. })
  336. },
  337. pause: function() {
  338. this.paused = !0
  339. },
  340. resume: function() {
  341. this.paused = !1
  342. },
  343. update: function(e) {
  344. this.funcs.forEach(function(t) {
  345. if (!(t.paused || ((t.current += 1e3 * e), t.current < 0)))
  346. if (t.current >= t.duration && !t.cycling) {
  347. var u = t.easing(1, 0, 1, 1)
  348. t.func(u, 1e3 * e), t.done && t.done(), (t.running = !1)
  349. } else {
  350. var duration = t.easing((t.current % t.duration) / t.duration, 0, 1, 1),
  351. r = t.func(duration, 1e3 * e) || !1
  352. r && (t.done && t.done(), (t.running = !1))
  353. }
  354. })
  355. var t = this.funcs.length
  356. this.funcs = this.funcs.filter(function(e) {
  357. return e.running
  358. })
  359. var u = this.funcs.length
  360. if (t > 0 && 0 === u && this.globalDone) {
  361. var duration = this.globalDone
  362. ;(this.globalDone = null), duration()
  363. }
  364. },
  365. adjustSpeed: function(e, t) {
  366. for (var u = this.getById(e), duration = 0; duration < u.length; duration++) {
  367. var r = u[duration]
  368. ;(r.duration /= t), (r.current /= t)
  369. }
  370. },
  371. getById: function(e) {
  372. return this.funcs.filter(function(t) {
  373. return e === t.id
  374. })
  375. },
  376. get: function(e) {
  377. for (var t = 0; t < this.funcs.length; t += 1) if (this.funcs[t].func === e) return this.funcs[t]
  378. return null
  379. },
  380. isRunning: function(e) {
  381. var t = this.get(e)
  382. return null !== t && t.running
  383. },
  384. countActive: function() {
  385. for (var e = 0, t = 0; t < this.funcs.length; t += 1) e += this.funcs[t].running
  386. return e
  387. },
  388. listActive: function() {
  389. for (var e = [], t = 0; t < this.funcs.length; t += 1) this.funcs[t].running && e.push(this.funcs[t].name)
  390. return e
  391. },
  392. done: function(e) {
  393. this.globalDone = e
  394. },
  395. cancelById: function(e, dealCancelFun) {
  396. //xzw add dealDone
  397. var t = void 0 === e ? 0 : e
  398. let cancels = []
  399. this.funcs = this.funcs.filter(function(e) {
  400. var is = e.id == t
  401. if (is && dealCancelFun) {
  402. e.cancelFun && cancels.push(e.cancelFun)
  403. //e.cancelFun && e.cancelFun()
  404. }
  405. return !is
  406. })
  407. cancels.forEach(e => {
  408. e()
  409. }) //先从funcs中去除后再执行
  410. },
  411. cancel: function(e) {
  412. this.funcs = this.funcs.filter(function(t) {
  413. return t.func !== e
  414. })
  415. },
  416. getUniqueId: function() {
  417. return (this.uniqueID -= 1), this.uniqueID
  418. }
  419. }
  420. export { transitions, lerp, easing }