Commit a7cc2d40 authored by wjf's avatar wjf

l

parent 01a093d8
...@@ -533,6 +533,9 @@ var Container = (function (_super) { ...@@ -533,6 +533,9 @@ var Container = (function (_super) {
children.forEach(function (child) { _this.removeChild(child); }); children.forEach(function (child) { _this.removeChild(child); });
return children; return children;
}; };
Container.prototype.removeAllChildren = function () {
return this.removeChildren();
};
Container.prototype.removeChildrenAt = function (beginIndex, endIndex) { Container.prototype.removeChildrenAt = function (beginIndex, endIndex) {
if (beginIndex === void 0) { beginIndex = 0; } if (beginIndex === void 0) { beginIndex = 0; }
if (endIndex === void 0) { endIndex = this.children.length; } if (endIndex === void 0) { endIndex = this.children.length; }
...@@ -1548,6 +1551,7 @@ var DisplayObject_1 = __webpack_require__(/*! ./DisplayObject */ "./src/2d/displ ...@@ -1548,6 +1551,7 @@ var DisplayObject_1 = __webpack_require__(/*! ./DisplayObject */ "./src/2d/displ
var MouseEvent_1 = __webpack_require__(/*! ../events/MouseEvent */ "./src/2d/events/MouseEvent.ts"); var MouseEvent_1 = __webpack_require__(/*! ../events/MouseEvent */ "./src/2d/events/MouseEvent.ts");
var WebglRenderer_1 = __webpack_require__(/*! ../renderers/WebglRenderer */ "./src/2d/renderers/WebglRenderer.ts"); var WebglRenderer_1 = __webpack_require__(/*! ../renderers/WebglRenderer */ "./src/2d/renderers/WebglRenderer.ts");
var CanvasRenderer_1 = __webpack_require__(/*! ../renderers/CanvasRenderer */ "./src/2d/renderers/CanvasRenderer.ts"); var CanvasRenderer_1 = __webpack_require__(/*! ../renderers/CanvasRenderer */ "./src/2d/renderers/CanvasRenderer.ts");
var utils_1 = __webpack_require__(/*! ../utils */ "./src/2d/utils/index.ts");
var Stage = (function (_super) { var Stage = (function (_super) {
__extends(Stage, _super); __extends(Stage, _super);
function Stage(canvas, desWidth, desHeight, divWidth, divHeight, renderType) { function Stage(canvas, desWidth, desHeight, divWidth, divHeight, renderType) {
...@@ -1563,6 +1567,8 @@ var Stage = (function (_super) { ...@@ -1563,6 +1567,8 @@ var Stage = (function (_super) {
_this.divWidth = 0; _this.divWidth = 0;
_this._bgColor = 0x000000; _this._bgColor = 0x000000;
_this._lastDpList = {}; _this._lastDpList = {};
_this._canvasOffsetX = 0;
_this._canvasOffsetY = 0;
_this._ml = []; _this._ml = [];
_this._mp = []; _this._mp = [];
_this._mouseDownPoint = {}; _this._mouseDownPoint = {};
...@@ -1574,6 +1580,7 @@ var Stage = (function (_super) { ...@@ -1574,6 +1580,7 @@ var Stage = (function (_super) {
touchMove: "onMouseMove", touchMove: "onMouseMove",
touchEnd: "onMouseUp" touchEnd: "onMouseUp"
}; };
_this.canvas = canvas;
var s = _this; var s = _this;
_this._instanceType = "Stage"; _this._instanceType = "Stage";
Stage._stageList["canvas"] = s; Stage._stageList["canvas"] = s;
...@@ -1583,6 +1590,12 @@ var Stage = (function (_super) { ...@@ -1583,6 +1590,12 @@ var Stage = (function (_super) {
s.desHeight = desHeight || 1206; s.desHeight = desHeight || 1206;
s.divWidth = divWidth; s.divWidth = divWidth;
s.divHeight = divHeight; s.divHeight = divHeight;
if (utils_1.getEnv() == "tb")
my.createSelectorQuery().select('#canvas').boundingClientRect().exec(function (r) {
s._canvasOffsetX = r[0].left;
s._canvasOffsetY = r[0].top;
});
console.log("%c版本:" + const_1.VERSION);
if (renderType == const_1.RENDERER_TYPE.CANVAS) { if (renderType == const_1.RENDERER_TYPE.CANVAS) {
var context = canvas.getContext("2d"); var context = canvas.getContext("2d");
s.renderObj = new CanvasRenderer_1.CanvasRenderer(context, canvas.width, canvas.height); s.renderObj = new CanvasRenderer_1.CanvasRenderer(context, canvas.width, canvas.height);
...@@ -1643,7 +1656,7 @@ var Stage = (function (_super) { ...@@ -1643,7 +1656,7 @@ var Stage = (function (_super) {
this.renderObj.render(this); this.renderObj.render(this);
}; };
Stage.prototype.onMouseEvent = function (e) { Stage.prototype.onMouseEvent = function (e) {
if (!my) if (utils_1.getEnv() == "web")
e.preventDefault(); e.preventDefault();
var s = this; var s = this;
if (EventDispatcher_1.EventDispatcher._totalMEC > 0) { if (EventDispatcher_1.EventDispatcher._totalMEC > 0) {
...@@ -1657,6 +1670,13 @@ var Stage = (function (_super) { ...@@ -1657,6 +1670,13 @@ var Stage = (function (_super) {
var eLen = void 0; var eLen = void 0;
var identifier = void 0; var identifier = void 0;
points = [e.changedTouches[0]]; points = [e.changedTouches[0]];
var offSetX = s._canvasOffsetX, offSetY = s._canvasOffsetY;
if (utils_1.getEnv() == "web") {
var doc = document.documentElement;
var box = s.canvas.getBoundingClientRect();
offSetX = box.left + window.pageXOffset - doc.clientLeft;
offSetY = box.top + window.pageYOffset - doc.clientTop;
}
for (var o = 0; o < points.length; o++) { for (var o = 0; o < points.length; o++) {
if (!points[o]) if (!points[o])
continue; continue;
...@@ -1669,8 +1689,8 @@ var Stage = (function (_super) { ...@@ -1669,8 +1689,8 @@ var Stage = (function (_super) {
else { else {
cp = new math_1.Point(); cp = new math_1.Point();
} }
cp.x = (points[o].pageX || points[o].x || points[o].b) * s.dpi; cp.x = ((points[o].pageX || points[o].x || points[o].b) - offSetX) * s.dpi;
cp.y = (points[o].pageY || points[o].y || points[o].c) * s.dpi; cp.y = ((points[o].pageY || points[o].y || points[o].c) - offSetY) * s.dpi;
sp = s.globalToLocal(cp, DisplayObject_1.DisplayObject._bp); sp = s.globalToLocal(cp, DisplayObject_1.DisplayObject._bp);
if (EventDispatcher_1.EventDispatcher.getMouseEventCount() > 0) { if (EventDispatcher_1.EventDispatcher.getMouseEventCount() > 0) {
if (!s._ml[eLen]) { if (!s._ml[eLen]) {
...@@ -4521,6 +4541,7 @@ var Graphics = (function (_super) { ...@@ -4521,6 +4541,7 @@ var Graphics = (function (_super) {
} }
}; };
Graphics.prototype._renderCanvas = function (renderer) { Graphics.prototype._renderCanvas = function (renderer) {
this.finishPoly();
if (this.cacheAsBitmap) { if (this.cacheAsBitmap) {
if (this.cacheDirty != this.dirty) { if (this.cacheDirty != this.dirty) {
this.cacheDirty = this.dirty; this.cacheDirty = this.dirty;
...@@ -4529,10 +4550,13 @@ var Graphics = (function (_super) { ...@@ -4529,10 +4550,13 @@ var Graphics = (function (_super) {
this.cacheAsBitmap = false; this.cacheAsBitmap = false;
var tempAlpha = this.alpha; var tempAlpha = this.alpha;
this.alpha = 1; this.alpha = 1;
var tempChildren = this.children;
this.children = [];
this.generateCanvasTexture(); this.generateCanvasTexture();
this.mask = tempMask; this.mask = tempMask;
this.alpha = tempAlpha; this.alpha = tempAlpha;
this.cacheAsBitmap = true; this.cacheAsBitmap = true;
this.children = tempChildren;
this.updateTransform(); this.updateTransform();
} }
renderer.plugins.sprite.render(this); renderer.plugins.sprite.render(this);
...@@ -6875,7 +6899,7 @@ var Loader = (function (_super) { ...@@ -6875,7 +6899,7 @@ var Loader = (function (_super) {
}, url); }, url);
}; };
Loader.prototype.loadJson = function (callback, url) { Loader.prototype.loadJson = function (callback, url) {
if (my) { if (utils_1.getEnv() == "tb") {
this.tbLoad(callback, url, "utf8"); this.tbLoad(callback, url, "utf8");
return; return;
} }
...@@ -7730,10 +7754,10 @@ var Rectangle = (function (_super) { ...@@ -7730,10 +7754,10 @@ var Rectangle = (function (_super) {
hy1 = y + h; hy1 = y + h;
wx2 = arg[i].x + arg[i].width; wx2 = arg[i].x + arg[i].width;
hy2 = arg[i].y + arg[i].height; hy2 = arg[i].y + arg[i].height;
if (x > arg[i].x || wx1 == 0) { if (x > arg[i].x) {
x = arg[i].x; x = arg[i].x;
} }
if (y > arg[i].y || hy1 == 0) { if (y > arg[i].y) {
y = arg[i].y; y = arg[i].y;
} }
if (wx1 < wx2) { if (wx1 < wx2) {
...@@ -9052,6 +9076,7 @@ var CanvasMaskManager = (function (_super) { ...@@ -9052,6 +9076,7 @@ var CanvasMaskManager = (function (_super) {
maskData["_drawShape"](renderer.context); maskData["_drawShape"](renderer.context);
} }
else { else {
maskData["finishPoly"]();
this.renderGraphicsShape(maskData); this.renderGraphicsShape(maskData);
} }
renderer.context.clip(); renderer.context.clip();
...@@ -9514,6 +9539,8 @@ var MaskManager = (function () { ...@@ -9514,6 +9539,8 @@ var MaskManager = (function () {
alphaMaskFilter[0].resolution = 1; alphaMaskFilter[0].resolution = 1;
alphaMaskFilter[0].maskSprite = maskData; alphaMaskFilter[0].maskSprite = maskData;
var cacheFilterArea = target.filterArea; var cacheFilterArea = target.filterArea;
if (maskData.instanceType == "Shape")
maskData.updateShape();
target.filterArea = maskData.getBounds(true); target.filterArea = maskData.getBounds(true);
this.renderer.filterManager.pushFilter(target, alphaMaskFilter); this.renderer.filterManager.pushFilter(target, alphaMaskFilter);
target.filterArea = cacheFilterArea; target.filterArea = cacheFilterArea;
...@@ -11581,7 +11608,8 @@ var TextField = (function (_super) { ...@@ -11581,7 +11608,8 @@ var TextField = (function (_super) {
configurable: true configurable: true
}); });
TextField.prototype._getMeasuredWidth = function (text) { TextField.prototype._getMeasuredWidth = function (text) {
var ctx = this.context; if (utils_1.getEnv() == "web")
return this.context.measureText(text).width;
var patternCh = new RegExp("[\u4E00-\u9FA5]+"); var patternCh = new RegExp("[\u4E00-\u9FA5]+");
var patternChB = /[\u3002|\uff1f|\uff01|\uff0c|\u3001|\uff1b|\uff1a|\u201c|\u201d|\u2018|\u2019|\uff08|\uff09|\u300a|\u300b|\u3008|\u3009|\u3010|\u3011|\u300e|\u300f|\u300c|\u300d|\ufe43|\ufe44|\u3014|\u3015|\u2026|\u2014|\uff5e|\ufe4f|\uffe5]/; var patternChB = /[\u3002|\uff1f|\uff01|\uff0c|\u3001|\uff1b|\uff1a|\u201c|\u201d|\u2018|\u2019|\uff08|\uff09|\u300a|\u300b|\u3008|\u3009|\u3010|\u3011|\u300e|\u300f|\u300c|\u300d|\ufe43|\ufe44|\u3014|\u3015|\u2026|\u2014|\uff5e|\ufe4f|\uffe5]/;
var patternEn = new RegExp("[A-Za-z]+"); var patternEn = new RegExp("[A-Za-z]+");
...@@ -12532,7 +12560,7 @@ function createTextureSheet(baseTexture, altaData) { ...@@ -12532,7 +12560,7 @@ function createTextureSheet(baseTexture, altaData) {
else { else {
frame = new math_1.Rectangle(Math.floor(data.x), Math.floor(data.y), Math.floor(data.w), Math.floor(data.h)); frame = new math_1.Rectangle(Math.floor(data.x), Math.floor(data.y), Math.floor(data.w), Math.floor(data.h));
} }
if (data.ox || data.oy) { if (data.ox || data.oy || data.w != data.sw || data.h != data.sh) {
trim = new math_1.Rectangle(Math.floor(data.ox), Math.floor(data.oy), Math.floor(data.w), Math.floor(data.h)); trim = new math_1.Rectangle(Math.floor(data.ox), Math.floor(data.oy), Math.floor(data.w), Math.floor(data.h));
} }
var texture = new Texture_1.default(baseTexture, frame, orig, trim, data.ro ? 2 : 0); var texture = new Texture_1.default(baseTexture, frame, orig, trim, data.ro ? 2 : 0);
...@@ -12849,6 +12877,9 @@ var utils_1 = __webpack_require__(/*! ../utils */ "./src/2d/utils/index.ts"); ...@@ -12849,6 +12877,9 @@ var utils_1 = __webpack_require__(/*! ../utils */ "./src/2d/utils/index.ts");
var tween_1 = __webpack_require__(/*! ../../tween */ "./src/tween/index.ts"); var tween_1 = __webpack_require__(/*! ../../tween */ "./src/tween/index.ts");
var texture_1 = __webpack_require__(/*! ../texture */ "./src/2d/texture/index.ts"); var texture_1 = __webpack_require__(/*! ../texture */ "./src/2d/texture/index.ts");
var display_1 = __webpack_require__(/*! ../display */ "./src/2d/display/index.ts"); var display_1 = __webpack_require__(/*! ../display */ "./src/2d/display/index.ts");
var BezierEaser_1 = __webpack_require__(/*! ./forLottie/BezierEaser */ "./src/2d/ui/forLottie/BezierEaser.ts");
var buildBezierProps_1 = __webpack_require__(/*! ./forLottie/buildBezierProps */ "./src/2d/ui/forLottie/buildBezierProps.ts");
var buildBezierEaserProps_1 = __webpack_require__(/*! ./forLottie/buildBezierEaserProps */ "./src/2d/ui/forLottie/buildBezierEaserProps.ts");
var Lottie = (function (_super) { var Lottie = (function (_super) {
__extends(Lottie, _super); __extends(Lottie, _super);
function Lottie(data) { function Lottie(data) {
...@@ -12862,7 +12893,7 @@ var Lottie = (function (_super) { ...@@ -12862,7 +12893,7 @@ var Lottie = (function (_super) {
} }
Object.defineProperty(Lottie.prototype, "totalFrames", { Object.defineProperty(Lottie.prototype, "totalFrames", {
get: function () { get: function () {
return this.rawData && (this.rawData.op - this.rawData.ip); return this.rawData && (this.rawData.op - this.rawData.ip) || 0;
}, },
enumerable: true, enumerable: true,
configurable: true configurable: true
...@@ -12936,14 +12967,16 @@ var Lottie = (function (_super) { ...@@ -12936,14 +12967,16 @@ var Lottie = (function (_super) {
}; };
Lottie.prototype.play = function (loop, callback) { Lottie.prototype.play = function (loop, callback) {
if (loop === void 0) { loop = 0; } if (loop === void 0) { loop = 0; }
this.stop(); this.stop(true);
this.loops = loop; this.loops = loop;
this.callback = callback; this.callback = callback;
this.addTweens(); this.addTweens();
}; };
Lottie.prototype.stop = function () { Lottie.prototype.stop = function (isReset) {
if (isReset === void 0) { isReset = false; }
tween_1.Tween.removeTweens(this);
this.children.forEach(function (c) { tween_1.Tween.removeTweens(c); }); this.children.forEach(function (c) { tween_1.Tween.removeTweens(c); });
this.initState(); isReset && this.initState();
}; };
Lottie.prototype.addTweens = function (con) { Lottie.prototype.addTweens = function (con) {
var _this = this; var _this = this;
...@@ -13383,6 +13416,301 @@ function getLoopInPingpongTween(objArr, round, op) { ...@@ -13383,6 +13416,301 @@ function getLoopInPingpongTween(objArr, round, op) {
} }
return tweenArr; return tweenArr;
} }
var totalOp = 0;
var lottieData;
function handleLottieData(data) {
if (data.svgaData)
return data.svgaData;
totalOp = data.op;
lottieData = data;
var videoEntity = {};
videoEntity.videoSize = {
width: data.w,
height: data.h
};
videoEntity.FPS = data.fr;
videoEntity.frames = data.op - data.ip;
if (data.assets) {
videoEntity.images = {};
data.assets.forEach(function (a) {
videoEntity.images[a.id] = a.p.replace("data:image/png;base64,", "");
});
}
for (var i = 0; i < data.layers.length; i++) {
var layerData = data.layers[i];
var ks = layerData.ks;
var ad = typeof layerData.ks.a.k[0] == "number" ? layerData.ks.a.k : layerData.ks.a.k[0].s;
ks.a.props = fillUp(ad);
addFrames(layerData);
}
data.layers.forEach(function (l) {
l.transformDatas = fillUp({
alpha: 0,
});
});
for (var i = 0; i < totalOp; i++) {
data.layers.forEach(function (l) {
var ks = l.ks;
var ip = l.ip;
var op = l.op;
if (i >= ip && i <= op) {
l.transformDatas[i].alpha = ks.o.props[i][0];
}
recursiveUpdateTransform(l, i);
});
}
videoEntity.sprites = [];
for (var i = 0; i < data.layers.length; i++) {
var layerData = data.layers[i];
if (layerData.refId)
videoEntity.sprites.push({
imageKey: layerData.refId,
frames: layerData.transformDatas
});
}
videoEntity.sprites.reverse();
return lottieData.svgaData = videoEntity;
}
exports.handleLottieData = handleLottieData;
function addFrames(layerData) {
var ks = layerData.ks;
var ip = layerData.ip;
var op = layerData.op;
if (ks.o.k.length) {
addFrame(layerData, "o");
}
else {
var alpha = ks.o.k / 100;
ks.o.props = fillUp([alpha]);
}
if (ks.r.k.length) {
addFrame(layerData, "r");
}
else {
ks.r.props = fillUp([ks.r.k]);
}
if (typeof ks.p.k[0] != "number") {
addFrame(layerData, "p");
}
else {
var anchor = typeof ks.a.k[0] == "number" ? ks.a.k : ks.a.k[0].s;
var p = ks.p.k;
ks.p.props = fillUp([p[0] - anchor[0], p[1] - anchor[1]]);
}
if (typeof ks.s.k[0] != "number") {
addFrame(layerData, "s");
}
else {
var s = ks.s.k;
ks.s.props = fillUp([s[0] / 100, s[1] / 100]);
}
}
function addFrame(layerData, type) {
var data = layerData.ks[type].k;
var ip = layerData.ip;
var op = layerData.op;
var ks = layerData.ks;
var anchor = typeof ks.a.k[0] == "number" ? ks.a.k : ks.a.k[0].s;
var frames = [];
var props = ks[type].props = [];
props.length = totalOp + 1;
for (var i_1 = 0; i_1 < data.length; i_1++) {
var d = data[i_1];
var value = void 0;
switch (type) {
case "r":
value = [d.s[0]];
break;
case "o":
value = [d.s[0] / 100];
break;
case "s":
value = [d.s[0] / 100, d.s[1] / 100, 0];
break;
case "p":
value = [d.s[0] - anchor[0], d.s[1] - anchor[1], 0];
break;
}
frames.push({
i: d.i, o: d.o, ti: d.ti, to: d.to,
h: d.h === 1,
value: value,
frame: d.t
});
}
for (var i = 0; i < frames.length - 1; i++) {
var f = frames[i], nextF = frames[i + 1];
if (f.to) {
var fnc = BezierEaser_1.getBezierEasing(f.o.x, f.o.y, f.i.x, f.i.y).get;
buildBezierProps_1.buildBezierProps(f.value, nextF.value, f.to, f.ti, f.frame, nextF.frame, props, fnc, ks[type].x ? undefined : totalOp);
}
else {
buildBezierEaserProps_1.buildBezierEaserProps(f.value, nextF.value, f.o, f.i, f.frame, nextF.frame, props, f.h, ks[type].x ? undefined : totalOp);
}
}
if (frames[frames.length - 1].h) {
props[frames[frames.length - 1].frame] = frames[frames.length - 1].value.slice();
}
if (ks[type].x && (ks[type].x.indexOf("loopOut") >= 0 || ks[type].x.indexOf("loopIn") >= 0)) {
var xs = ks[type].x;
var loopOut = xs.indexOf("loopOut") >= 0;
var loopIn = xs.indexOf("loopIn") >= 0;
var rr = +xs.replace(/[^0-9]/ig, "");
if (rr > frames.length - 1)
rr = 0;
var propsClone = props.slice();
var isCycle = xs.indexOf("cycle") >= 0;
var isPingpong = xs.indexOf("pingpong") >= 0;
var dir = false;
var lastIndex = frames.length - 1;
var startIndex = 0;
var count = loopOut ? frames[lastIndex].frame :
frames[0].frame;
var stepOffset = loopOut ? frames[lastIndex - (rr || lastIndex)].frame :
frames[0].frame;
var stepAll = loopOut ? frames[lastIndex].frame - stepOffset :
frames[0 + (rr || lastIndex)].frame - stepOffset;
while (loopOut ?
(count <= totalOp) :
(count >= 0)) {
if (isPingpong) {
if (dir) {
funLoop(function (index) {
if (loopOut) {
props[++count] = propsClone[index + 1 + stepOffset].slice();
}
else {
props[--count] = propsClone[stepAll - 1 - index + stepOffset].slice();
}
}, stepAll);
}
else {
funLoop(function (index) {
if (loopOut) {
props[++count] = propsClone[stepAll - 1 - index + stepOffset].slice();
}
else {
props[--count] = propsClone[index + 1 + stepOffset].slice();
}
}, stepAll);
}
dir = !dir;
}
else if (isCycle) {
funLoop(function (index) {
if (loopOut) {
props[++count] = propsClone[index + 1 + stepOffset].slice();
}
else {
props[--count] = propsClone[stepAll - 1 - index + stepOffset].slice();
}
}, stepAll);
}
else {
break;
}
}
}
var arr = returnEmpty(props);
if (arr[0] !== null) {
var countFront = arr[0];
var startValue = props[countFront];
while (countFront--) {
props[countFront] = startValue.slice();
}
}
if (arr[1] !== null) {
var countAfter = arr[1];
var endValue = props[countAfter];
while (countAfter++ <= totalOp) {
props[countAfter] = endValue.slice();
}
}
}
function findLayerByInd(ind) {
for (var i = 0; i < lottieData.layers.length; i++) {
if (lottieData.layers[i].ind === ind)
return lottieData.layers[i];
}
}
function recursiveUpdateTransform(l, index) {
if (l.parent !== undefined) {
var p = findLayerByInd(l.parent);
recursiveUpdateTransform(p, index);
if (!l.transformDatas[index].transform) {
var lt = l.transformDatas[index];
lt.transform = createWorldMatrix(createLocalMatrix(l, index), p.transformDatas[index].transform);
}
}
else if (!l.transformDatas[index].transform) {
var lt = l.transformDatas[index];
lt.transform = createLocalMatrix(l, index);
}
}
function createLocalMatrix(l, index) {
var ks = l.ks;
var x = 0, y = 0, scaleX = 1, scaleY = 1, rotation = 0;
var anchorX = ks.a.props[0][0], anchorY = ks.a.props[0][1];
if (ks.p.props[index]) {
x = ks.p.props[index][0];
y = ks.p.props[index][1];
}
if (ks.s.props[index]) {
scaleX = ks.s.props[index][0];
scaleY = ks.s.props[index][1];
}
if (ks.r.props[index]) {
rotation = ks.r.props[index][0];
}
var lt = {};
rotation *= Math.PI / 180;
lt.a = Math.cos(rotation) * scaleX;
lt.b = Math.sin(rotation) * scaleX;
lt.c = -Math.sin(rotation) * scaleY;
lt.d = Math.cos(rotation) * scaleY;
lt.tx = x + anchorX - ((anchorX * lt.a) + (anchorY * lt.c));
lt.ty = y + anchorY - ((anchorX * lt.b) + (anchorY * lt.d));
return lt;
}
function createWorldMatrix(lt, pt) {
return {
a: (lt.a * pt.a) + (lt.b * pt.c),
b: (lt.a * pt.b) + (lt.b * pt.d),
c: (lt.c * pt.a) + (lt.d * pt.c),
d: (lt.c * pt.b) + (lt.d * pt.d),
tx: (lt.tx * pt.a) + (lt.ty * pt.c) + pt.tx,
ty: (lt.tx * pt.b) + (lt.ty * pt.d) + pt.ty,
};
}
function returnEmpty(arr) {
var front = null, after = null;
var last = !!arr[0];
for (var i = 1; i < arr.length; i++) {
if (!last) {
if (arr[i] !== undefined) {
front = i;
}
}
else {
if (arr[i] === undefined) {
after = i - 1;
break;
}
}
last = !!arr[i];
}
return [front, after];
}
function funLoop(fun, times) {
if (times <= 0)
return;
var count = times;
while (count--)
fun(times - count - 1);
}
function fillUp(value) {
return Array.apply(void 0, Array(totalOp)).map(function (a, i) { return JSON.parse(JSON.stringify(value)); });
}
/***/ }), /***/ }),
...@@ -13412,8 +13740,8 @@ var Texture_1 = __webpack_require__(/*! ../texture/Texture */ "./src/2d/texture/ ...@@ -13412,8 +13740,8 @@ var Texture_1 = __webpack_require__(/*! ../texture/Texture */ "./src/2d/texture/
var Sprite_1 = __webpack_require__(/*! ../display/Sprite */ "./src/2d/display/Sprite.ts"); var Sprite_1 = __webpack_require__(/*! ../display/Sprite */ "./src/2d/display/Sprite.ts");
var Event_1 = __webpack_require__(/*! ../events/Event */ "./src/2d/events/Event.ts"); var Event_1 = __webpack_require__(/*! ../events/Event */ "./src/2d/events/Event.ts");
var utils_1 = __webpack_require__(/*! ../utils */ "./src/2d/utils/index.ts"); var utils_1 = __webpack_require__(/*! ../utils */ "./src/2d/utils/index.ts");
var const_1 = __webpack_require__(/*! ../const */ "./src/2d/const.ts");
var math_1 = __webpack_require__(/*! ../math */ "./src/2d/math/index.ts"); var math_1 = __webpack_require__(/*! ../math */ "./src/2d/math/index.ts");
var texture_1 = __webpack_require__(/*! ../texture */ "./src/2d/texture/index.ts");
var MovieClip = (function (_super) { var MovieClip = (function (_super) {
__extends(MovieClip, _super); __extends(MovieClip, _super);
function MovieClip(mv) { function MovieClip(mv) {
...@@ -13422,18 +13750,13 @@ var MovieClip = (function (_super) { ...@@ -13422,18 +13750,13 @@ var MovieClip = (function (_super) {
_this._curFrame = 1; _this._curFrame = 1;
_this._isPlaying = true; _this._isPlaying = true;
_this._isFront = true; _this._isFront = true;
_this.textures = {};
_this.frameCount = 0; _this.frameCount = 0;
_this._lastFrame = 0; _this._lastFrame = 0;
_this.commonDeltaTime = 1000 / 60; _this.commonDeltaTime = 1000 / 60;
var s = _this; var s = _this;
s._instanceType = "MovieClip"; s._instanceType = "MovieClip";
if (mv) { if (mv)
s.init(mv); s.init(mv);
}
else {
s.totalFrames = 0;
}
return _this; return _this;
} }
Object.defineProperty(MovieClip.prototype, "currentFrame", { Object.defineProperty(MovieClip.prototype, "currentFrame", {
...@@ -13457,85 +13780,85 @@ var MovieClip = (function (_super) { ...@@ -13457,85 +13780,85 @@ var MovieClip = (function (_super) {
enumerable: true, enumerable: true,
configurable: true configurable: true
}); });
Object.defineProperty(MovieClip.prototype, "totalFrames", {
get: function () {
return this.rawData && this.rawData.frames || 0;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MovieClip.prototype, "videoWidth", {
get: function () {
return this.rawData && this.rawData.videoSize.width;
},
enumerable: true,
configurable: true
});
;
Object.defineProperty(MovieClip.prototype, "videoHeight", {
get: function () {
return this.rawData && this.rawData.videoSize.height;
},
enumerable: true,
configurable: true
});
;
MovieClip.prototype.init = function (mv) { MovieClip.prototype.init = function (mv) {
if (!mv)
return;
this.rawData = mv;
this.timeInterval = 1000 / mv.FPS; this.timeInterval = 1000 / mv.FPS;
this.startTime = Date.now(); this.startTime = Date.now();
this.startFrame = 1; this.startFrame = 1;
this.totalFrames = mv.frames;
this.deltaFrame = 60 / mv.FPS; this.deltaFrame = 60 / mv.FPS;
this.frameCount = this.deltaFrame; this.frameCount = this.deltaFrame;
this._curFrame = 1; this._curFrame = 1;
this.videoWidth = mv.videoSize.width; if (mv.images && !mv.textures) {
this.videoHeight = mv.videoSize.height; mv.textures = {};
var images = mv.images; for (var key in mv.images) {
if (mv.hasBeenCached) { var src = mv.images[key];
for (var keyName in images) { if (src.indexOf("iVBO") === 0 || src.indexOf("/9j/2w") === 0) {
this.textures[keyName] = utils_1.TextureCache[keyName]; src = 'data:image/png;base64,' + src;
}
this.initChildren(mv.sprites);
}
else {
for (var key in images) {
var bitmap = images[key];
var imgTag = utils_1.getCreateImage()();
var backCanvas = void 0;
if (bitmap.indexOf("iVBO") === 0 || bitmap.indexOf("/9j/2w") === 0) {
imgTag.src = 'data:image/png;base64,' + bitmap;
}
else {
imgTag.src = bitmap;
} }
this.textures[key] = Texture_1.default.from(backCanvas || imgTag); var imgTag = utils_1.getCreateImage()();
Texture_1.default.addToCache(this.textures[key], key); imgTag.src = src;
mv.textures[key] = new Texture_1.default(new texture_1.BaseTexture(imgTag));
} }
mv.hasBeenCached = true;
this.initChildren(mv.sprites);
} }
this.initChildren(mv.sprites);
}; };
MovieClip.prototype.initChildren = function (sprites) { MovieClip.prototype.initChildren = function (sprites) {
for (var i = 0, len = sprites.length; i < len; i++) { for (var i = 0, len = sprites.length; i < len; i++) {
var ele = sprites[i]; var ele = sprites[i];
if (ele.imageKey) { if (ele.imageKey) {
var child = new Sprite_1.default(this.textures[ele.imageKey]); var child = this.addChild(new Sprite_1.default(this.rawData.textures ?
this.rawData.textures[ele.imageKey] :
utils_1.TextureCache[ele.imageKey] ||
utils_1.TextureCache[ele.imageKey + ".png"]));
child["frames"] = ele.frames; child["frames"] = ele.frames;
child.transform.localMatrix.copy(ele.frames[0].transform);
child.transform._parentID = -1;
this.addChild(child);
if (ele.frames[0].alpha < 0.05) { if (ele.frames[0].alpha < 0.05) {
child.alpha = 0; child.alpha = 0;
} }
else { else {
child.alpha = ele.frames[0].alpha; child.alpha = ele.frames[0].alpha;
child.transform.localMatrix.copy(ele.frames[0].transform);
child.transform._parentID = -1;
} }
child["framesOri"] = ele.frames; child["framesOri"] = ele.frames;
child["imageKey"] = ele.imageKey; child["imageKey"] = ele.imageKey;
child["matteKey"] = ele.matteKey;
} }
} }
}; };
MovieClip.prototype.resetTransform = function (display, transform) { MovieClip.prototype.setImage = function (imagekey, imageUrl) {
display.x = transform.tx; var cs = [];
display.y = transform.ty;
display.scaleX = transform.a;
display.scaleY = transform.d;
display.rotation = Math.round(Math.atan2(transform.b, transform.a) * const_1.RAD_TO_DEG);
};
MovieClip.prototype.resetTransformAll = function (frameIndex) {
if (frameIndex > this.totalFrames)
frameIndex = this.totalFrames;
if (frameIndex <= 0)
frameIndex = 1;
for (var i = 0; i < this.children.length; i++) { for (var i = 0; i < this.children.length; i++) {
var child = this.children[i]; if (this.children[i]["imageKey"] == imagekey) {
if (child["frames"] && child["frames"][frameIndex - 1]) { cs.push(this.children[i]);
this.resetTransform(child, child["frames"][frameIndex - 1].transform);
} }
} }
}; if (!cs.length)
MovieClip.prototype.setImage = function (imagekey, imageUrl) {
if (!this.textures[imagekey])
return; return;
var texture = this.textures[imagekey]; var texture = cs[0].texture;
var width = texture.width; var width = texture.width;
var height = texture.height; var height = texture.height;
var image = utils_1.getCreateImage()(); var image = utils_1.getCreateImage()();
...@@ -13560,12 +13883,7 @@ var MovieClip = (function (_super) { ...@@ -13560,12 +13883,7 @@ var MovieClip = (function (_super) {
} }
newTexture = Texture_1.default.fromCanvas(canvas); newTexture = Texture_1.default.fromCanvas(canvas);
} }
for (var i = 0; i < self.children.length; i++) { cs.forEach(function (c) { c.texture = newTexture; });
var child = self.children[i];
if (child["imageKey"] == imagekey) {
child.texture = newTexture;
}
}
}; };
image.src = imageUrl; image.src = imageUrl;
}; };
...@@ -13823,6 +14141,40 @@ var MovieClip = (function (_super) { ...@@ -13823,6 +14141,40 @@ var MovieClip = (function (_super) {
return MovieClip; return MovieClip;
}(Container_1.default)); }(Container_1.default));
exports.MovieClip = MovieClip; exports.MovieClip = MovieClip;
function deepCopyFrames(frames, x, y, scaleX, scaleY, rotation, anchorX, anchorY) {
if (x === void 0) { x = 0; }
if (y === void 0) { y = 0; }
if (scaleX === void 0) { scaleX = 1; }
if (scaleY === void 0) { scaleY = 1; }
if (rotation === void 0) { rotation = 0; }
if (anchorX === void 0) { anchorX = 0; }
if (anchorY === void 0) { anchorY = 0; }
var cf = [];
rotation *= Math.PI / 180;
var lt = {};
lt.a = Math.cos(rotation) * scaleX;
lt.b = Math.sin(rotation) * scaleX;
lt.c = -Math.sin(rotation) * scaleY;
lt.d = Math.cos(rotation) * scaleY;
lt.tx = x + anchorX - ((anchorX * lt.a) + (anchorY * lt.c));
lt.ty = y + anchorY - ((anchorX * lt.b) + (anchorY * lt.d));
for (var j = 0; j < frames.length; j++) {
var frame = frames[j];
var pt = frame.transform;
var f = { alpha: 0, transform: null };
f.alpha = frame.alpha;
f.transform = {
a: (lt.a * pt.a) + (lt.b * pt.c),
b: (lt.a * pt.b) + (lt.b * pt.d),
c: (lt.c * pt.a) + (lt.d * pt.c),
d: (lt.c * pt.b) + (lt.d * pt.d),
tx: (lt.tx * pt.a) + (lt.ty * pt.c) + pt.tx,
ty: (lt.tx * pt.b) + (lt.ty * pt.d) + pt.ty,
};
cf.push(f);
}
return cf;
}
/***/ }), /***/ }),
...@@ -14371,6 +14723,299 @@ var ShowWord = (function (_super) { ...@@ -14371,6 +14723,299 @@ var ShowWord = (function (_super) {
exports.ShowWord = ShowWord; exports.ShowWord = ShowWord;
/***/ }),
/***/ "./src/2d/ui/forLottie/BezierEaser.ts":
/*!********************************************!*\
!*** ./src/2d/ui/forLottie/BezierEaser.ts ***!
\********************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getBezierEasing = (function () {
var beziers = {};
function getBezierEasing(a, b, c, d, nm) {
var str = nm || ('bez_' + a + '_' + b + '_' + c + '_' + d).replace(/\./g, 'p');
if (beziers[str]) {
return beziers[str];
}
var bezEasing = new BezierEasing([a, b, c, d]);
beziers[str] = bezEasing;
return bezEasing;
}
var NEWTON_ITERATIONS = 4;
var NEWTON_MIN_SLOPE = 0.001;
var SUBDIVISION_PRECISION = 0.0000001;
var SUBDIVISION_MAX_ITERATIONS = 10;
var kSplineTableSize = 11;
var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
var float32ArraySupported = typeof Float32Array === "function";
function A(aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; }
function B(aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; }
function C(aA1) { return 3.0 * aA1; }
function calcBezier(aT, aA1, aA2) {
return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT;
}
function getSlope(aT, aA1, aA2) {
return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1);
}
function binarySubdivide(aX, aA, aB, mX1, mX2) {
var currentX, currentT, i = 0;
do {
currentT = aA + (aB - aA) / 2.0;
currentX = calcBezier(currentT, mX1, mX2) - aX;
if (currentX > 0.0) {
aB = currentT;
}
else {
aA = currentT;
}
} while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
return currentT;
}
function newtonRaphsonIterate(aX, aGuessT, mX1, mX2) {
for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
var currentSlope = getSlope(aGuessT, mX1, mX2);
if (currentSlope === 0.0)
return aGuessT;
var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
aGuessT -= currentX / currentSlope;
}
return aGuessT;
}
function BezierEasing(points) {
this._p = points;
this._mSampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
this._precomputed = false;
this.get = this.get.bind(this);
}
BezierEasing.prototype = {
get: function (x) {
var mX1 = this._p[0], mY1 = this._p[1], mX2 = this._p[2], mY2 = this._p[3];
if (!this._precomputed)
this._precompute();
if (mX1 === mY1 && mX2 === mY2)
return x;
if (x === 0)
return 0;
if (x === 1)
return 1;
return calcBezier(this._getTForX(x), mY1, mY2);
},
_precompute: function () {
var mX1 = this._p[0], mY1 = this._p[1], mX2 = this._p[2], mY2 = this._p[3];
this._precomputed = true;
if (mX1 !== mY1 || mX2 !== mY2)
this._calcSampleValues();
},
_calcSampleValues: function () {
var mX1 = this._p[0], mX2 = this._p[2];
for (var i = 0; i < kSplineTableSize; ++i) {
this._mSampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
}
},
_getTForX: function (aX) {
var mX1 = this._p[0], mX2 = this._p[2], mSampleValues = this._mSampleValues;
var intervalStart = 0.0;
var currentSample = 1;
var lastSample = kSplineTableSize - 1;
for (; currentSample !== lastSample && mSampleValues[currentSample] <= aX; ++currentSample) {
intervalStart += kSampleStepSize;
}
--currentSample;
var dist = (aX - mSampleValues[currentSample]) / (mSampleValues[currentSample + 1] - mSampleValues[currentSample]);
var guessForT = intervalStart + dist * kSampleStepSize;
var initialSlope = getSlope(guessForT, mX1, mX2);
if (initialSlope >= NEWTON_MIN_SLOPE) {
return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
}
else if (initialSlope === 0.0) {
return guessForT;
}
else {
return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
}
}
};
return getBezierEasing;
}());
/***/ }),
/***/ "./src/2d/ui/forLottie/buildBezierEaserProps.ts":
/*!******************************************************!*\
!*** ./src/2d/ui/forLottie/buildBezierEaserProps.ts ***!
\******************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var BezierEaser_1 = __webpack_require__(/*! ./BezierEaser */ "./src/2d/ui/forLottie/BezierEaser.ts");
function buildBezierEaserProps(startValue, endValue, outV, inV, startIndex, endIndex, points, useH, limit) {
if (useH) {
for (var k = startIndex; k < endIndex; k++) {
points[k] = startValue.slice();
}
return;
}
var outX, outY, inX, inY, keyValue, perc;
var len = startValue.length;
var fncts, fnc;
if (outV.x.constructor === Array) {
fncts = [];
for (var i = 0; i < len; i++) {
outX = (typeof outV.x[i] === 'undefined') ? outV.x[0] : outV.x[i];
outY = (typeof outV.y[i] === 'undefined') ? outV.y[0] : outV.y[i];
inX = (typeof inV.x[i] === 'undefined') ? inV.x[0] : inV.x[i];
inY = (typeof inV.y[i] === 'undefined') ? inV.y[0] : inV.y[i];
fncts[i] = BezierEaser_1.getBezierEasing(outX, outY, inX, inY).get;
}
}
else {
outX = outV.x;
outY = outV.y;
inX = inV.x;
inY = inV.y;
fnc = BezierEaser_1.getBezierEasing(outX, outY, inX, inY).get;
}
var delta = endIndex - startIndex;
for (var k = startIndex; k <= endIndex; k++) {
if (limit) {
if (k < 0)
continue;
if (k >= limit)
break;
}
var frameNum = k;
var newValue = [];
for (var i = 0; i < len; i += 1) {
if (frameNum == endIndex) {
perc = 1;
}
else if (frameNum == startIndex) {
perc = 0;
}
else {
if (fncts) {
perc = fncts[i]((frameNum - startIndex) / delta);
}
else {
perc = fnc((frameNum - startIndex) / delta);
}
}
keyValue = startValue[i] + (endValue[i] - startValue[i]) * perc;
newValue[i] = keyValue;
}
points[k] = newValue;
}
}
exports.buildBezierEaserProps = buildBezierEaserProps;
/***/ }),
/***/ "./src/2d/ui/forLottie/buildBezierProps.ts":
/*!*************************************************!*\
!*** ./src/2d/ui/forLottie/buildBezierProps.ts ***!
\*************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function buildBezierProps(pt1, pt2, pt3, pt4, startIndex, endIndex, points, fnc, limit) {
var bezierData = buildBezierData(pt1, pt2, pt3, pt4);
for (var i = startIndex; i <= endIndex; i++) {
if (limit) {
if (i < 0)
continue;
if (i >= limit)
break;
}
var perc = fnc((i - startIndex) / (endIndex - startIndex));
var distanceInLine = bezierData.segmentLength * perc;
if (perc == 0) {
points[i] = bezierData.points[0].point;
continue;
}
if (perc == 1) {
points[i] = bezierData.points[bezierData.points.length - 1].point;
continue;
}
points[i] = findNearest(distanceInLine, bezierData.points);
}
}
exports.buildBezierProps = buildBezierProps;
function findNearest(distanceInLine, bezierDataPoints) {
for (var i = 0; i < bezierDataPoints.length; i++) {
var preLength = bezierDataPoints[i].preLength;
if (distanceInLine < preLength) {
var segmentPerc = (distanceInLine - bezierDataPoints[i - 1].preLength) / bezierDataPoints[i].partialLength;
var kLen = bezierDataPoints[i - 1].point.length;
var newValue = [];
for (var k = 0; k < kLen; k += 1) {
newValue[k] = bezierDataPoints[i - 1].point[k] + (bezierDataPoints[i].point[k] - bezierDataPoints[i - 1].point[k]) * segmentPerc;
}
return newValue;
}
}
return bezierDataPoints[bezierDataPoints.length - 1].point;
}
var storedData = {};
function buildBezierData(pt1, pt2, pt3, pt4) {
var bezierName = (pt1[0] + '_' + pt1[1] + '_' + pt2[0] + '_' + pt2[1] + '_' + pt3[0] + '_' + pt3[1] + '_' + pt4[0] + '_' + pt4[1]).replace(/\./g, 'p');
if (!storedData[bezierName]) {
var curveSegments = 150;
var k, i, len;
var ptCoord, perc, addedLength = 0;
var ptDistance;
var point, lastPoint = null;
if (pt1.length === 2 && (pt1[0] != pt2[0] || pt1[1] != pt2[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt1[0] + pt3[0], pt1[1] + pt3[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt2[0] + pt4[0], pt2[1] + pt4[1])) {
curveSegments = 2;
}
var bezierData = {
segmentLength: 0,
points: new Array(curveSegments)
};
len = pt3.length;
for (k = 0; k < curveSegments; k += 1) {
point = new Array(len);
perc = k / (curveSegments - 1);
ptDistance = 0;
for (i = 0; i < len; i += 1) {
ptCoord = Math.pow(1 - perc, 3) * pt1[i] + 3 * Math.pow(1 - perc, 2) * perc * (pt1[i] + pt3[i]) + 3 * (1 - perc) * Math.pow(perc, 2) * (pt2[i] + pt4[i]) + Math.pow(perc, 3) * pt2[i];
point[i] = ptCoord;
if (lastPoint !== null) {
ptDistance += Math.pow(point[i] - lastPoint[i], 2);
}
}
ptDistance = Math.sqrt(ptDistance);
addedLength += ptDistance;
bezierData.points[k] = {
partialLength: ptDistance,
preLength: addedLength,
point: point
};
lastPoint = point;
}
bezierData.segmentLength = addedLength;
storedData[bezierName] = bezierData;
}
return storedData[bezierName];
}
function pointOnLine2D(x1, y1, x2, y2, x3, y3) {
var det1 = (x1 * y2) + (y1 * x3) + (x2 * y3) - (x3 * y2) - (y3 * x1) - (x2 * y1);
return det1 > -0.001 && det1 < 0.001;
}
/***/ }), /***/ }),
/***/ "./src/2d/ui/index.ts": /***/ "./src/2d/ui/index.ts":
...@@ -15171,6 +15816,13 @@ exports.mapWebGLBlendModes = mapWebGLBlendModes; ...@@ -15171,6 +15816,13 @@ exports.mapWebGLBlendModes = mapWebGLBlendModes;
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
var env = "web";
if (window)
window["my"] = null;
function getEnv() {
return env;
}
exports.getEnv = getEnv;
function createCanvas() { function createCanvas() {
return document && document.createElement("canvas") || my._createOffscreenCanvas(); return document && document.createElement("canvas") || my._createOffscreenCanvas();
} }
...@@ -15182,6 +15834,7 @@ function initedByCanvas(canvas) { ...@@ -15182,6 +15834,7 @@ function initedByCanvas(canvas) {
requestAnimationFrame: canvas.requestAnimationFrame.bind(canvas), requestAnimationFrame: canvas.requestAnimationFrame.bind(canvas),
cancelAnimationFrame: canvas.cancelAnimationFrame.bind(canvas), cancelAnimationFrame: canvas.cancelAnimationFrame.bind(canvas),
}; };
env = "tb";
} }
exports.initedByCanvas = initedByCanvas; exports.initedByCanvas = initedByCanvas;
function destroyCanvasContent() { function destroyCanvasContent() {
...@@ -15774,10 +16427,10 @@ function createNineTextures(imageUrl) { ...@@ -15774,10 +16427,10 @@ function createNineTextures(imageUrl) {
"y": ~~(i / 3) * h, "y": ~~(i / 3) * h,
w: w, h: h, sw: w, sh: h, ox: 0, oy: 0, ro: false w: w, h: h, sw: w, sh: h, ox: 0, oy: 0, ro: false
}; };
FYGE.createTextureSheet(new FYGE.BaseTexture(image), obj); var textures = FYGE.createTextureSheet(new FYGE.BaseTexture(image), obj);
var arr = []; var arr = [];
for (var i = 0; i < 9; i++) for (var i = 0; i < 9; i++)
arr.push(FYGE.TextureCache[name + i]); arr.push(textures[name + i]);
resolve(arr); resolve(arr);
}; };
image.onerror = function () { image.onerror = function () {
...@@ -16061,7 +16714,7 @@ var Object3D = (function (_super) { ...@@ -16061,7 +16714,7 @@ var Object3D = (function (_super) {
Object3D.prototype.copy = function (source, recursive) { Object3D.prototype.copy = function (source, recursive) {
if (recursive === void 0) { recursive = true; } if (recursive === void 0) { recursive = true; }
this.name = source.name; this.name = source.name;
this.visible = this.visible; this.visible = source.visible;
this.up.copy(source.up); this.up.copy(source.up);
this.position.copy(source.position); this.position.copy(source.position);
this.quaternion.copy(source.quaternion); this.quaternion.copy(source.quaternion);
...@@ -21436,8 +22089,6 @@ __export(__webpack_require__(/*! ./2d/utils */ "./src/2d/utils/index.ts")); ...@@ -21436,8 +22089,6 @@ __export(__webpack_require__(/*! ./2d/utils */ "./src/2d/utils/index.ts"));
__export(__webpack_require__(/*! ./sound */ "./src/sound/index.ts")); __export(__webpack_require__(/*! ./sound */ "./src/sound/index.ts"));
__export(__webpack_require__(/*! ./tween */ "./src/tween/index.ts")); __export(__webpack_require__(/*! ./tween */ "./src/tween/index.ts"));
__export(__webpack_require__(/*! ./3d */ "./src/3d/index.ts")); __export(__webpack_require__(/*! ./3d */ "./src/3d/index.ts"));
if (window)
window["my"] = null;
__export(__webpack_require__(/*! ./Stats */ "./src/Stats.ts")); __export(__webpack_require__(/*! ./Stats */ "./src/Stats.ts"));
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -67,7 +67,7 @@ export function createTextureSheet(baseTexture: BaseTexture, altaData) { ...@@ -67,7 +67,7 @@ export function createTextureSheet(baseTexture: BaseTexture, altaData) {
} }
//如果是被截掉过透明边界的 //如果是被截掉过透明边界的
if (data.ox || data.oy) { if (data.ox || data.oy || data.w != data.sw || data.h != data.sh) {
//其实就是在orig上切图,偏移 //其实就是在orig上切图,偏移
trim = new Rectangle( trim = new Rectangle(
Math.floor(data.ox), Math.floor(data.ox),
......
...@@ -3,6 +3,10 @@ import { Tween } from "../../tween"; ...@@ -3,6 +3,10 @@ import { Tween } from "../../tween";
import { Texture, BaseTexture } from "../texture"; import { Texture, BaseTexture } from "../texture";
import { Container, Sprite, DisplayObject } from "../display"; import { Container, Sprite, DisplayObject } from "../display";
import { getBezierEasing } from "./forLottie/BezierEaser";
import { buildBezierProps } from "./forLottie/buildBezierProps";
import { buildBezierEaserProps } from "./forLottie/buildBezierEaserProps";
interface LottieData { interface LottieData {
"fr": number,//珍露 30 60等 "fr": number,//珍露 30 60等
"ip": number,//开始帧 "ip": number,//开始帧
...@@ -17,7 +21,9 @@ interface LottieData { ...@@ -17,7 +21,9 @@ interface LottieData {
"h": number, "h": number,
"p": string,//base64数据 "p": string,//base64数据
}[], }[],
"textures"?: { [key: string]: Texture }//缓存的贴图,为了上面的assets里的图片数据,不进全局缓存 "textures"?: { [key: string]: Texture }//缓存的贴图,为了上面的assets里的图片数据,不进全局缓存,
svgaData?: any //数据生成后存入
} }
interface LayerData { interface LayerData {
"ind": number,//id唯一 "ind": number,//id唯一
...@@ -28,16 +34,37 @@ interface LayerData { ...@@ -28,16 +34,37 @@ interface LayerData {
"ks": KsData; "ks": KsData;
"ip": number,//开始帧 "ip": number,//开始帧
"op": number,//结束帧 "op": number,//结束帧
transformDatas?: TansformData[];
} }
interface KsData { interface KsData {
o: KeyData o: KeyData //透明度
r: KeyData r: KeyData //旋转
p: KeyData p: KeyData //位置
a: KeyData a: KeyData //锚点
s: KeyData s: KeyData //缩放
} }
interface KeyData { interface KeyData {
a: number, k: { "t": number, "s": number[] }[] | number[] | number, x: string a: number,
k: KeyAniData[] | number[] | number,
x: string,//可能有表达式
// frames?: KeyFrameInt[],//注意根据表达式还要添加
props?: number[][],//记录所有的属性,每一帧的
}
interface KeyAniData {
t: number,
s: number[],
i: { x: number | number[], y: number | number[] },
o: { x: number | number[], y: number | number[] },
to: number[],
ti: number[],
h: number
} }
/** /**
...@@ -57,6 +84,51 @@ interface TweenData { ...@@ -57,6 +84,51 @@ interface TweenData {
timeOri?: number, timeOri?: number,
} }
/**
* 每一个属性在总帧数上每个关键点的数据
* 挂在每个层级的的ks的各个属性上,到时直接计算出所有的x,y,sx,sy,r,alpha, ax和ay固定,注意xy都得减axy
* 第一步只处理ks里面的数据
*/
interface KeyFrameInt {
/**
* 数值
*/
value: number[],
/**
* 第几帧
*/
frame: number,
// type: "stay" | "tween",//stay停留不变,到下一个状态时硬切 ,
/**
* 为了计算贝塞尔补间数据 ,有io或toti才有缓动
*/
i?: { x: number | number[], y: number | number[] };
o?: { x: number | number[], y: number | number[] };
/**
* 为了计算贝塞尔补间数据
*/
to?: number[],
ti?: number[],
//不知道干嘛用的,但是有用
h?: boolean,
}
interface TansformData {
alpha: number;
transform?: {
a: number,
b: number,
c: number,
d: number,
tx: number,
ty: number,
};
}
/** /**
* 用Tween拼,后续计算帧数据记录 * 用Tween拼,后续计算帧数据记录
...@@ -71,7 +143,7 @@ export class Lottie extends Container { ...@@ -71,7 +143,7 @@ export class Lottie extends Container {
* 总帧数 * 总帧数
*/ */
get totalFrames(): number { get totalFrames(): number {
return this.rawData && (this.rawData.op - this.rawData.ip); return this.rawData && (this.rawData.op - this.rawData.ip) || 0;
}; };
/** /**
* 锁步的时间间隔,按fps定,毫秒 * 锁步的时间间隔,按fps定,毫秒
...@@ -813,4 +885,385 @@ function getLoopInPingpongTween(objArr: TweenData[], round: number, op: number) ...@@ -813,4 +885,385 @@ function getLoopInPingpongTween(objArr: TweenData[], round: number, op: number)
return tweenArr return tweenArr
}
//动画总ip必须为0,否则修改
let totalOp: number = 0;
let lottieData: LottieData
export function handleLottieData(data: LottieData) {
//已经计算过了就直接返回了
if (data.svgaData) return data.svgaData;
//存一下,全局用
totalOp = data.op;//最后一帧估计不算
lottieData = data;
//是否需要深拷贝
// data = JSON.parse(JSON.stringify(data))
//最终返回的数据
var videoEntity: any = {};
//一些简单的先设置了
videoEntity.videoSize = {
width: data.w,
height: data.h
}
videoEntity.FPS = data.fr;
videoEntity.frames = data.op - data.ip;
//图片还在的时
if (data.assets) {//注意这时不能把素材干进全局。单独存在自己的数据中
videoEntity.images = {};
data.assets.forEach((a) => {
videoEntity.images[a.id] = a.p.replace("data:image/png;base64,", "")//去掉相同的前缀
})
}
for (var i = 0; i < data.layers.length; i++) {
var layerData = data.layers[i];
var ks = layerData.ks;
//锚点是不变的,先写
var ad: [number, number] = typeof layerData.ks.a.k[0] == "number" ? layerData.ks.a.k : layerData.ks.a.k[0].s;
// ks.a.frames = [{ value: ad, frame: 0 }];
//@ts-ignore
ks.a.props = fillUp(ad);
//其他的
addFrames(layerData);
}
//开始计算每帧矩阵,注意父级,循环每帧,必须上面的先执行完毕
data.layers.forEach((l) => {
l.transformDatas = fillUp({
alpha: 0,
// transform: {
// a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0
// }
});
})
for (var i = 0; i < totalOp; i++) {
data.layers.forEach((l) => {
var ks = l.ks;
var ip = l.ip;
var op = l.op;
if (i >= ip && i <= op) {
// if()
// console.log(ks.o.props[i], l.nm, ks.o.props.length, i)
l.transformDatas[i].alpha = ks.o.props[i][0];
}
recursiveUpdateTransform(l, i);
})
}
//sprites最重要的东西,里面有imageKey和frames,TODO
videoEntity.sprites = [];
for (var i = 0; i < data.layers.length; i++) {
var layerData = data.layers[i];
if (layerData.refId)//有图片的才存下,因为全部已经转换成世界矩阵。容器已经没有意义
videoEntity.sprites.push({
imageKey: layerData.refId,
frames: layerData.transformDatas
})
}
videoEntity.sprites.reverse()
return lottieData.svgaData = videoEntity
}
function addFrames(layerData: LayerData) {
var ks = layerData.ks;
var ip = layerData.ip;
var op = layerData.op;
//@ts-ignore透明度
if (ks.o.k.length) {
addFrame(layerData, "o");
} else {//没有直接取首诊数据,且根据ip op处理显隐 具体怎么处理好点
//@ts-ignore 透明度决定显隐,最后根据ip和op来重新修正alpha 注意ip有可能小于0,op可能大于totalOp,所以注意判断 TODO
var alpha = ks.o.k / 100;
// ks.o.frames = [{ value: alpha, frame: 0 }]
//@ts-ignore
ks.o.props = fillUp([alpha]);
}
//@ts-ignore 旋转
if (ks.r.k.length) {
addFrame(layerData, "r");
} else {
//@ts-ignore
// ks.r.frames = [{ value: ks.r.k, frame: 0 }]
//@ts-ignore
ks.r.props = fillUp([ks.r.k]);
}
//位置,得是对象
if (typeof ks.p.k[0] != "number") {
addFrame(layerData, "p");
} else {
var anchor: [number, number] = typeof ks.a.k[0] == "number" ? ks.a.k : ks.a.k[0].s;
//@ts-ignore
var p = ks.p.k;
// ks.p.frames = [{ value: [p[0] - anchor[0], p[1] - anchor[1]], frame: 0 }]
//@ts-ignore
ks.p.props = fillUp([p[0] - anchor[0], p[1] - anchor[1]]);
}
//缩放
if (typeof ks.s.k[0] != "number") {
addFrame(layerData, "s");
} else {
//@ts-ignore
var s = ks.s.k;
// ks.s.frames = [{ value: [s[0] / 100, s[1] / 100], frame: 0 }]
//@ts-ignore
ks.s.props = fillUp([s[0] / 100, s[1] / 100]);
}
}
function addFrame(layerData: LayerData, type: "o" | "r" | "p" | "s") {
//@ts-ignore
var data: KeyAniData[] = layerData.ks[type].k;
var ip = layerData.ip; //有小于0的情况
var op = layerData.op; //有大于totalOp的情况
var ks = layerData.ks;
var anchor: [number, number] = typeof ks.a.k[0] == "number" ? ks.a.k : ks.a.k[0].s;
var frames: KeyFrameInt[] = [];
var props: number[][] = ks[type].props = [];
props.length = totalOp + 1;
for (let i = 0; i < data.length; i++) {
let d = data[i];
let value: number[];
switch (type) {
case "r":
value = [d.s[0]];
break;
case "o":
value = [d.s[0] / 100];
break;
case "s":
value = [d.s[0] / 100, d.s[1] / 100, 0]
break;
case "p":
value = [d.s[0] - anchor[0], d.s[1] - anchor[1], 0]
break;
}
frames.push({
i: d.i, o: d.o, ti: d.ti, to: d.to,
h: d.h === 1,
value,
frame: d.t
})
}
//把已有的干一边
for (var i = 0; i < frames.length - 1; i++) {//最后一个数据不用
let f = frames[i], nextF = frames[i + 1];
if (f.to) {
//把函数也传进去吧,用来处理
var fnc = getBezierEasing(f.o.x, f.o.y, f.i.x, f.i.y).get;
buildBezierProps(
f.value,
nextF.value,
f.to,//.map((e, index) => e - anchor[index] || 0),
f.ti,//.map((e, index) => e - anchor[index] || 0),
f.frame,
nextF.frame,
props,
fnc,
ks[type].x ? undefined : totalOp //没有表达式时直接加限制
);
}
//没有路径,只有缓动
else {
buildBezierEaserProps(
f.value,
nextF.value,
f.o,
f.i,
f.frame,
nextF.frame,
props,
f.h,
ks[type].x ? undefined : totalOp,
)
}
}
//如果是h==1的,把最后的数据加上
if (frames[frames.length - 1].h) {
props[frames[frames.length - 1].frame] = frames[frames.length - 1].value.slice();
}
//有表达式的,把最后一帧数据加上,循环有用
if (ks[type].x && (ks[type].x.indexOf("loopOut") >= 0 || ks[type].x.indexOf("loopIn") >= 0)) {
var xs = ks[type].x;
var loopOut = xs.indexOf("loopOut") >= 0;
var loopIn = xs.indexOf("loopIn") >= 0;
//取数字
var rr = +xs.replace(/[^0-9]/ig, "");
if (rr > frames.length - 1) rr = 0;
var propsClone = props.slice();
var isCycle = xs.indexOf("cycle") >= 0;
var isPingpong = xs.indexOf("pingpong") >= 0;
var dir = false;
var lastIndex = frames.length - 1;
var startIndex = 0;
var count = loopOut ? frames[lastIndex].frame ://开始接的那一帧
frames[0].frame;//往前的从0开始
var stepOffset = loopOut ? frames[lastIndex - (rr || lastIndex)].frame :
// frames[0 + (rr || lastIndex)].frame;//循环帧数起点索引,往后补和往前补的
frames[0].frame
// frames[lastIndex - (rr || lastIndex)].frame
var stepAll = loopOut ? frames[lastIndex].frame - stepOffset :
// stepOffset - frames[0].frame; //总循环数每次,拐点只算一次,多一帧应该也计算了
// frames[lastIndex].frame - stepOffset
frames[0 + (rr || lastIndex)].frame - stepOffset;
while (loopOut ?
(/*count <= op &&*/ count <= totalOp) ://op也可能大于totalOp;
(/*count >= ip &&*/ count >= 0)//ip他妈有可能是负的
) {//到op为止,其他的不算
if (isPingpong) {
if (dir) {//正向,第一帧不算
funLoop((index) => {
if (loopOut) {
props[++count] = propsClone[index + 1 + stepOffset].slice();
} else {
props[--count] = propsClone[stepAll - 1 - index + stepOffset].slice();
}
}, stepAll)
} else {//反向,从最后一帧(不算)开始往前加剩下的
funLoop((index) => {
if (loopOut) {
props[++count] = propsClone[stepAll - 1 - index + stepOffset].slice();
} else {//从起始点参考其实是正向
// props[--count] = propsClone[index + 1 + stepOffset].slice();
props[--count] = propsClone[index + 1 + stepOffset].slice();
}
}, stepAll)
}
dir = !dir;
} else if (isCycle) {
funLoop((index) => {
if (loopOut) {
props[++count] = propsClone[index + 1 + stepOffset].slice()
} else {
props[--count] = propsClone[stepAll - 1 - index + stepOffset].slice();
}
}, stepAll)
} else {//其他情况暂时不管
break;
}
}
}
var arr = returnEmpty(props);
if (arr[0] !== null) {//前面补齐
var countFront = arr[0]
var startValue = props[countFront];
while (countFront--) {
props[countFront] = startValue.slice();
}
}
// console.log(layerData.nm, arr)
if (arr[1] !== null) {
// console.log(layerData.nm, arr, arr[1])
var countAfter = arr[1];
var endValue = props[countAfter];
while (countAfter++ <= totalOp) {
props[countAfter] = endValue.slice();
}
}
}
function findLayerByInd(ind: number): LayerData {
for (var i = 0; i < lottieData.layers.length; i++) {
if (lottieData.layers[i].ind === ind) return lottieData.layers[i]
}
//貌似layer是按顺序的,TMD有些中间的ind是没有的,还是找吧
// return lottieData.layers[ind - 1];
}
function recursiveUpdateTransform(l: LayerData, index: number) {
if (l.parent !== undefined) {
//ind从1开始,所以不用考虑0,且不应该存在 p没有的情况
var p = findLayerByInd(l.parent)
recursiveUpdateTransform(p, index);
if (!l.transformDatas[index].transform) {
//计算自己的先
var lt = l.transformDatas[index];
lt.transform = createWorldMatrix(
createLocalMatrix(l, index),
p.transformDatas[index].transform
);
}
}
//直接进行tans
else if (!l.transformDatas[index].transform) {
//计算顶级的自己的世界矩阵
var lt = l.transformDatas[index];
lt.transform = createLocalMatrix(l, index);
}
}
//不用Matrix类,担心属性太多,直接用函数
function createLocalMatrix(l: LayerData, index: number) {
var ks = l.ks;
var x = 0, y = 0, scaleX = 1, scaleY = 1, rotation = 0;
var anchorX = ks.a.props[0][0], anchorY = ks.a.props[0][1];
if (ks.p.props[index]) {
x = ks.p.props[index][0];
y = ks.p.props[index][1];
}
if (ks.s.props[index]) {
scaleX = ks.s.props[index][0];
scaleY = ks.s.props[index][1];
}
if (ks.r.props[index]) {
rotation = ks.r.props[index][0];
}
var lt: any = {};
rotation *= Math.PI / 180;
lt.a = Math.cos(rotation) * scaleX;
lt.b = Math.sin(rotation) * scaleX;
lt.c = -Math.sin(rotation) * scaleY;
lt.d = Math.cos(rotation) * scaleY;
lt.tx = x + anchorX - ((anchorX * lt.a) + (anchorY * lt.c));
lt.ty = y + anchorY - ((anchorX * lt.b) + (anchorY * lt.d));
return lt;
}
//不用Matrix类,担心属性太多,直接用函数
function createWorldMatrix(lt, pt) {
return {
a: (lt.a * pt.a) + (lt.b * pt.c),
b: (lt.a * pt.b) + (lt.b * pt.d),
c: (lt.c * pt.a) + (lt.d * pt.c),
d: (lt.c * pt.b) + (lt.d * pt.d),
tx: (lt.tx * pt.a) + (lt.ty * pt.c) + pt.tx,
ty: (lt.tx * pt.b) + (lt.ty * pt.d) + pt.ty,
}
}
function returnEmpty(arr: any[]): [number, number] {
var front = null, after = null;
var last = !!arr[0];
for (var i = 1; i < arr.length; i++) {
if (!last) {
if (arr[i] !== undefined) {
front = i;
}
} else {
if (arr[i] === undefined) {
after = i - 1;
break
}
}
last = !!arr[i]
}
return [front, after]
}
function funLoop(fun: (index: number) => void, times: number) {
if (times <= 0) return;
let count = times;
// while (count--) fun(count);//刚好索引从times-1开始,到0结束
while (count--) fun(times - count - 1);//刚好索引从0开始,到times-1结束
}
function fillUp<T>(value: T): T[] {//最后一个数据应该用不到吧
return Array(...Array(totalOp)).map((a, i) => JSON.parse(JSON.stringify(value)));
} }
\ No newline at end of file
...@@ -6,6 +6,7 @@ import { Event } from "../events/Event"; ...@@ -6,6 +6,7 @@ import { Event } from "../events/Event";
import { TextureCache, getCreateImage } from "../utils"; import { TextureCache, getCreateImage } from "../utils";
import { RAD_TO_DEG } from "../const"; import { RAD_TO_DEG } from "../const";
import { Matrix } from "../math"; import { Matrix } from "../math";
import { BaseTexture } from "../texture";
/** /**
* 用于播放动画 * 用于播放动画
...@@ -29,7 +30,10 @@ import { Matrix } from "../math"; ...@@ -29,7 +30,10 @@ import { Matrix } from "../math";
* @extends Container * @extends Container
*/ */
export class MovieClip extends Container { export class MovieClip extends Container {
/**
* 原始数据,接口在解析类上,不搞先
*/
private rawData
/** /**
* 锁步将按时间间隔来执行动画 * 锁步将按时间间隔来执行动画
*/ */
...@@ -106,18 +110,18 @@ export class MovieClip extends Container { ...@@ -106,18 +110,18 @@ export class MovieClip extends Container {
* @public * @public
* @since 1.0.0 * @since 1.0.0
* @type {number} * @type {number}
* @default 1 * @default 0
* @readonly * @readonly
*/ */
public totalFrames: number; get totalFrames(): number {
return this.rawData && this.rawData.frames || 0;
public videoWidth: number; }
public videoHeight: number; get videoWidth(): number {
/** return this.rawData && this.rawData.videoSize.width;
* 所有textures缓存 };
*/ get videoHeight(): number {
private textures = {}; return this.rawData && this.rawData.videoSize.height;
};
/** /**
* 锁步的时间间隔,按fps定,毫秒 * 锁步的时间间隔,按fps定,毫秒
*/ */
...@@ -142,11 +146,7 @@ export class MovieClip extends Container { ...@@ -142,11 +146,7 @@ export class MovieClip extends Container {
let s: any = this; let s: any = this;
s._instanceType = "MovieClip"; s._instanceType = "MovieClip";
//初始化 //初始化
if (mv) { if (mv) s.init(mv);
s.init(mv);
} else {
s.totalFrames = 0;
}
} }
/** /**
...@@ -154,19 +154,19 @@ export class MovieClip extends Container { ...@@ -154,19 +154,19 @@ export class MovieClip extends Container {
* @param mv * @param mv
*/ */
init(mv) { init(mv) {
if (!mv) return
//记录源数据
this.rawData = mv;
//记录基本信息,fps,每秒输出帧数,frames,总帧数,videoSize暂时不管 //记录基本信息,fps,每秒输出帧数,frames,总帧数,videoSize暂时不管
//如果fps小于60怎么处理。update时怎么处理 //如果fps小于60怎么处理。update时怎么处理
this.timeInterval = 1000 / mv.FPS; this.timeInterval = 1000 / mv.FPS;
this.startTime = Date.now(); this.startTime = Date.now();
this.startFrame = 1; this.startFrame = 1;
this.totalFrames = mv.frames
//间隔帧数, //间隔帧数,
this.deltaFrame = 60 / mv.FPS; this.deltaFrame = 60 / mv.FPS;
this.frameCount = this.deltaFrame; this.frameCount = this.deltaFrame;
this._curFrame = 1; this._curFrame = 1;
this.videoWidth = mv.videoSize.width;
this.videoHeight = mv.videoSize.height;
//考虑是否要加遮罩,用videoSize,暂时不用,为了性能 //考虑是否要加遮罩,用videoSize,暂时不用,为了性能
// var mask = new Graphics(); // var mask = new Graphics();
// mask.beginFill(0xffffff, 1); // mask.beginFill(0xffffff, 1);
...@@ -174,128 +174,127 @@ export class MovieClip extends Container { ...@@ -174,128 +174,127 @@ export class MovieClip extends Container {
// mask.endFill(); // mask.endFill();
// this.mask = mask; // this.mask = mask;
//缓存所有图片 //缓存图片
const images = mv.images; if (mv.images && !mv.textures) {//带图片数据的待测试
if (mv.hasBeenCached) { mv.textures = {};
//如已被缓存,则直接取了赋值 for (var key in mv.images) {
for (var keyName in images) { var src = mv.images[key];
if (src.indexOf("iVBO") === 0 || src.indexOf("/9j/2w") === 0) {
this.textures[keyName] = TextureCache[keyName]; src = 'data:image/png;base64,' + src;
} }//图片链接时的宽高适配再说,暂时没有遇到过
this.initChildren(mv.sprites)
} else {
//合图有bug,先不合了
// if (GlobalPro.stageRenderType == RENDERER_TYPE.WEBGL) {
// //缓存成一张canvas,考虑要不要把所有资源搞成图集
// DrawAllToCanvas(images, (t) => {
// this.textures = t;
// this.initChildren(mv.sprites)
// //缓存
// for (var key in this.textures) {
// Texture.addToCache(this.textures[key], key)
// }
// mv.hasBeenCached = true;
// })
// } else {
//canvas直接缓存
for (var key in images) {
var bitmap = images[key];
// let imgTag = document.createElement('img');
let imgTag = getCreateImage()(); let imgTag = getCreateImage()();
let backCanvas; imgTag.src = src;
if (bitmap.indexOf("iVBO") === 0 || bitmap.indexOf("/9j/2w") === 0) { mv.textures[key] = new Texture(new BaseTexture(imgTag));//这种方法不会缓存进全局
imgTag.src = 'data:image/png;base64,' + bitmap;
}
else {
imgTag.src = bitmap;
//这里有问题,再说
// if (frames[0] && frames[0].layout) {
// backCanvas = document.createElement('canvas');
// backCanvas.width = frames[0].layout.width
// backCanvas.height = frames[0].layout.height
// imgTag.onload = function () {
// backCanvas.getContext('2d').drawImage(imgTag, 0, 0, frames[0].layout.width, frames[0].layout.height)
// }
// }
}
this.textures[key] = Texture.from(backCanvas || imgTag);
// this.textures[key].once("loaded",()=>{
// 是否监听加载完成?
// })
//考虑到key和已有缓存冲突,svga的都单独自己缓存,外部不可用,以后有时间搞
Texture.addToCache(this.textures[key], key)
} }
mv.hasBeenCached = true;
this.initChildren(mv.sprites)
// }
} }
this.initChildren(mv.sprites);
//缓存所有图片
// const images = mv.images;
// if (mv.hasBeenCached) {
// //如已被缓存,则直接取了赋值
// for (var keyName in images) {
// this.textures[keyName] = TextureCache[keyName];
// }
// this.initChildren(mv.sprites)
// } else {
// //合图有bug,先不合了
// // if (GlobalPro.stageRenderType == RENDERER_TYPE.WEBGL) {
// // //缓存成一张canvas,考虑要不要把所有资源搞成图集
// // DrawAllToCanvas(images, (t) => {
// // this.textures = t;
// // this.initChildren(mv.sprites)
// // //缓存
// // for (var key in this.textures) {
// // Texture.addToCache(this.textures[key], key)
// // }
// // mv.hasBeenCached = true;
// // })
// // } else {
// //canvas直接缓存
// for (var key in images) {
// var bitmap = images[key];
// // let imgTag = document.createElement('img');
// let imgTag = getCreateImage()();
// let backCanvas;
// if (bitmap.indexOf("iVBO") === 0 || bitmap.indexOf("/9j/2w") === 0) {
// imgTag.src = 'data:image/png;base64,' + bitmap;
// }
// else {
// imgTag.src = bitmap;
// //这里有问题,再说//这里估计是直接用图片链接的,为了适配画在canvas,以后遇到再说
// // if (frames[0] && frames[0].layout) {
// // backCanvas = document.createElement('canvas');
// // backCanvas.width = frames[0].layout.width
// // backCanvas.height = frames[0].layout.height
// // imgTag.onload = function () {
// // backCanvas.getContext('2d').drawImage(imgTag, 0, 0, frames[0].layout.width, frames[0].layout.height)
// // }
// // }
// }
// this.textures[key] = Texture.from(backCanvas || imgTag);
// // this.textures[key].once("loaded",()=>{
// // 是否监听加载完成?
// // })
// //考虑到key和已有缓存冲突,svga的都单独自己缓存,外部不可用,以后有时间搞
// Texture.addToCache(this.textures[key], key)
// }
// mv.hasBeenCached = true;
// this.initChildren(mv.sprites)
// // }
// }
} }
private initChildren(sprites) { private initChildren(sprites) {
for (var i = 0, len = sprites.length; i < len; i++) { for (var i = 0, len = sprites.length; i < len; i++) {
var ele = sprites[i]; var ele = sprites[i];
if (ele.imageKey) { if (ele.imageKey) {
var child = new Sprite(this.textures[ele.imageKey]); // var child = new Sprite(this.textures[ele.imageKey]);
var child = this.addChild(new Sprite(
this.rawData.textures ?
this.rawData.textures[ele.imageKey] ://自身没存的,取全局的,有图片单独处理出去
TextureCache[ele.imageKey] ||
TextureCache[ele.imageKey + ".png"]||null
));
//直接赋值矩阵 //直接赋值矩阵
child["frames"] = ele.frames; child["frames"] = ele.frames;
child.transform.localMatrix.copy(ele.frames[0].transform);
child.transform._parentID = -1;
this.addChild(child);
//透明度处理 //透明度处理
if (ele.frames[0].alpha < 0.05) { if (ele.frames[0].alpha < 0.05) {
// child.visible = false; // child.visible = false;
child.alpha = 0; child.alpha = 0;
} else { } else {
child.alpha = ele.frames[0].alpha; child.alpha = ele.frames[0].alpha;
//透明度不为0才赋值吧
child.transform.localMatrix.copy(ele.frames[0].transform);
child.transform._parentID = -1;
} }
//记录一个源数据 //记录一个源数据
child["framesOri"] = ele.frames; child["framesOri"] = ele.frames;
//记录一个源imageKey //记录一个源imageKey
child["imageKey"] = ele.imageKey; child["imageKey"] = ele.imageKey;
//记录一个标识 //记录一个标识
child["matteKey"] = ele.matteKey; // child["matteKey"] = ele.matteKey;
} }
} }
} }
/**
* 用基础属性重置,废的
* @param display
* @param transform
*/
private resetTransform(display, transform) {
display.x = transform.tx;
display.y = transform.ty;
display.scaleX = transform.a;
display.scaleY = transform.d;
display.rotation = Math.round(Math.atan2(transform.b, transform.a) * RAD_TO_DEG);
}
/**
* 用基础属性重置所有的待frame的children
* @param frameIndex 帧 1到total
*/
public resetTransformAll(frameIndex: number) {
if (frameIndex > this.totalFrames) frameIndex = this.totalFrames;
if (frameIndex <= 0) frameIndex = 1;
for (var i = 0; i < this.children.length; i++) {
let child = this.children[i];
if (child["frames"] && child["frames"][frameIndex - 1]) {
this.resetTransform(child, child["frames"][frameIndex - 1].transform)
}
}
}
/** /**
* *
* @param imagekey 对应的imagekey * @param imagekey 对应的imagekey
* @param imageUrl 图片路径,以后考虑支持多种形式 * @param imageUrl 图片路径,以后考虑支持多种形式
*/ */
setImage(imagekey, imageUrl: string) { setImage(imagekey: string, imageUrl: string) {//新修改,待测试TODO
if (!this.textures[imagekey]) return //先获取原先贴图,为了宽高适配,,这种如何保证base64已经加载完毕,考虑lottie的图片宽高信息存过来?
let texture = this.textures[imagekey] let cs: Sprite[] = [];//找都找了,就全记录吧
for (var i = 0; i < this.children.length; i++) {
if (this.children[i]["imageKey"] == imagekey) {
cs.push(this.children[i])
}
}
if (!cs.length) return;
var texture: Texture = cs[0].texture;
var width = texture.width; var width = texture.width;
var height = texture.height; var height = texture.height;
let image = getCreateImage()(); let image = getCreateImage()();
...@@ -323,16 +322,8 @@ export class MovieClip extends Container { ...@@ -323,16 +322,8 @@ export class MovieClip extends Container {
} }
newTexture = Texture.fromCanvas(canvas) newTexture = Texture.fromCanvas(canvas)
} }
//修改textures指向
// self.textures[imagekey]=Texture.fromCanvas(canvas)
//修改相应sprite //修改相应sprite
for (var i = 0; i < self.children.length; i++) { cs.forEach((c) => { c.texture = newTexture; })
let child = self.children[i]
//texture相等
if (child["imageKey"] == imagekey) {
child.texture = newTexture
}
}
} }
image.src = imageUrl; image.src = imageUrl;
} }
...@@ -703,3 +694,53 @@ export class MovieClip extends Container { ...@@ -703,3 +694,53 @@ export class MovieClip extends Container {
super.destroy(); super.destroy();
} }
} }
/**
* 用源数据拷贝一份,用相应参数
* @param frames 源数据
* @param x 偏移x,默认0
* @param y 偏移y,默认0
* @param scaleX 相对缩放x,默认1
* @param scaleY 相对缩放y,默认1
* @param rotation 相对旋转,角度制,默认0
* @param anchorX 相对锚点x,默认0
* @param anchorY 相对锚点y,默认0
*/
function deepCopyFrames(
frames,
x: number = 0,
y: number = 0,
scaleX: number = 1,
scaleY: number = 1,
rotation: number = 0,
anchorX: number = 0,
anchorY: number = 0
) {
var cf = [];
rotation *= Math.PI / 180;
//@ts-ignore
var lt: Matrix = {};
lt.a = Math.cos(rotation) * scaleX;
lt.b = Math.sin(rotation) * scaleX;
lt.c = -Math.sin(rotation) * scaleY;
lt.d = Math.cos(rotation) * scaleY;
lt.tx = x + anchorX - ((anchorX * lt.a) + (anchorY * lt.c));
lt.ty = y + anchorY - ((anchorX * lt.b) + (anchorY * lt.d));
for (var j = 0; j < frames.length; j++) {
var frame = frames[j];
const pt = frame.transform;
var f = { alpha: 0, transform: null };
//透明度
f.alpha = frame.alpha;
f.transform = {
a: (lt.a * pt.a) + (lt.b * pt.c),
b: (lt.a * pt.b) + (lt.b * pt.d),
c: (lt.c * pt.a) + (lt.d * pt.c),
d: (lt.c * pt.b) + (lt.d * pt.d),
tx: (lt.tx * pt.a) + (lt.ty * pt.c) + pt.tx,
ty: (lt.tx * pt.b) + (lt.ty * pt.d) + pt.ty,
};
cf.push(f)
}
return cf;
}
\ No newline at end of file
import { TextureCache, getCreateImage } from "../../utils";
import { Tween } from "../../../tween";
import { Texture, BaseTexture } from "../../texture";
import { Container, Sprite, DisplayObject } from "../../display";
import { buildBezierProps } from "./buildBezierProps";
import { getBezierEasing } from "./BezierEaser";
interface LottieData {
"fr": number,//珍露 30 60等
"ip": number,//开始帧
"op": number,//结束帧
"w": number,//宽度
"h": number,//高度
"nm": string,//名字
"layers": LayerData[],
"assets"?: {
"id": string,//图片id,与layers里的refId对应
"w": number,
"h": number,
"p": string,//base64数据
}[],
"textures"?: { [key: string]: Texture }//缓存的贴图,为了上面的assets里的图片数据,不进全局缓存,
svgaData?: any //数据生成后存入
}
interface LayerData {
"ind": number,//id唯一
"ty": number,//类型,暂时只有2
"nm": string//"owl_sleep.png",//暂时就是图片
"refId": string,
"parent"?: number,//父级id
"ks": KsData;
"ip": number,//开始帧
"op": number,//结束帧
transformDatas?: TansformData[];
}
interface KsData {
o: KeyData //透明度
r: KeyData //旋转
p: KeyData //位置
a: KeyData //锚点
s: KeyData //缩放
}
interface KeyData {
a: number,
k: KeyAniData[] | number[] | number,
x: string,//可能有表达式
frames?: KeyFrameInt[],//注意根据表达式还要添加
props?: number[][],//记录所有的属性,每一帧的
}
interface KeyAniData {
t: number,
s: number[],
i: { x: number | number[], y: number | number[] },
o: { x: number | number[], y: number | number[] },
to: number[],
ti: number[],
}
/**
* 记录的Tween数据
*/
interface TweenData {
/**
* 属性对象
*/
obj: any,
deltaTime: number,
deltaT: number,
isSet?: boolean,
/**
* 原始帧数据,算pingpong的时间差值用
*/
timeOri?: number,
}
/**
* 每一个属性在总帧数上每个关键点的数据
* 挂在每个层级的的ks的各个属性上,到时直接计算出所有的x,y,sx,sy,r,alpha, ax和ay固定,注意xy都得减axy
* 第一步只处理ks里面的数据
*/
interface KeyFrameInt {
/**
* 数值
*/
value: number[],
/**
* 第几帧
*/
frame: number,
// type: "stay" | "tween",//stay停留不变,到下一个状态时硬切 ,
/**
* 为了计算贝塞尔补间数据 ,有io或toti才有缓动
*/
i?: { x: number | number[], y: number | number[] };
o?: { x: number | number[], y: number | number[] };
/**
* 为了计算贝塞尔补间数据
*/
to?: number[],
ti?: number[],
}
interface TansformData {
alpha: number;
transform: {
a: number,
b: number,
c: number,
d: number,
tx: number,
ty: number,
};
}
//动画总ip必须为0,否则修改
let totalOp: number = 0;
export function handleLottieData(data: LottieData) {
//存一下,全局用
totalOp = data.op;//最后一帧估计不算
//是否需要深拷贝
// data = JSON.parse(JSON.stringify(data))
//最终返回的数据
var videoEntity: any = {};
//一些简单的先设置了
videoEntity.videoSize = {
width: data.w,
height: data.h
}
videoEntity.FPS = data.fr;
videoEntity.frames = data.op - data.ip;
//图片还在的时
if (data.assets) {//注意这时不能把素材干进全局。单独存在自己的数据中
videoEntity.images = {};
data.assets.forEach((a) => {
videoEntity.images[a.id] = a.p.replace("data:image/png;base64,", "")//去掉相同的前缀
})
}
for (var i = 0; i < data.layers.length; i++) {
var layerData = data.layers[i];
var ks = layerData.ks;
//锚点是不变的,先写
var ad: [number, number] = typeof layerData.ks.a.k[0] == "number" ? layerData.ks.a.k : layerData.ks.a.k[0].s;
// ks.a.frames = [{ value: ad, frame: 0 }];
//@ts-ignore
ks.a.props = fillUp(ad);
addFrames(layerData);
}
//开始计算每帧属性,循环每个层级
//开始计算每帧矩阵,注意父级,循环每帧
//sprites最重要的东西,里面有imageKey和frames,TODO
videoEntity.sprites = [];
for (var i = 0; i < data.layers.length; i++) {
var layerData = data.layers[i];
videoEntity.sprites.push({
imageKey: layerData.refId,
frames: layerData.transformDatas
})
}
return videoEntity
}
function addFrames(layerData: LayerData) {
var ks = layerData.ks;
var ip = layerData.ip;
var op = layerData.op;
//@ts-ignore透明度
if (ks.o.k.length) {
addFrame(layerData, "o");
} else {//没有直接取首诊数据,且根据ip op处理显隐 具体怎么处理好点
//@ts-ignore 透明度决定显隐,最后根据ip和op来重新修正alpha 注意ip有可能小于0,op可能大于totalOp,所以注意判断 TODO
var alpha = ks.o.k / 100;
// ks.o.frames = [{ value: alpha, frame: 0 }]
//@ts-ignore
ks.o.props = fillUp(alpha);
}
//@ts-ignore 旋转
if (data.ks.r.k.length) {
addFrame(layerData, "r");
} else {
//@ts-ignore
// ks.r.frames = [{ value: ks.r.k, frame: 0 }]
//@ts-ignore
ks.r.props = fillUp(ks.r.k);
}
//位置,得是对象
if (typeof ks.p.k[0] != "number") {
addFrame(layerData, "p");
} else {
var anchor: [number, number] = typeof ks.a.k[0] == "number" ? ks.a.k : ks.a.k[0].s;
//@ts-ignore
var p = ks.p.k[0].s;
// ks.p.frames = [{ value: [p[0] - anchor[0], p[1] - anchor[1]], frame: 0 }]
//@ts-ignore
ks.p.props = fillUp([p[0] - anchor[0], p[1] - anchor[1]]);
}
//缩放
if (typeof ks.s.k[0] != "number") {
addFrame(layerData, "s");
} else {
//@ts-ignore
var s = ks.s.k[0].s;
// ks.s.frames = [{ value: [s[0] / 100, s[1] / 100], frame: 0 }]
//@ts-ignore
ks.s.props = fillUp([s[0] / 100, s[1] / 100]);
}
}
function addFrame(layerData: LayerData, type: "o" | "r" | "p" | "s") {
//@ts-ignore
var data: KeyAniData[] = layerData.ks[type].k;
var ip = layerData.ip; //有小于0的情况
var op = layerData.op; //有大于totalOp的情况
var ks = layerData.ks;
var anchor: [number, number] = typeof ks.a.k[0] == "number" ? ks.a.k : ks.a.k[0].s;
var frames: KeyFrameInt[] = [];
var props: number[][] = ks[type].props = [];
for (let i = 0; i < data.length; i++) {
let d = data[i];
frames.push({
i: d.i, o: d.o, ti: d.ti, to: d.to,
value: getValue(d.s, type, anchor),
frame: d.t
})
}
//有表达式的
if (ks[type].x) {
var xs = ks[type].x;
//取数字
var rr = +xs.replace(/[^0-9]/ig, "");
}
//没表达式的,前后有空的,用前后数据补,小于0的不用,超过totalOp的不用
else {
for (var i = 0; i < frames.length - 1; i++) {//最后一个数据不用
let f = frames[i], nextF = frames[i + 1];
if (f.to) {
//把函数也传进去吧,用来处理
var fnc = getBezierEasing(f.o.x, f.o.y, f.i.x, f.i.y).get;
buildBezierProps(
f.value,
nextF.value,
f.to,
f.ti,
f.frame,
nextF.frame,
props,
fnc,
totalOp
);
}
}
}
}
/**
* 默认数据
* @param type
*/
function createDefaultFrame(type: "o" | "r" | "p" | "s") {
if (type == "p") {
return { value: [0, 0], frame: 0 }
}
if (type == "s") {
return { value: [1, 1], frame: 0 }
}
return { value: 0, frame: 0 }
}
function getValue(s: number[], type: "r" | "o" | "s" | "p", anchor?: [number, number]) {
let value;
switch (type) {
case "r":
value = [s[0]];
break;
case "o":
value = [s[0] / 100];
break;
case "s":
value = [s[0] / 100, s[1] / 100]
break;
case "p":
value = [s[0] - anchor[0], s[1] - anchor[1]]
break;
}
return value;
}
function fillUp(value: number | [number, number]) {
return Array(...Array(totalOp)).map((a, i) => value);
}
/**
* 用Tween拼,后续计算帧数据记录
* 临时写的,真尼玛乱得很,以后再说
*/
export class Lottie extends Container {
/**
* 原始数据,尽量只获取,不修改
*/
private rawData: LottieData;
/**
* 总帧数
*/
get totalFrames(): number {
return this.rawData && (this.rawData.op - this.rawData.ip);
};
/**
* 锁步的时间间隔,按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
constructor(data) {
super()
this._instanceType = "Lottie";
//初始化
if (data) {
this.init(data);
}
// else {
// this.totalFrames = 0;
// }
}
/**
* 暂时不考虑重复init
* @param data
*/
init(data: LottieData) {
if (!data) return
this.rawData = data;
this.timeInterval = 1000 / data.fr;
// this.totalFrames = data.op - data.ip
//间隔帧数,
this.deltaFrame = 60 / data.fr;
this.name = data.nm;
//初始化图片 有assets但无textures
if (data.assets && !data.textures) {//带图片数据的待测试
data.textures = {};
data.assets.forEach((a) => {
let imgTag = getCreateImage()();
imgTag.src = a.p;
data.textures[a.id] = new Texture(new BaseTexture(imgTag));
})
}
this.initChildren();
}
private initChildren() {
//初始化内容吧,假设所有资源已经加载好额
var layers = this.rawData.layers.slice();
//先筛选出所有不带parents,说明是顶级容器
for (var i = layers.length - 1; i >= 0; i--) {
let layer = layers[i];
// if (!layer.refId) console.log(layer)
let c = this.addChild(new Sprite(
// RES.getRes(layer.nm) ||
layer.refId ?
this.rawData.textures ?
this.rawData.textures[layer.refId] :
TextureCache[layer.refId] ||
TextureCache[layer.refId + ".png"] : null
));
//记录一下数据
c["layerData"] = layer;
}
this.initState()
}
private initState(con = this.children) {
for (var i = 0; i < con.length; i++) {
var c: 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] / 100 : data.ks.o.k / 100;
// c.alpha = c.alpha === 0.01 ? 1 : c.alpha;
//@ts-ignore 选转
c.rotation = data.ks.r.k[0] ? data.ks.r.k[0].s[0] : data.ks.r.k;
//锚点,用贴图锚点
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)
//如果入场不在的
c.visible = data.ip <= 0
// if (data.ip > 0) {
// c.visible = false
// } else {
// c.visible = true
// }
}
if (c.children.length) this.initState(c.children)
}
}
/**
* 为了那啥 修改 loop默认0
*/
play(loop: number = 0, callback?: () => void) {
// this.initState();
this.stop(true);//需要回到初始状态再开始
this.loops = loop;
this.callback = callback;
this.addTweens();
}
/**
* 移除所有的Tween,临时方法
* @param isReset 是否回到初始状态,默认否
*/
stop(isReset: boolean = false) {
//tween要去掉
Tween.removeTweens(this)
this.children.forEach((c) => { Tween.removeTweens(c) })
isReset && this.initState();
}
private addTweens(con = this.children) {
for (var i = 0; i < con.length; i++) {
let c: 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");
//显示隐藏统一这里处理,还有个循环的,如何计算显示隐藏再说
var t = Tween.get(c, { loop: true })
if (data.ip > 0 || data.op < this.rawData.op) {
var aa = data.ip < 0 ? 0 : data.ip;
var bb = data.op > this.rawData.op ? this.rawData.op : data.op
t.wait(aa * this.timeInterval)
.call(() => { c.visible = true; })
.wait((bb - aa) * this.timeInterval)
.call(() => { c.visible = false; })
.wait((this.rawData.op - bb) * this.timeInterval)
}
}
//其实不会有
if (c.children.length) this.addTweens(c.children)
}
//考虑回调
Tween.get(this, { loop: true })
.wait((this.rawData.op - this.rawData.ip) * this.timeInterval)
.call(() => {
if (--this.loops == 0) {
this.stop();
this.callback && this.callback();
}
})
}
/**
* 来吧重写,,。专干loopOut和loopIn
* @param dis
* @param type
*/
private addTween(dis: DisplayObject, type: "r" | "o" | "s" | "p") {
const data: { "t": number, "s": number[] }[] = dis["layerData"].ks[type].k
let tween = Tween.get(dis, { loop: true })
let countTime = 0;
//有表达式的,先随便写,到时整理
if (dis["layerData"].ks[type].x) {
var xs = dis["layerData"].ks[type].x;
//取数字
var rr = +xs.replace(/[^0-9]/ig, "");
//loopOut后续循环,补齐从最后一个数据的t到dis["layerData"].op的间隔,不足一个的情况需要单独计算
if (xs.indexOf("loopOut") >= 0) {
//先走完一次整的,反正补后面的
let objArr: { obj: any, deltaTime: number, deltaT: number, isSet?: boolean }[] = [];
let curT = 0;
for (let i = 0; i < data.length; i++) {
let d = data[i];
//如果超过op的
if (d.t > dis["layerData"].op) break;
let deltaT = d.t - curT;
let deltaTime = deltaT * this.timeInterval;
let obj = getTweenObj(d);
//如果第一帧不是0,需要等待
if (i == 0 && d.t > 0) {
tween.wait(deltaTime)
countTime += deltaTime
// console.log("asdffff",countALL,d.t)
//需加set,但是时间0,暂时别加吧,tween会自行记录初始值
// objArr.push({ obj, deltaT:0, deltaTime:0, isSet: true })
}
//从0开始,但是t为0,用set
else if (i == 0 && d.t == 0) { //考虑下是否需要,deltaTime也是0
tween.set(obj);
objArr.push({ obj, deltaT, deltaTime, isSet: true })
} else {
//一帧当作set
if (d.t - curT == 1) {
tween.wait(deltaTime)
.set(obj);
objArr.push({ obj, deltaT, deltaTime, isSet: true })
countTime += deltaTime
// console.log("asdff",countALL)
} else {
tween.to(obj, deltaTime);
objArr.push({ obj, deltaT, deltaTime })
countTime += deltaTime
// console.log("asdff",countALL)
}
}
//赋值
curT = d.t;
}
// if (dis["layerData"].ind == "1") console.log(45445456, objArr)
// console.log("asdf",countALL)
//pingpong先不考虑次数,还没遇到
if (xs.indexOf("pingpong") >= 0 && data[data.length - 1].t < dis["layerData"].op) {
// Math.floor((dis["layerData"].op - data[0].t))
var round = Math.round(
(dis["layerData"].op - data[data.length - 1].t) /
(data[data.length - 1].t - data[0].t) //不一定所有
)
curT += round * (data[data.length - 1].t - data[0].t) //不一定所有
var dir = false;
while (--round) {
if (dir) {
for (var o = 0; o < objArr.length; o++) {
tween.to(objArr[o].obj, objArr[o].deltaTime);
countTime += objArr[o].deltaTime;
}
} else {
for (var o = objArr.length - 1; o >= 1; o--) {
tween.to(objArr[o - 1].obj, objArr[o].deltaTime);
countTime += objArr[o].deltaTime;
}
}
dir = !dir;
}
}
//循环,先floor,多余的重走一次,估计不能用dis["layerData"].op,得用this.rawData.op,loopOut到时也得单独计算
else if (xs.indexOf("cycle") >= 0 && data[data.length - 1].t < dis["layerData"].op) {
var lastIndex = data.length - 1;
var num = Math.floor(
(dis["layerData"].op - data[lastIndex].t) /
(data[lastIndex].t - data[lastIndex - (rr || lastIndex)].t)
);
// console.log("asd",num,data[lastIndex].t - data[lastIndex - (rr || lastIndex)].t)
//取一部分
let objArrC = objArr.slice(-rr);
while (num) {
num--;
//补满
for (var o = 0; o < objArrC.length; o++) {
if (objArrC[o].isSet) {
tween.wait(objArrC[o].deltaTime)
.set(objArrC[o].obj);
} else {
tween.to(objArrC[o].obj, objArrC[o].deltaTime);
}
countTime += objArrC[o].deltaTime
}
}
// console.log("asd",countALL)
//补剩下的,跑一部分
var left = (dis["layerData"].op - data[lastIndex].t) % (data[lastIndex].t - data[lastIndex - (rr || lastIndex)].t);
// if(dis["layerData"].ind=="1") console.log(45445456,left)
for (var o = 0; o < objArrC.length; o++) {
if (objArrC[o].deltaT <= left) {
if (objArrC[o].isSet) {
tween.wait(objArrC[o].deltaTime)
.set(objArrC[o].obj);
} else {
tween.to(objArrC[o].obj, objArrC[o].deltaTime);
}
left -= objArrC[o].deltaT
countTime += objArrC[o].deltaTime
} else {
if (left > 0) {//这种情况不会是set,再调吧,这样算补间有问题
// console.log(o,left, objArrC.length)
// if(o == 0)console.log(left, objArrC[o].deltaT)
var ooo = o == 0 ?
calculateInterpolation(
/*objArrC[0].obj,*/ copyProps(objArrC[o].obj, tween["_initQueueProps"]),//初始值用tween记录的
objArrC[o].obj,
left / objArrC[o].deltaT
) : calculateInterpolation(
objArrC[o - 1].obj,
objArrC[o].obj,
left / objArrC[o].deltaT
)
tween.to(
ooo,
left * this.timeInterval
);
countTime += left * this.timeInterval
// console.log(countALL)
}
break;
}
}
}
}
//前面循环,先取所有的tween序列,初始状态要改
else if (xs.indexOf("loopIn") >= 0) {
let objArr: TweenData[] = [];
let curT = 0;
for (let i = 0; i < data.length; i++) {
let d = data[i];
//不能去掉,有可能需要用到
// if (d.t > dis["layerData"].op) break;
let deltaT = d.t - curT;
let deltaTime = deltaT * this.timeInterval;
let obj = getTweenObj(d);
//一帧当作set
if (d.t - curT == 1) {
objArr.push({ obj, deltaT, deltaTime, isSet: true, timeOri: d.t })
} else {
objArr.push({ obj, deltaT, deltaTime, timeOri: d.t })
}
//赋值
curT = d.t;
}
//pingpong再loopIn暂时没有,用到时再写,还真尼玛下个就是
if (xs.indexOf("pingpong") >= 0 && data[0].t > 0) {
objArr = getLoopInPingpongTween(objArr, rr, dis["layerData"].op)
// if (dis["layerData"].ind == 8) console.log("asdf", objArr);
for (var o = 0; o < objArr.length; o++) {
// if (dis["layerData"].ind == 8) console.log("asdf", objArrC[o]);
if (objArr[o].isSet) {
tween.wait(objArr[o].deltaTime)
.set(objArr[o].obj);
} else {
tween.to(objArr[o].obj, objArr[o].deltaTime);
}
countTime += objArr[o].deltaTime
}
}
//循环,其实应该用dis["layerData"].ip判断
else if (xs.indexOf("cycle") >= 0 && data[0].t > 0) {//不考虑不整的,直接从0开始,算出整的,然后自然过度到最后一个
//可能入场的时间不能算
// if (dis["layerData"].ip > 0) tween.wait(dis["layerData"].ip * this.timeInterval)
objArr = getLoopInCycleTween(objArr, rr, dis["layerData"].op, dis["layerData"].ip);
if (dis["layerData"].ip) {
// console.log(5464,dis["layerData"].ip,countTime)
tween.wait(dis["layerData"].ip * this.timeInterval)//以后改
countTime += dis["layerData"].ip * this.timeInterval
}
for (var o = 0; o < objArr.length; o++) {
if (objArr[o].isSet) {
tween.wait(objArr[o].deltaTime)
.set(objArr[o].obj);
} else {
tween.to(objArr[o].obj, objArr[o].deltaTime);
}
countTime += objArr[o].deltaTime
}
}
// if (dis["layerData"].ind == 1) console.log("asd", countTime);
//多余的时间
var op = Math.min(dis["layerData"].op, this.rawData.op)
if (countTime < op * this.timeInterval) {
var dd = op * this.timeInterval - countTime;
tween.wait(dd)
countTime += dd
}
// console.log(countTime)
// if (dis["layerData"].ind == 1) console.log("asde", countTime);
}
//还有一部分 dis["layerData"].op 到 this.rawData.op
if (dis["layerData"].op < this.rawData.op) {
tween.wait((this.rawData.op - dis["layerData"].op) * this.timeInterval)
countTime += (this.rawData.op - dis["layerData"].op) * this.timeInterval
}
//查看所有时间
// console.log(countTime)
}
//没表达式的,用wait补满前面的和后面的
else {
let curT = 0;
for (let i = 0; i < data.length; i++) {
let d = data[i],
obj = getTweenObj(d),
deltaTime;
//判断是否小于0,小于0需要和下一帧算补间
if (d.t < 0) {
//下一帧不存在或也小于0
if (!data[i + 1] || data[i + 1].t < 0) break;
obj = calculateInterpolation(
obj,
getTweenObj(data[i + 1]),
-d.t / (data[i + 1].t - d.t)
);
// if (d.t == -35) console.log(123)
tween.set(obj);
curT = 0;
}
//如果超过op的,和上一帧算补间
else if (d.t > this.rawData.op) {
if (!data[i - 1] || data[i - 1].t > this.rawData.op) break;
let dt = this.rawData.op - data[i - 1].t;
deltaTime = dt * this.timeInterval;
obj = calculateInterpolation(
getTweenObj(data[i - 1]),
obj,
dt / (d.t - data[i - 1].t)
);
// if (dis["layerData"].ind == 7) console.log(999, d.t, data[i - 1].t, getTweenObj(data[i - 1]), obj)
tween.to(obj, deltaTime);
//累计时间
countTime += deltaTime;
//没必要记了。最后一帧了
curT = this.rawData.op;
}
else {
deltaTime = (d.t - curT) * this.timeInterval
//如果第一帧不是0,需要等待
if (i == 0 && d.t > 0) {
tween.wait(deltaTime)
}
//从0开始,但是t为0,用set
else if (i == 0 && d.t == 0) {
tween.set(obj);
} else {
tween.to(obj, deltaTime);
}
countTime += deltaTime
//赋值
curT = d.t;
}
}
//考虑还有部分时间,等待
if (this.rawData.op > curT) {
tween.wait((this.rawData.op - curT) * this.timeInterval)
}
}
// console.log(countTime)
//结束的操作
// tween.call(() => {
// if (--this.loops == 0) {
// this.stop();
// this.callback && this.callback();
// }
// })
/**
* type和dis主参数里取
* @param d 循环里取
*/
function getTweenObj(d: { "t": number; "s": number[] }) {
let obj;
switch (type) {
case "r":
obj = { rotation: d.s[0] }
break;
case "o":
obj = { alpha: d.s[0] / 100 }
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;
}
return obj;
}
}
/**
* 对所有的进行刷新,,根据cParent进行迭代刷新
* 层级有问题,只能平铺,手动计算矩阵
* 因为要平铺,所以记录cParent和ind 从1开始,也许只需要+1就行,还是用ind记录查找吧
* 遍历找
*/
updateTransform() {
//super不行,到时查
this.displayObjectUpdateTransform();
this.children.forEach((c) => {
this._recursivePostUpdateTransformAA(c);
})
this.children.forEach((c) => {
c.mark = false;
})
}
private findChildByInd(ind: number) {
for (var i = 0; i < this.children.length; i++) {
if (this.children[i].layerData &&
this.children[i].layerData.ind === ind
) return this.children[i]
}
return null
}
private _recursivePostUpdateTransformAA(c) {
if (c.layerData && c.layerData.parent) {
//ind从1开始,所以不用考虑0,且不应该存在 p没有的情况
var p = this.findChildByInd(c.layerData.parent)
this._recursivePostUpdateTransformAA(p);
if (!c.mark) {
c.mark = true;
c.transform.updateWorldMatrix(p.transform);
//透明度单独计算,不跟cParent保持
c._worldAlpha = c.alpha * c.parent._worldAlpha;
}
}
//直接进行tans
else if (!c.mark) {
c.updateTransform();//alpha跟父级有关
c.mark = true
}
}
/**
* 加个方法,前两个参数都没用,为了一头牛
* @param beginFrame
* @param endFrame
* @param loops
* @param callback
*/
public startAniRange(
beginFrame: number = 1,
endFrame: number = this.totalFrames,
loops: number = 1,
callback?: () => void
) {
this.play(loops, callback)
}
destroy() {
//tween要去掉
this.children.forEach((c) => { Tween.removeTweens(c) })
super.destroy();
}
}
function calculateInterpolation(
d1: any,
d2: any,
scale: number //时间比例 t/(t2-t1)
) {
let obj = {};
// for (let key in d1) obj[key] = Math.abs(d1[key] - d2[key]) * scale + d1[key]
//之前为何要加绝对值
for (let key in d1) obj[key] = (d2[key] - d1[key]) * scale + d1[key]
return obj
}
/**
* 返回一个带obj里所有的key的对象,但是key值为sObj里的
* @param obj 取里面的key
* @param sObj 取里面的key值
*/
function copyProps(obj, sObj) {
var o = {};
if (!obj) return o;
for (let key in obj) o[key] = sObj[key];
return o;
}
/**
* 以后可能还会改,以后整理吧,以后可能要计算补间,现在先不管
* @param objArr
* @param time 第一帧的时间间隔
* @param round 循环索引
*/
function getLoopInCycleTween(objArr: TweenData[], round: number, op: number, ip: number = 0) {
var time = objArr[0].deltaT - ip;//以后算插值时再说
//这样是否合理,也可能是objArrC的length下标,超出一个
if (round >= objArr.length) round = 0;
var objArrC = objArr.slice(0, round ? round + 1 : objArr.length)
// var lastDeltaT = objArrC[objArrC.length - 1].deltaT;
// if (objArrC.length > 2) {//如果长度大于2,首帧和尾帧是一致的,默认,所以不取最后一帧
// //去掉最后一帧
// objArrC.pop();
// }
// console.log(objArrC.length, objArr.length)
var tweenArr: TweenData[] = [];
var curIndex = 0;
while (time > 0) {
curIndex--;
//超出就是最后一帧
if (curIndex < 0) curIndex = objArrC.length - 1;
//第0帧是set
if (!curIndex) {
tweenArr.unshift({
obj: objArrC[0].obj,
deltaT: 0,
deltaTime: 0,
timeOri: objArrC[0].timeOri,
isSet: true
})
}
//其他的都是终点
else {
tweenArr.unshift(objArrC[curIndex])
time -= objArrC[curIndex].deltaT
}
}
//第一帧加上
tweenArr.unshift({
obj: objArrC[0].obj,
deltaT: 0,
deltaTime: 0,
timeOri: objArrC[0].timeOri,
isSet: true
})
//把剩下的,第一项要变成set,再加后面的所有
tweenArr.push({
obj: objArrC[0].obj,
deltaT: 0,
deltaTime: 0,
isSet: true
})
for (var i = 1; i < objArr.length; i++) {
if (objArr[i].timeOri > op) break;
tweenArr.push(objArr[i]);
}
// console.log(tweenArr)
return tweenArr
}
function getLoopInCycleTween11(objArr: TweenData[], time: number, round: number) {
//这样是否合理,也可能是objArrC的length下标,超出一个
if (round >= objArr.length) round = 0;
var lastDeltaT = objArr[round || objArr.length - 1].deltaT;
var lastDeltaTime = objArr[round || objArr.length - 1].deltaTime;
objArr[0].deltaT = lastDeltaT;
objArr[0].deltaTime = lastDeltaTime;
var objArrC = objArr.slice(0, round || objArr.length)
var tweenArr: TweenData[] = [];
var curT = 0;
//从0开始,一般就是初始未知,不做任何处理,不考虑插值
for (var i = 1; i < objArrC.length; i++) {
tweenArr.push(objArrC[i]);//不做拷贝应该也没事
curT += objArrC[i].deltaT;
}
time -= curT;
while (time > lastDeltaT) {
for (var i = 0; i < objArrC.length; i++) {
tweenArr.push(objArrC[i]);//不做拷贝应该也没事
time -= objArrC[i].deltaT
}
}
//接上最后一组
tweenArr = tweenArr.concat(objArr)
return tweenArr
}
/**
* pingpong的,取首尾相接的循环
* @param objArr
* @param time
* @param round
*/
function getLoopInPingpongTween(objArr: TweenData[], round: number, op: number) {
var time = objArr[0].deltaT;
if (round >= objArr.length) round = 0;
var objArrC = objArr.slice(0, round ? round + 1 : objArr.length)
var timeInterval = objArr[0].deltaTime / objArr[0].deltaT;
// var allTime = 0;
// objArrC.forEach((o, i) => { if (i != 0) allTime += o.deltaT })
var tweenArr: TweenData[] = [];
var dir: boolean = true// = (time / allTime) % 2 == 0;
var curIndex = 0;
var lastIndex = 0;
while (time > 0) {
dir ? curIndex++ : curIndex--;
//如果超了,就反向
if (curIndex > objArrC.length - 1) {
dir = false;
curIndex -= 2
}
else if (curIndex < 0) {
dir = true;
curIndex += 2
}
var deltaT = Math.abs(objArrC[lastIndex].timeOri - objArrC[curIndex].timeOri);
tweenArr.unshift({
obj: objArrC[lastIndex].obj,
deltaT,
deltaTime: deltaT * timeInterval,
timeOri: objArrC[lastIndex].timeOri,
isSet: objArrC[lastIndex].isSet
})
lastIndex = curIndex;
time -= deltaT
}
//塞入
tweenArr.unshift({
obj: objArrC[lastIndex].obj,
deltaT: 0,
deltaTime: 0,
timeOri: objArrC[lastIndex].timeOri,
isSet: true
})
//把剩下的,除了第一项不要
//得考虑超出的op
for (var i = 1; i < objArr.length; i++) {
if (objArr[i].timeOri > op) break;
tweenArr.push(objArr[i]);
}
// objArr.forEach((o, i) => {
// if (i) tweenArr.push(o)
// })
return tweenArr
}
\ No newline at end of file
import { getBezierEasing } from "./BezierEaser";
export function buildBezierEaserProps(
startValue: number[],
endValue: number[],
outV,
inV,
startIndex: number,
endIndex: number,
points,
useH:boolean,
limit?: number
) {
if(useH){
for (var k = startIndex; k < endIndex; k++) {//这时不算最后一个
points[k] = startValue.slice();
}
return
}
var outX, outY, inX, inY, keyValue, perc;
var len = startValue.length;
var fncts, fnc;
if (outV.x.constructor === Array) {
fncts = [];
for (var i = 0; i < len; i++) {
outX = (typeof outV.x[i] === 'undefined') ? outV.x[0] : outV.x[i];
outY = (typeof outV.y[i] === 'undefined') ? outV.y[0] : outV.y[i];
inX = (typeof inV.x[i] === 'undefined') ? inV.x[0] : inV.x[i];
inY = (typeof inV.y[i] === 'undefined') ? inV.y[0] : inV.y[i];
fncts[i] = getBezierEasing(outX, outY, inX, inY).get;
}
} else {
outX = outV.x;
outY = outV.y;
inX = inV.x;
inY = inV.y;
fnc = getBezierEasing(outX, outY, inX, inY).get;
}
var delta = endIndex - startIndex
for (var k = startIndex; k <= endIndex; k++) {
if (limit) {
//小于0的不算了,浪费时间
if (k < 0) continue;
//超出的也不要了
if (k >= limit) break;//遇到那种
}
var frameNum = k;
var newValue = [];
for (var i = 0; i < len; i += 1) {
if (frameNum == endIndex) {
perc = 1;
} else if (frameNum == startIndex) {
perc = 0;
} else {
if (fncts) {
perc = fncts[i]((frameNum - startIndex) / delta);
} else {
perc = fnc((frameNum - startIndex) / delta);
}
}
keyValue = startValue[i] + (endValue[i] - startValue[i]) * perc;
newValue[i] = keyValue;
}
points[k] = newValue
}
}
\ No newline at end of file
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
export function buildBezierProps(pt1, pt2, pt3, pt4, startIndex, endIndex, points, fnc, limit?: number) { export function buildBezierProps(pt1, pt2, pt3, pt4, startIndex, endIndex, points, fnc, limit?: number) {
var bezierData = buildBezierData(pt1, pt2, pt3, pt4); var bezierData = buildBezierData(pt1, pt2, pt3, pt4);
//处理完所有的点 //处理完所有的点
for (var i = startIndex; i < endIndex; i++) { for (var i = startIndex; i <= endIndex; i++) {
if (limit) { if (limit) {
//小于0的不算了,浪费时间 //小于0的不算了,浪费时间
if (i < 0) continue; if (i < 0) continue;
...@@ -16,6 +16,10 @@ export function buildBezierProps(pt1, pt2, pt3, pt4, startIndex, endIndex, point ...@@ -16,6 +16,10 @@ export function buildBezierProps(pt1, pt2, pt3, pt4, startIndex, endIndex, point
points[i] = bezierData.points[0].point; points[i] = bezierData.points[0].point;
continue; continue;
} }
if (perc == 1) {
points[i] = bezierData.points[bezierData.points.length - 1].point;
continue;
}
//找最近的点 //找最近的点
points[i] = findNearest(distanceInLine, bezierData.points); points[i] = findNearest(distanceInLine, bezierData.points);
} }
......
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