diff --git a/js-framework/src/ui/animation.ts b/js-framework/src/ui/animation.ts index 1cbadb59..2b0e43bd 100644 --- a/js-framework/src/ui/animation.ts +++ b/js-framework/src/ui/animation.ts @@ -1,3 +1,5 @@ +import { Modeling, Model } from "../util/types" + /* * Copyright [2019] [Doric.Pub] * @@ -14,159 +16,196 @@ * limitations under the License. */ + +export type AnimatedKey = "translationX" | "translationY" | "scaleX" | "scaleY" | "rotation" | "pivotX" | "pivotY" export enum RepeatMode { RESTART, REVERSE, } - -export class Animation { - - translationX?: number - - translationY?: number - - scaleX?: number - - scaleY?: number - - pivotX?: number - - pivotY?: number - - rotation?: number - - duration = 100 - - startDelay = 0 - - repeatCount = 1 - - repeatMode = RepeatMode.RESTART +export interface IAnimation extends Modeling { + repeatCount?: number + repeatMode?: RepeatMode + duration: number + delay?: number } -export class AnimationSetBuilder { - currentNode: Node - group: AnimationSet - - constructor(group: AnimationSet, anim: Animation) { - this.currentNode = group.getNodeForAnimation(anim) - this.group = group - } - - with(animation: Animation) { - const node = this.group.getNodeForAnimation(animation) - this.currentNode.addSibling(node) - return this - } - - after(animation: Animation) { - const node = this.group.getNodeForAnimation(animation) - this.currentNode.addParent(node) - return this - } - - before(animation: Animation) { - const node = this.group.getNodeForAnimation(animation) - this.currentNode.addChild(node) - return this - } +export interface Changeable { + fromValue: number + toValue: number + key: AnimatedKey } -class Node { - children: Set = new Set - siblings: Set = new Set - parents: Set = new Set - animation: Animation - built = false - constructor(anim: Animation) { - this.animation = anim - } +abstract class Animation implements IAnimation { + changeables: Map = new Map + duration = 0 + repeatCount?: number + repeatMode?: RepeatMode + delay?: number - addParent(node: Node) { - if (!this.parents.has(node)) { - this.parents.add(node); - node.addChild(this); - } - } - - addSibling(node: Node) { - if (!this.siblings.has(node)) { - this.siblings.add(node); - node.addSibling(this); - } - } - - addChild(node: Node) { - if (!this.children.has(node)) { - this.children.add(node) - node.addParent(this) - } - } -} -export class AnimationSet { - nodeMap: Map = new Map - nodes: Node[] = [] - - getNodeForAnimation(anim: Animation) { - let node = this.nodeMap.get(anim) - if (node === undefined) { - node = new Node(anim) - this.nodeMap.set(anim, node) - this.nodes.push(node) - } - return node; - } - play(animation: Animation) { - return new AnimationSetBuilder(this, animation) - } - - playTogether(animations: Animation[]) { - if (animations.length == 1) { - this.play(animations[0]); - } else { - for (let i = 0; i < animations.length - 1; i++) { - this.play(animations[i]).with(animations[i + 1]) - } - } - } - - playSequentially(animations: Animation[]) { - if (animations.length == 1) { - this.play(animations[0]); - } else { - for (let i = 0; i < animations.length - 1; i++) { - this.play(animations[i]).before(animations[i + 1]) - } - } - } - findSiblings(node: Node, siblings: Set) { - if (!siblings.has(node)) { - siblings.add(node) - node.siblings.forEach(e => { - this.findSiblings(e, siblings) + toModel() { + const ret = [] + for (let e of this.changeables.values()) { + ret.push({ + repeatCount: this.repeatCount, + repeatMode: this.repeatMode, + delay: this.delay, + duration: this.duration, + key: e.key, + fromValue: e.fromValue, + toValue: e.toValue, }) } - } - createDependencyGraph() { - this.nodes.forEach(node => { - if (node.built) { - return - } - this.findSiblings(node, node.siblings) - node.siblings.delete(node) - node.siblings.forEach(e => { - e.parents.forEach(p => { - node.addParent(p) - }) - }) - node.built = true - - node.siblings.forEach(s => { - node.parents.forEach(p => { - s.addParent(p) - }) - s.built = true - }) - }) + return ret } } + +export class ScaleAnimation extends Animation { + private scaleXChaneable: Changeable = { + key: "scaleX", + fromValue: 1, + toValue: 1, + } + private scaleYChangeable: Changeable = { + key: "scaleY", + fromValue: 1, + toValue: 1, + } + constructor() { + super() + this.changeables.set("scaleX", this.scaleXChaneable) + this.changeables.set("scaleY", this.scaleXChaneable) + } + + + set fromScaleX(v: number) { + this.scaleXChaneable.fromValue = v + } + + get fromScaleX() { + return this.scaleXChaneable.fromValue + } + + set toScaleX(v: number) { + this.scaleXChaneable.toValue = v + } + + get toScaleX() { + return this.scaleXChaneable.toValue + } + set fromScaleY(v: number) { + this.scaleYChangeable.fromValue = v + } + + get fromScaleY() { + return this.scaleYChangeable.fromValue + } + + set toScaleY(v: number) { + this.scaleYChangeable.toValue = v + } + + get toScaleY() { + return this.scaleYChangeable.toValue + } +} + +export class TranslationAnimation extends Animation { + private translationXChangeable: Changeable = { + key: "translationX", + fromValue: 1, + toValue: 1, + } + private translationYChangeable: Changeable = { + key: "translationY", + fromValue: 1, + toValue: 1, + } + constructor() { + super() + this.changeables.set("translationX", this.translationXChangeable) + this.changeables.set("translationY", this.translationYChangeable) + } + + set fromTranslationX(v: number) { + this.translationXChangeable.fromValue = v + } + + get fromTranslationX() { + return this.translationXChangeable.fromValue + } + + set toTranslationX(v: number) { + this.translationXChangeable.toValue = v + } + + get toTranslationX() { + return this.translationXChangeable.toValue + } + set fromTranslationY(v: number) { + this.translationYChangeable.fromValue = v + } + + get fromTranslationY() { + return this.translationYChangeable.fromValue + } + + set toTranslationY(v: number) { + this.translationYChangeable.toValue = v + } + + get toTranslationY() { + return this.translationYChangeable.toValue + } +} + +export class RotationAnimation extends Animation { + private rotationChaneable: Changeable = { + key: "rotation", + fromValue: 1, + toValue: 1, + } + constructor() { + super() + this.changeables.set("rotation", this.rotationChaneable) + } + + set fromRotation(v: number) { + this.rotationChaneable.fromValue = v + } + + get fromRotation() { + return this.rotationChaneable.fromValue + } + + set toRotation(v: number) { + this.rotationChaneable.toValue = v + } + + get toRotation() { + return this.rotationChaneable.toValue + } +} + +export class AnimaionSet implements IAnimation { + animations: IAnimation[] = [] + _duration = 0 + + repeatCount?: number + repeatMode?: RepeatMode + delay?: number + + get duration() { + return this._duration + } + + set duration(v: number) { + this._duration = v + this.animations.forEach(e => e.duration = v) + } + + toModel() { + return this.animations.map(e => { + return e.toModel() + }) as Model + } +} \ No newline at end of file diff --git a/js-framework/src/ui/view.ts b/js-framework/src/ui/view.ts index f943641c..bc399242 100644 --- a/js-framework/src/ui/view.ts +++ b/js-framework/src/ui/view.ts @@ -19,6 +19,7 @@ import { uniqueId } from "../util/uniqueId"; import { loge } from "../util/log"; import { BridgeContext } from "../runtime/global"; import { LayoutConfig } from '../util/layoutconfig' +import { IAnimation } from "./animation"; export function Property(target: Object, propKey: string) { Reflect.defineMetadata(propKey, true, target) @@ -333,6 +334,10 @@ export abstract class View implements Modeling, IView { @Property rotation?: number /**----------transform----------*/ + + doAnimation(context: BridgeContext, animation: IAnimation) { + return this.nativeChannel(context, "doAnimation")(animation) + } } export abstract class Superview extends View {