Source: tiny/actions/ActionInterval.js

import Action from './Action';
import { isNumber, deg2radian, radian2deg, hex2color, hex2rgb, rgb2hex } from '../../utils';

/**
 * @static
 * @memberof Tiny
 * @function MoveBy
 * @param {number} duration
 * @param {object} to
 * @param {number} to.x
 * @param {number} to.y
 * @return {Tiny.Action}
 */
export function MoveBy(duration, to) {
  const _to = {};
  Object.assign(_to, to);
  const action = new Action(duration, _to);
  action._to = to;
  action._onStart = function(tween, object) {
    action.to.x = object.x + to.x;
    action.to.y = object.y + to.y;
  };
  action._onUpdate = function(tween, object) {
    object.setPosition(tween.x, tween.y);
  };
  action._type = 'MoveBy';
  return action;
}

/**
 * @static
 * @memberof Tiny
 * @function MoveTo
 * @param {number} duration
 * @param {object} to
 * @param {number} to.x
 * @param {number} to.y
 * @return {Tiny.Action}
 */
export function MoveTo(duration, to) {
  const action = new Action(duration, to);
  action._onUpdate = function(tween, object) {
    object.setPosition(tween.x, tween.y);
  };
  action._type = 'MoveTo';
  return action;
}

/**
 * @static
 * @memberof Tiny
 * @function ScaleBy
 * @param {number} duration
 * @param {object} to
 * @param {object} to.scaleX
 * @param {object} to.scaleY
 * @return {Tiny.Action}
 */
export function ScaleBy(duration, to) {
  const _to = {};
  Object.assign(_to, to);
  const action = new Action(duration, _to);
  action._to = to;
  action._onStart = function(tween, object) {
    action.to.scaleX = object.scale.x * to.scaleX;
    action.to.scaleY = object.scale.y * to.scaleY;
  };
  action._onUpdate = function(tween, object) {
    object.setScale(tween.scaleX, tween.scaleY);
  };
  action._type = 'ScaleBy';
  return action;
}

/**
 * @static
 * @memberof Tiny
 * @function ScaleTo
 * @param {number} duration
 * @param {object} to
 * @param {object} to.scaleX
 * @param {object} to.scaleY
 * @return {Tiny.Action}
 */
export function ScaleTo(duration, to) {
  const action = new Action(duration, to);
  action._onUpdate = function(tween, object) {
    object.setScale(tween.scaleX, tween.scaleY);
  };
  action._type = 'ScaleTo';
  return action;
}

/**
 * @static
 * @memberof Tiny
 * @function RotateBy
 * @param {number} duration
 * @param {object} to
 * @param {number} to.rotation
 * @return {Tiny.Action}
 */
export function RotateBy(duration, to) {
  const _to = {};
  Object.assign(_to, to);
  const action = new Action(duration, _to);
  action._to = to;
  action._onStart = function(tween, object) {
    action.to.rotation = deg2radian(radian2deg(object.rotation) + radian2deg(to.rotation));
  };
  action._onUpdate = function(tween, object) {
    object.rotation = tween.rotation;
  };
  action._type = 'RotateBy';
  return action;
}

/**
 * @static
 * @memberof Tiny
 * @function RotateTo
 * @param {number} duration
 * @param {object} to
 * @param {number} to.rotation
 * @return {Tiny.Action}
 */
export function RotateTo(duration, to) {
  const action = new Action(duration, to);
  action._onUpdate = function(tween, object) {
    object.rotation = tween.rotation;
  };
  action._type = 'RotateTo';
  return action;
}

/**
 * @static
 * @memberof Tiny
 * @function JumpTo
 * @param {number} duration
 * @param {object} to
 * @param {number} height
 * @param {number} times
 * @return {Tiny.Action}
 */
export function JumpTo(duration, to, height, times) {
  const _to = {};
  Object.assign(_to, to);

  const newY = [];
  for (let i = 0; i < times * 2; i++) {
    if (i % 2 === 0) {
      newY.push(_to.y - height);
    } else {
      newY.push(_to.y);
    }
  }

  _to.y = newY;

  const action = new Action(duration, _to);
  action._to = to;
  action.yoyo = false;
  action.repeatTimes = 0;
  action._onUpdate = function(tween, object) {
    object.setPosition(tween.x, tween.y);
  };
  action._type = 'JumpTo';
  action._arg = [height, times];
  return action;
}

/**
 * @static
 * @memberof Tiny
 * @function Blink
 * @param {number} hideDuration
 * @param {number} showDuration
 * @return {Tiny.Action}
 */
export function Blink(hideDuration, showDuration) {
  const newVisible = [];
  for (let i = 0; i < hideDuration; i++) {
    newVisible.push(false);
  }
  for (let i = 0; i < showDuration; i++) {
    newVisible.push(true);
  }

  const action = new Action(showDuration + hideDuration, {
    visible: newVisible,
  });
  action.yoyo = false;
  action.repeatTimes = 0;
  action._onUpdate = function(tween, object) {
    object.visible = ~~tween.visible;
  };
  action._type = 'Blink';
  action._arg = [hideDuration, showDuration];
  return action;
}

/**
 * @static
 * @memberof Tiny
 * @function FadeTo
 * @param {number} duration
 * @param {number} to
 * @return {Tiny.Action}
 */
export function FadeTo(duration, to) {
  const action = new Action(duration, {
    alpha: to,
  });
  action._to = to;
  action.yoyo = false;
  action.repeatTimes = 0;
  action._onUpdate = function(tween, object) {
    object.setOpacity(tween.alpha);
  };
  action._type = 'FadeTo';
  return action;
}

/**
 * @static
 * @memberof Tiny
 * @function FadeIn
 * @param {number} duration
 * @return {Tiny.Action}
 */
export function FadeIn(duration) {
  return FadeTo(duration, 1);
}

/**
 * @static
 * @memberof Tiny
 * @function FadeOut
 * @param {number} duration
 * @return {Tiny.Action}
 */
export function FadeOut(duration) {
  return FadeTo(duration, 0);
}

/**
 * 注意:差值计算时,R、G、B三个通道,无论加减多少,最后的结果最少是0,最多是255。
 *
 * @example
 * var action = Tiny.TintBy(1000, Tiny.color(-85, 0, 85));
 * sprite.runAction(action);
 * //=> sprite.tint 等于 0xaaffff(即:[170, 255, 255])
 *
 * @static
 * @memberof Tiny
 * @function TintBy
 * @param {number} duration
 * @param {number|Tiny.color} color - 此处的 color 虽然是 Tiny.color 类型,但是并不代表某个色值,而是色值与色值直接要做的差值
 * @return {Tiny.Action}
 */
export function TintBy(duration, color) {
  if (isNumber(color)) {
    color = hex2color(color);
  }
  const _to = {};
  Object.assign(_to, color);
  const action = TintTo(duration, _to);
  action._to = color;
  action._onStart = function(tween, object) {
    const oc = hex2rgb(object.tint);
    action.to.colorR = oc[0] * 255 + color.colorR;
    action.to.colorG = oc[1] * 255 + color.colorG;
    action.to.colorB = oc[2] * 255 + color.colorB;
    action.to.colorR <= 0 && (action.to.colorR = 0);
    action.to.colorG <= 0 && (action.to.colorG = 0);
    action.to.colorB <= 0 && (action.to.colorB = 0);
    action.to.colorR >= 255 && (action.to.colorR = 255);
    action.to.colorG >= 255 && (action.to.colorG = 255);
    action.to.colorB >= 255 && (action.to.colorB = 255);
  };
  action._type = 'TintBy';
  action._arg = [duration, color];
  return action;
}

/**
 * @example
 * var action = Tiny.TintTo(1000, 0xFFFF00);
 * sprite.tint = 0xFF0000;
 * sprite.runAction(action);
 *
 * @example
 * // [255, 102, 0] 即橙色(#FF6600)
 * var action = Tiny.TintTo(1000, Tiny.color(255, 102, 0));
 * sprite.runAction(action);
 *
 * @static
 * @memberof Tiny
 * @function TintTo
 * @param {number} duration
 * @param {number|Tiny.color} color
 * @return {Tiny.Action}
 */
export function TintTo(duration, color) {
  if (isNumber(color)) {
    color = hex2color(color);
  }
  const action = new Action(duration, color);
  action._onUpdate = function(tween, object) {
    object.tint = rgb2hex([tween.colorR / 255, tween.colorG / 255, tween.colorB / 255]);
  };
  action._type = 'TintTo';
  action._arg = [duration, color];
  return action;
}

/**
 * 永久重复
 *
 * @static
 * @memberof Tiny
 * @function RepeatForever
 * @param {Tiny.Action} action - 要重复的 Action
 * @param {number} delay - 延迟(ms)
 * @return {Tiny.Action}
 */
export function RepeatForever(action, delay) {
  return Repeat(Infinity, action, delay);
}

/**
 * 重复
 *
 * @static
 * @memberof Tiny
 * @function Repeat
 * @param {number} times - 重复次数
 * @param {Tiny.Action} action - 要重复的 Action
 * @param {number} delay - 延迟(ms)
 * @return {Tiny.Action}
 */
export function Repeat(times, action, delay) {
  !delay && action.repeatDelayTime && (delay = action.repeatDelayTime);

  if (action._type && ['MoveBy', 'ScaleBy', 'RotateBy', 'TintBy'].indexOf(action._type) !== -1) {
    action._onComplete = function(tween, object) {
      if (!object.__tmp_times) {
        object.__tmp_times = 1;
      }
      object.__tmp_times++;
      if (object.__tmp_times > times) {
        return;
      }
      if (action._caller === 'runAction') {
        let fn;
        switch (action._type) {
          case 'MoveBy':
            fn = MoveBy;
            break;
          case 'ScaleBy':
            fn = ScaleBy;
            break;
          case 'RotateBy':
            fn = RotateBy;
            break;
          case 'TintBy':
            fn = TintBy;
            break;
        }
        if (!fn) {
          return;
        }
        const act = fn(action.duration, Object.assign(Object.create(Object.prototype), action._to || action.to));
        act._onComplete = action._onComplete;
        delay && act.setDelay(delay);
        act.onStart = action.onStart;
        act.onUpdate = action.onUpdate;
        act.onComplete = action.onComplete;
        object.runAction(act);
      }
    };
    return action;
  }

  action.repeatDelayTime = delay;
  action.repeatTimes = times - 1;
  action._type = 'Repeat';
  return action;
}

/**
 * 原动作返回
 *
 * @static
 * @memberof Tiny
 * @function Back
 * @param {Tiny.Action} action
 * @return {Tiny.Action}
 */
export function Back(action) {
  action.yoyo = true;
  if (!action.repeatTimes) {
    action.repeatTimes = 1;
  }
  if (action._type === 'Repeat') {
    action.repeatTimes = (action.repeatTimes - 1) * 2 + 1;
  }
  action._type = 'Back';
  return action;
}
Documentation generated by JSDoc 3.4.3 on Fri Jul 09 2021 19:32:25 GMT+0800 (CST)