Commit 0eded96c authored by wjf's avatar wjf

k

parent e4815058
import { removeTweens } from "../module/ctrls";
import { RES } from "../module/RES";
interface LottieData {
"fr": number,//珍露 30 60等
"ip": number,//开始帧
"op": number,//结束帧
"w": number,//宽度
"h": number,//高度
"nm": string,//名字
"layers": LayerData[]
}
interface LayerData {
"ind": number,//id唯一
"ty": number,//类型,暂时只有2
"nm": "owl_sleep.png",//暂时就是图片
"refId": string,
"parent"?: number,//父级id
"ks": KsData;
"ip": number,//开始帧
"op": number,//结束帧
}
interface KsData {
o: KeyData
r: KeyData
p: KeyData
a: KeyData
s: KeyData
}
interface KeyData {
a: number, k: { "t": number, "s": number[] }[] | number[] | number, x: string
}
/**
* 每帧数据
*/
interface FrameData {
a: number,
r: number,
ax: number,
ay: number,
x: number,
y: number,
sx: number,
sy: number,
v: boolean,
}
/**
* 用Tween拼,后续计算帧数据记录
* 临时写的,乱得很,以后再说
*/
export class Lottie extends FYGE.Container {
rawData: LottieData;
totalTime: number;
totalFrames: number;
/**
* 锁步的时间间隔,按fps定,毫秒
*/
private timeInterval;
/**
* 按帧率计算,60为1,30为2,
*/
private deltaFrame: number = 1;
get videoWidth(): number {
return this.rawData && this.rawData.w;
};
get videoHeight(): number {
return this.rawData && this.rawData.h;
};
/**
* 供循环用
*/
private loops: number
private callback: () => void
// private
constructor(data) {
super()
this._instanceType = "MovieClip";
//初始化
if (data) {
this.init(data);
} else {
this.totalFrames = 0;
}
}
init(data: LottieData) {
if (!data) return
this.rawData = data;
this.timeInterval = 1000 / data.fr;
this.totalFrames = data.op - data.ip + 1//感觉得加1;
//间隔帧数,
this.deltaFrame = 60 / data.fr;
this.name = data.nm;
this.initChildren();
}
private initChildren() {
const hash = {};
//初始化内容吧,假设所有资源已经加载好额
var layers = this.rawData.layers.slice();
//先筛选出所有不带parents,说明是顶级容器
for (var i = layers.length - 1; i >= 0; i--) {
let layer = layers[i];
if (!layer.parent) {
let c = this.addChild(new FYGE.Container())
c.addChild(new FYGE.Sprite(RES.getRes(layer.nm) || RES.getRes(layer.refId + ".png")));
c.name = layer.nm;
//记录一下数据
c["layerData"] = layer;
//计入hash
hash[layer.ind] = c;
//从数组移除
layers.splice(i, 1);
}
}
//剩下就找爹了
while (layers.length) {
for (var j = layers.length - 1; j >= 0; j--) {
let layer = layers[j];
if (hash[layer.parent]) {
let c = hash[layer.parent].addChild(FYGE.Sprite.fromFrame(layer.nm));
c.name = layer.nm;
//记录一下数据
c["layerData"] = layer;
//计入hash
hash[layer.ind] = c;
//从数组移除
layers.splice(j, 1);
}
}
}
this.initState()
}
/**
* 初始化每个对象的帧数据
*/
private initFrameData(dis: FYGE.DisplayObject, layerData: LayerData) {
var frames: FrameData[] = this.createEmptyFrames();
//@ts-ignore 透明度,有动画的
if (layerData.ks.o.k.length) {
}
//无动画的
else {
//@ts-ignore
this.coverProp(frames, { alpha: layerData.ks.o.k / 100 })
}
// c.alpha = layerData.ks.o.k[0] ? layerData.ks.o.k[0].s[0] : layerData.ks.o.k / 100;
// ["o", "r", "a", "p", "s"].forEach((e) => {
// let data: = layerData.ks[e].k;
// if (e == "o") {
// }
// })
// for (var i = 0; i < layerData.ks.) { }
}
private addFrames() {
}
private createEmptyFrames() {
var frames: FrameData[] = []
var count = 0;
while (count++ < this.totalFrames) {
//@ts-ignore
frames.push({
a: 1,
r: 0,
ax: 0,
ay: 0,
x: 0,
y: 0,
sx: 1,
sy: 1,
v: true,
})
}
return frames
}
private coverProp(frames: FrameData[], obj) {
//@ts-ignore
frames.forEach((f) => { Object.assign(f, obj) })
}
private updateFrame() {
}
update() {
this.updateFrame();
super.update()
}
private initState(con = this.children) {
for (var i = 0; i < con.length; i++) {
var c: FYGE.Sprite = con[i];
if (c["layerData"]) {
//取第一个数据
let data: LayerData = c["layerData"];
//@ts-ignore 透明度
c.alpha = data.ks.o.k[0] ? data.ks.o.k[0].s[0] : data.ks.o.k / 100;
//@ts-ignore 选转
c.rotation = data.ks.r.k[0] ? data.ks.r.k[0].s[0] : data.ks.r.k / 100;
//锚点,用贴图锚点
var ad = typeof data.ks.a.k[0] == "number" ? data.ks.a.k : data.ks.a.k[0].s;
c.anchor.set(ad[0], ad[1])
//位置
var ad = typeof data.ks.p.k[0] == "number" ? data.ks.p.k : data.ks.p.k[0].s;
c.position.set(ad[0] - c.anchorX, ad[1] - c.anchorY)
//缩放
var ad = typeof data.ks.s.k[0] == "number" ? data.ks.s.k : data.ks.s.k[0].s;
c.scale.set(ad[0] / 100, ad[1] / 100)
//如果入场不在的
if (data.ip != 0) c.visible = false
}
if (c.children.length) this.initState(c.children)
}
}
/**
* 只有一次或无数次
*/
play(loop: number = 1, callback?: () => void) {
this.initState();
this.loops = loop;
this.callback = callback;
this.addTweens();
}
/**
* 移除所有的Tween
*/
stop() {
removeTweens(this);
this.initState();
}
private addTweens(con = this.children) {
for (var i = 0; i < con.length; i++) {
let c: FYGE.Sprite = con[i];
if (c["layerData"]) {
//取第一个数据
let data: LayerData = c["layerData"];
//@ts-ignore 透明度,如果k是数组,肯定有帧数据
if (data.ks.o.k.length) this.addTween(c, "o");
//@ts-ignore 旋转
if (data.ks.r.k.length) this.addTween(c, "r");
//位置,得是对象
if (typeof data.ks.p.k[0] != "number") this.addTween(c, "p");
//缩放
if (typeof data.ks.s.k[0] != "number") this.addTween(c, "s");
}
if (c.children.length) this.addTweens(c.children)
}
}
private addTween(dis: FYGE.DisplayObject, type: "r" | "o" | "s" | "p") {
const data: { "t": number, "s": number[] }[] = dis["layerData"].ks[type].k
let tween = FYGE.Tween.get(dis, { loop: true })
let countTime = 0;
//记录用过的obj
var objArr: { obj: any, deltaTime: number }[] = []
for (let i = 0; i < data.length; i++) {
let d = data[i];
let deltaTime = d.t * this.timeInterval - countTime;
countTime += deltaTime;
let obj;
switch (type) {
case "r":
obj = { rotation: d.s[0] }
break;
case "o":
obj = { alpha: d.s[0] }
break;
case "s":
obj = { scaleX: d.s[0] / 100, scaleY: d.s[1] / 100 }
break;
case "p":
obj = { x: d.s[0] - dis.anchorX, y: d.s[1] - dis.anchorY }
break;
}
//第一个不是0,加wait
if (i == 0 && d.t != 0) {
tween.wait(deltaTime)
.call(() => { dis.visible = true })
continue
} else if (i == 0 && d.t == 0) {//从0开始的,不进行缓动,但是要记录状态
objArr.push({ obj, deltaTime })
continue
}
tween.to(obj, deltaTime);
objArr.push({ obj, deltaTime })
}
if (dis["layerData"].ks[type].x) {
var xs = dis["layerData"].ks[type].x;
if (xs.indexOf("loopOut") >= 0) {
//如果是往复的,
if (xs.indexOf("pingpong") >= 0 && data[data.length - 1].t < this.rawData.op) {
var round = Math.round(this.rawData.op / data[data.length - 1].t)
var dir = false;
while (--round) {
if (dir) {
for (var o = 0; o < objArr.length; o++) {
tween.to(objArr[o].obj, objArr[o].deltaTime);
}
} else {
for (var o = objArr.length - 1; o >= 1; o--) {
tween.to(objArr[o - 1].obj, objArr[o].deltaTime);
}
}
dir = !dir;
}
}
//如果是循环的,且没满一个循环的
else if (xs.indexOf("cycle") >= 0 && data[data.length - 1].t < this.rawData.op) {
//补满
for (var o = 0; o < objArr.length; o++) {
tween.to(objArr[o].obj, objArr[o].deltaTime);
}
}
}
}
//入场不是0
if (dis["layerData"].ip != 0) {
tween.call(() => {
dis.visible = false;
})
}
//不管x的
if (!dis["layerData"].ks[type].x) {
if (data[data.length - 1].t < this.rawData.op) {
tween.wait(this.rawData.op * this.timeInterval - countTime)
}
}
tween.call(() => {
if (--this.loops == 0) {
this.stop();
this.callback && this.callback();
}
})
}
destroy() {
removeTweens(this);
super.destroy();
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment