Home Reference Source Repository

js/QuartzCore/CABasicAnimation.js

  1. 'use strict'
  2.  
  3. import CAPropertyAnimation from './CAPropertyAnimation'
  4.  
  5. /**
  6. * An object that provides basic, single-keyframe animation capabilities for a layer property.
  7. * @access public
  8. * @extends {CAPropertyAnimation}
  9. * @see https://developer.apple.com/documentation/quartzcore/cabasicanimation
  10. */
  11. export default class CABasicAnimation extends CAPropertyAnimation {
  12.  
  13. /**
  14. * constructor
  15. * @access public
  16. * @param {?string} path -
  17. * @constructor
  18. */
  19. constructor(path) {
  20. super(path)
  21.  
  22. // Interpolation values
  23.  
  24. /**
  25. * Defines the value the receiver uses to start interpolation.
  26. * @type {?Object}
  27. * @see https://developer.apple.com/documentation/quartzcore/cabasicanimation/1412519-fromvalue
  28. */
  29. this.fromValue = null
  30.  
  31. /**
  32. * Defines the value the receiver uses to end interpolation.
  33. * @type {?Object}
  34. * @see https://developer.apple.com/documentation/quartzcore/cabasicanimation/1412523-tovalue
  35. */
  36. this.toValue = null
  37.  
  38. /**
  39. * Defines the value the receiver uses to perform relative interpolation.
  40. * @type {?Object}
  41. * @see https://developer.apple.com/documentation/quartzcore/cabasicanimation/1412445-byvalue
  42. */
  43. this.byValue = null
  44.  
  45. this._baseValue = null
  46. }
  47.  
  48. /**
  49. * @access public
  50. * @returns {CABasicAnimation} -
  51. */
  52. copy() {
  53. const anim = super.copy()
  54. //anim._copyValue(this)
  55.  
  56. anim.fromValue = this.fromValue
  57. anim.toValue = this.toValue
  58. anim.byValue = this.byValue
  59.  
  60. return anim
  61. }
  62.  
  63. /*
  64. _copyValue(src) {
  65. this.fromValue = src.fromValue
  66. this.toValue = src.toValue
  67. this.byValue = src.byValue
  68. }
  69. */
  70.  
  71. /**
  72. * apply animation to the given node.
  73. * @access private
  74. * @param {Object} obj - target object to apply this animation.
  75. * @param {number} time - active time
  76. * @param {boolean} [needTimeConversion = true] -
  77. * @returns {void}
  78. */
  79. _applyAnimation(obj, time, needTimeConversion = true) {
  80. let t = time
  81. if(needTimeConversion){
  82. const baseTime = this._basetimeFromTime(time)
  83. if(baseTime === null){
  84. return
  85. }
  86. t = baseTime
  87. if(this.timingFunction !== null){
  88. t = this.timingFunction._getValueAtTime(baseTime)
  89. }
  90. if(t < 0){
  91. t = 0
  92. }
  93. if(t > 1){
  94. t = 1
  95. }
  96. //if(this.keyPath === 'rotation.w'){
  97. // console.log(`time: ${time}, activeTime: ${time - this._animationStartTime}, baseTime: ${baseTime}, t: ${t}`)
  98. //}
  99. }
  100.  
  101. let isObject = false
  102. if(this._baseValue === null || this.isAdditive){
  103. this._baseValue = obj.valueForKeyPath(this.keyPath, false)
  104. }
  105. if(typeof this._baseValue !== 'number' && this._baseValue !== null){
  106. isObject = true
  107. }
  108.  
  109. let fromValue = 0
  110. let toValue = 0
  111. if(this.fromValue !== null && this.toValue !== null){
  112. fromValue = this.fromValue
  113. toValue = this.toValue
  114. }else if(this.fromValue !== null && this.byValue !== null){
  115. fromValue = this.fromValue
  116. if(isObject){
  117. toValue = this.fromValue.add(this.byValue)
  118. }else{
  119. toValue = this.fromValue + this.byValue
  120. }
  121. }else if(this.byValue !== null && this.toValue !== null){
  122. if(isObject){
  123. fromValue = this.toValue.sub(this.byValue)
  124. }else{
  125. fromValue = this.toValue - this.byValue
  126. }
  127. toValue = toValue
  128. }else if(this.fromValue !== null){
  129. fromValue = this.fromValue
  130. if(this.isAdditive){
  131. if(isObject){
  132. toValue = this._baseValue.zero()
  133. }else{
  134. toValue = 0
  135. }
  136. }else{
  137. toValue = this._baseValue
  138. }
  139. }else if(this.toValue !== null){
  140. if(this.isAdditive){
  141. if(isObject){
  142. fromValue = this._baseValue.zero()
  143. }else{
  144. fromValue = 0
  145. }
  146. }else{
  147. fromValue = this._baseValue
  148. }
  149. toValue = this.toValue
  150. }else if(this.byValue !== null){
  151. if(this.isAdditive){
  152. if(isObject){
  153. fromValue = this._baseValue.zero()
  154. }else{
  155. fromValue = 0
  156. }
  157. toValue = this.byValue
  158. }else{
  159. fromValue = this._baseValue
  160. if(isObject){
  161. toValue = this._baseValue.add(this.byValue)
  162. }else{
  163. toValue = this._baseValue + this.byValue
  164. }
  165. }
  166. }else{
  167. // TODO: retain prevValue
  168. //value = this._lerp(prevValue, currentValue, t)
  169. }
  170. let value = this._lerp(fromValue, toValue, t)
  171.  
  172. //if(this.keyPath === 'rotation.w'){
  173. // console.log(`from: ${fromValue}, to: ${toValue}, t: ${t}, value: ${value}`)
  174. //}
  175.  
  176. if(this.isAdditive){
  177. if(isObject){
  178. //value = value.add(obj.valueForKeyPath(this.keyPath))
  179. value = value.add(this._baseValue)
  180. }else{
  181. value += this._baseValue
  182. }
  183. }
  184.  
  185. //if(this.keyPath === 'rotation.w'){
  186. // console.log(`value after: ${value}`)
  187. //}
  188.  
  189. //console.log(`CABasicAnimation._applyAnimation: keyPath: ${this.keyPath}, time: ${time}, baseTime: ${baseTime}, t: ${t}, value: ${value}`)
  190. this._applyValue(obj, value)
  191. this._handleEvents(obj, t)
  192. }
  193. }