js/SceneKit/SCNActionRepeat.js
- 'use strict'
-
- import SCNAction from './SCNAction'
- import SCNActionTimingMode from './SCNActionTimingMode'
-
- export default class SCNActionRepeat extends SCNAction {
- static get _propTypes() {
- return {
- _timesToRepeat: 'float',
- _finished: 'boolean',
- _duration: 'float',
- _timingMode: 'integer',
- _beginTime: 'float',
- _isRunning: 'boolean',
- _repeatedAction: 'SCNAction',
- _forever: 'boolean',
- _timesRepeated: 'integer',
- _pausedTime: 'float',
-
- name: ['string', null]
- }
- }
-
- /**
- * constructor
- * @access public
- * @constructor
- */
- constructor() {
- super()
-
- this._timesToRepeat = 0
- this._repeatedAction = null
- this._forever = false
- this._timesRepeated = 0
- this._finished = false
- this._duration = 0
- this._timingMode = SCNActionTimingMode.linear
- this._beginTime = 0
- this._isRunning = false
- this._pausedTime = 0
- }
-
- /**
- * Creates an action that repeats another action a specified number of times.
- * @access public
- * @param {SCNAction} action - The action to be executed.
- * @param {number} count - The number of times to execute the action.
- * @returns {SCNAction} -
- * @desc When the action executes, the associated action runs to completion and then repeats, until the count is reached.This action is reversible; it creates a new action that is the reverse of the specified action and then repeats it the same number of times.
- * @see https://developer.apple.com/documentation/scenekit/scnaction/1522764-repeat
- */
- static repeat(action, count) {
- const _action = new SCNActionRepeat()
- _action._repeatedAction = action
- _action._duration = action.duration
- _action._timesToRepeat = count
- _action._forever = (count === Infinity)
- return _action
- }
-
- /**
- * Creates an action that repeats another action forever.
- * @access public
- * @param {SCNAction} action - The action to execute.
- * @returns {SCNAction} -
- * @desc When the action executes, the associated action runs to completion and then repeats.This action is reversible; it creates a new action that is the reverse of the specified action and then repeats it forever.NoteThe action to be repeated must have a non-instantaneous duration.
- * @see https://developer.apple.com/documentation/scenekit/scnaction/1522908-repeatforever
- */
- static repeatForever(action) {
- return this.repeat(action, Infinity)
- }
-
- /**
- * @access public
- * @returns {SCNActionRepeat} -
- */
- copy() {
- const action = super.copy()
-
- action._timesToRepeat = this._timesToRepeat
- action._repeatedAction = this._repeatedAction.copy()
- action._forever = this._forever
- action._timesRepeated = this._timesRepeated
-
- return action
- }
-
- _getTime(time, needTimeConversion) {
- if(!needTimeConversion){
- return time
- }
-
- const baseTime = this._basetimeFromTime(time)
- if(this.timingFunction === null){
- return baseTime
- }
-
- const n = Math.floor(baseTime)
- const t = this.timingFunction._getValueAtTime(baseTime - n)
- return n + t
- }
-
- /**
- * apply action to the given node.
- * @access private
- * @param {Object} obj - target object to apply this action.
- * @param {number} time - active time
- * @param {boolean} [needTimeConversion = true] -
- * @returns {void}
- */
- _applyAction(obj, time, needTimeConversion = true) {
- const dt = this._getTime(time, needTimeConversion)
- const timesRepeated = Math.floor(dt)
- while(timesRepeated > this._timesRepeated){
- this._timesRepeated += 1
- this._repeatedAction._applyAction(obj, 1.0, false)
- if(!this._forever && this._timesRepeated >= this._timesToRepeat){
- this._finished = true
- return
- }
- this._repeatedAction._resetFinished()
- }
- let t = dt - this._timesRepeated
- this._repeatedAction._applyAction(obj, t, false)
- this._finished = false
- }
-
- get duration() {
- if(this._forever){
- return Infinity
- }
- return this._repeatedAction.duration * this._timesToRepeat
- }
-
- _resetFinished() {
- this._repeatedAction._resetFinished()
- this._timesRepeated = 0
- this._finished = false
- }
- }
-
- SCNAction.repeat = SCNActionRepeat.repeat
- SCNAction.repeatForever = SCNActionRepeat.repeatForever