feat:define animation

This commit is contained in:
pengfei.zhou 2019-11-30 16:14:22 +08:00
parent 007898329f
commit 85a8e0fdaf
2 changed files with 187 additions and 143 deletions

View File

@ -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<Node> = new Set
siblings: Set<Node> = new Set
parents: Set<Node> = new Set
animation: Animation
built = false
constructor(anim: Animation) {
this.animation = anim
}
abstract class Animation implements IAnimation {
changeables: Map<AnimatedKey, Changeable> = 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<Animation, Node> = 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<Node>) {
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
}
}

View File

@ -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 {