Merge branch 'master' into 91_canvas_paint_operations_optimization
diff --git a/player/js/elements/canvasElements/CVContextData.js b/player/js/elements/canvasElements/CVContextData.js
index f5d8b93..88df6fa 100644
--- a/player/js/elements/canvasElements/CVContextData.js
+++ b/player/js/elements/canvasElements/CVContextData.js
@@ -3,28 +3,57 @@
} from '../../utils/helpers/arrays';
import Matrix from '../../3rd_party/transformation-matrix';
+function CanvasContext() {
+ this.opacity = -1;
+ this.transform = createTypedArray('float32', 16);
+ this.fillStyle = '';
+ this.strokeStyle = '';
+ this.lineWidth = '';
+ this.lineCap = '';
+ this.lineJoin = '';
+ this.miterLimit = '';
+ this.id = Math.random();
+}
+
function CVContextData() {
- this.saved = [];
+ this.stack = [];
this.cArrPos = 0;
this.cTr = new Matrix();
- this.cO = 1;
var i;
var len = 15;
- this.savedOp = createTypedArray('float32', len);
for (i = 0; i < len; i += 1) {
- this.saved[i] = createTypedArray('float32', 16);
+ var canvasContext = new CanvasContext();
+ this.stack[i] = canvasContext;
}
this._length = len;
+ this.nativeContext = null;
+ this.transformMat = new Matrix();
+ this.currentOpacity = 1;
+ //
+ this.currentFillStyle = '';
+ this.appliedFillStyle = '';
+ //
+ this.currentStrokeStyle = '';
+ this.appliedStrokeStyle = '';
+ //
+ this.currentLineWidth = '';
+ this.appliedLineWidth = '';
+ //
+ this.currentLineCap = '';
+ this.appliedLineCap = '';
+ //
+ this.currentLineJoin = '';
+ this.appliedLineJoin = '';
+ //
+ this.appliedMiterLimit = '';
+ this.currentMiterLimit = '';
}
CVContextData.prototype.duplicate = function () {
var newLength = this._length * 2;
- var currentSavedOp = this.savedOp;
- this.savedOp = createTypedArray('float32', newLength);
- this.savedOp.set(currentSavedOp);
var i = 0;
for (i = this._length; i < newLength; i += 1) {
- this.saved[i] = createTypedArray('float32', 16);
+ this.stack[i] = new CanvasContext();
}
this._length = newLength;
};
@@ -32,59 +61,179 @@
CVContextData.prototype.reset = function () {
this.cArrPos = 0;
this.cTr.reset();
- this.cO = 1;
+ this.stack[this.cArrPos].opacity = 1;
};
-CVContextData.prototype.popTransform = function () {
- var popped = this.saved[this.cArrPos];
+CVContextData.prototype.restore = function (forceRestore) {
+ this.cArrPos -= 1;
+ var currentContext = this.stack[this.cArrPos];
+ var transform = currentContext.transform;
var i;
var arr = this.cTr.props;
for (i = 0; i < 16; i += 1) {
- arr[i] = popped[i];
+ arr[i] = transform[i];
}
- return popped;
+ if (forceRestore) {
+ this.nativeContext.restore();
+ var prevStack = this.stack[this.cArrPos + 1];
+ this.appliedFillStyle = prevStack.fillStyle;
+ this.appliedStrokeStyle = prevStack.strokeStyle;
+ this.appliedLineWidth = prevStack.lineWidth;
+ this.appliedLineCap = prevStack.lineCap;
+ this.appliedLineJoin = prevStack.lineJoin;
+ this.appliedMiterLimit = prevStack.miterLimit;
+ }
+ this.nativeContext.setTransform(transform[0], transform[1], transform[4], transform[5], transform[12], transform[13]);
+ if (forceRestore || (currentContext.opacity !== -1 && this.currentOpacity !== currentContext.opacity)) {
+ this.nativeContext.globalAlpha = currentContext.opacity;
+ this.currentOpacity = currentContext.opacity;
+ }
+ this.currentFillStyle = currentContext.fillStyle;
+ this.currentStrokeStyle = currentContext.strokeStyle;
+ this.currentLineWidth = currentContext.lineWidth;
+ this.currentLineCap = currentContext.lineCap;
+ this.currentLineJoin = currentContext.lineJoin;
+ this.currentMiterLimit = currentContext.miterLimit;
};
-CVContextData.prototype.popOpacity = function () {
- var popped = this.savedOp[this.cArrPos];
- this.cO = popped;
- return popped;
-};
-
-CVContextData.prototype.pop = function () {
- this.cArrPos -= 1;
- var transform = this.popTransform();
- var opacity = this.popOpacity();
- return {
- transform: transform,
- opacity: opacity,
- };
-};
-
-CVContextData.prototype.push = function () {
+CVContextData.prototype.save = function (saveOnNativeFlag) {
+ if (saveOnNativeFlag) {
+ this.nativeContext.save();
+ }
var props = this.cTr.props;
if (this._length <= this.cArrPos) {
this.duplicate();
}
+
+ var currentStack = this.stack[this.cArrPos];
var i;
- var arr = this.saved[this.cArrPos];
for (i = 0; i < 16; i += 1) {
- arr[i] = props[i];
+ currentStack.transform[i] = props[i];
}
- this.savedOp[this.cArrPos] = this.cO;
this.cArrPos += 1;
-};
-
-CVContextData.prototype.getTransform = function () {
- return this.cTr;
-};
-
-CVContextData.prototype.getOpacity = function () {
- return this.cO;
+ var newStack = this.stack[this.cArrPos];
+ newStack.opacity = currentStack.opacity;
+ newStack.fillStyle = currentStack.fillStyle;
+ newStack.strokeStyle = currentStack.strokeStyle;
+ newStack.lineWidth = currentStack.lineWidth;
+ newStack.lineCap = currentStack.lineCap;
+ newStack.lineJoin = currentStack.lineJoin;
+ newStack.miterLimit = currentStack.miterLimit;
};
CVContextData.prototype.setOpacity = function (value) {
- this.cO = value;
+ this.stack[this.cArrPos].opacity = value;
+};
+
+CVContextData.prototype.setContext = function (value) {
+ this.nativeContext = value;
+};
+
+CVContextData.prototype.fillStyle = function (value) {
+ if (this.stack[this.cArrPos].fillStyle !== value) {
+ this.currentFillStyle = value;
+ this.stack[this.cArrPos].fillStyle = value;
+ }
+};
+
+CVContextData.prototype.strokeStyle = function (value) {
+ if (this.stack[this.cArrPos].strokeStyle !== value) {
+ this.currentStrokeStyle = value;
+ this.stack[this.cArrPos].strokeStyle = value;
+ }
+};
+
+CVContextData.prototype.lineWidth = function (value) {
+ if (this.stack[this.cArrPos].lineWidth !== value) {
+ this.currentLineWidth = value;
+ this.stack[this.cArrPos].lineWidth = value;
+ }
+};
+
+CVContextData.prototype.lineCap = function (value) {
+ if (this.stack[this.cArrPos].lineCap !== value) {
+ this.currentLineCap = value;
+ this.stack[this.cArrPos].lineCap = value;
+ }
+};
+
+CVContextData.prototype.lineJoin = function (value) {
+ if (this.stack[this.cArrPos].lineJoin !== value) {
+ this.currentLineJoin = value;
+ this.stack[this.cArrPos].lineJoin = value;
+ }
+};
+
+CVContextData.prototype.miterLimit = function (value) {
+ if (this.stack[this.cArrPos].miterLimit !== value) {
+ this.currentMiterLimit = value;
+ this.stack[this.cArrPos].miterLimit = value;
+ }
+};
+
+CVContextData.prototype.transform = function (props) {
+ this.transformMat.cloneFromProps(props);
+ // Taking the last transform value from the stored stack of transforms
+ var currentTransform = this.cTr;
+ // Applying the last transform value after the new transform to respect the order of transformations
+ this.transformMat.multiply(currentTransform);
+ // Storing the new transformed value in the stored transform
+ currentTransform.cloneFromProps(this.transformMat.props);
+ var trProps = currentTransform.props;
+ // Applying the new transform to the canvas
+ this.nativeContext.setTransform(trProps[0], trProps[1], trProps[4], trProps[5], trProps[12], trProps[13]);
+};
+
+CVContextData.prototype.opacity = function (op) {
+ var currentOpacity = this.stack[this.cArrPos].opacity;
+ currentOpacity *= op < 0 ? 0 : op;
+ if (this.stack[this.cArrPos].opacity !== currentOpacity) {
+ if (this.currentOpacity !== op) {
+ this.nativeContext.globalAlpha = op;
+ this.currentOpacity = op;
+ }
+ this.stack[this.cArrPos].opacity = currentOpacity;
+ }
+};
+
+CVContextData.prototype.fill = function (rule) {
+ if (this.appliedFillStyle !== this.currentFillStyle) {
+ this.appliedFillStyle = this.currentFillStyle;
+ this.nativeContext.fillStyle = this.appliedFillStyle;
+ }
+ this.nativeContext.fill(rule);
+};
+
+CVContextData.prototype.fillRect = function (x, y, w, h) {
+ if (this.appliedFillStyle !== this.currentFillStyle) {
+ this.appliedFillStyle = this.currentFillStyle;
+ this.nativeContext.fillStyle = this.appliedFillStyle;
+ }
+ this.nativeContext.fillRect(x, y, w, h);
+};
+
+CVContextData.prototype.stroke = function () {
+ if (this.appliedStrokeStyle !== this.currentStrokeStyle) {
+ this.appliedStrokeStyle = this.currentStrokeStyle;
+ this.nativeContext.strokeStyle = this.appliedStrokeStyle;
+ }
+ if (this.appliedLineWidth !== this.currentLineWidth) {
+ this.appliedLineWidth = this.currentLineWidth;
+ this.nativeContext.lineWidth = this.appliedLineWidth;
+ }
+ if (this.appliedLineCap !== this.currentLineCap) {
+ this.appliedLineCap = this.currentLineCap;
+ this.nativeContext.lineCap = this.appliedLineCap;
+ }
+ if (this.appliedLineJoin !== this.currentLineJoin) {
+ this.appliedLineJoin = this.currentLineJoin;
+ this.nativeContext.lineJoin = this.appliedLineJoin;
+ }
+ if (this.appliedMiterLimit !== this.currentMiterLimit) {
+ this.appliedMiterLimit = this.currentMiterLimit;
+ this.nativeContext.miterLimit = this.appliedMiterLimit;
+ }
+ this.nativeContext.stroke();
};
export default CVContextData;
diff --git a/player/js/elements/canvasElements/CVShapeElement.js b/player/js/elements/canvasElements/CVShapeElement.js
index f37cf51..3217bf5 100644
--- a/player/js/elements/canvasElements/CVShapeElement.js
+++ b/player/js/elements/canvasElements/CVShapeElement.js
@@ -295,13 +295,19 @@
renderer.save();
elems = currentStyle.elements;
if (type === 'st' || type === 'gs') {
- ctx.strokeStyle = type === 'st' ? currentStyle.co : currentStyle.grd;
- ctx.lineWidth = currentStyle.wi;
- ctx.lineCap = currentStyle.lc;
- ctx.lineJoin = currentStyle.lj;
- ctx.miterLimit = currentStyle.ml || 0;
+ renderer.ctxStrokeStyle(type === 'st' ? currentStyle.co : currentStyle.grd);
+ // ctx.strokeStyle = type === 'st' ? currentStyle.co : currentStyle.grd;
+ renderer.ctxLineWidth(currentStyle.wi);
+ // ctx.lineWidth = currentStyle.wi;
+ renderer.ctxLineCap(currentStyle.lc);
+ // ctx.lineCap = currentStyle.lc;
+ renderer.ctxLineJoin(currentStyle.lj);
+ // ctx.lineJoin = currentStyle.lj;
+ renderer.ctxMiterLimit(currentStyle.ml || 0);
+ // ctx.miterLimit = currentStyle.ml || 0;
} else {
- ctx.fillStyle = type === 'fl' ? currentStyle.co : currentStyle.grd;
+ renderer.ctxFillStyle(type === 'fl' ? currentStyle.co : currentStyle.grd);
+ // ctx.fillStyle = type === 'fl' ? currentStyle.co : currentStyle.grd;
}
renderer.ctxOpacity(currentStyle.coOp);
if (type !== 'st' && type !== 'gs') {
@@ -330,14 +336,16 @@
}
}
if (type === 'st' || type === 'gs') {
- ctx.stroke();
+ // ctx.stroke();
+ renderer.ctxStroke();
if (currentStyle.da) {
ctx.setLineDash(this.dashResetter);
}
}
}
if (type !== 'st' && type !== 'gs') {
- ctx.fill(currentStyle.r);
+ // ctx.fill(currentStyle.r);
+ this.globalData.renderer.ctxFill(currentStyle.r);
}
renderer.restore();
}
diff --git a/player/js/elements/canvasElements/CVSolidElement.js b/player/js/elements/canvasElements/CVSolidElement.js
index 61eadd8..23e0d98 100644
--- a/player/js/elements/canvasElements/CVSolidElement.js
+++ b/player/js/elements/canvasElements/CVSolidElement.js
@@ -19,9 +19,11 @@
CVSolidElement.prototype.prepareFrame = IImageElement.prototype.prepareFrame;
CVSolidElement.prototype.renderInnerContent = function () {
- var ctx = this.canvasContext;
- ctx.fillStyle = this.data.sc;
- ctx.fillRect(0, 0, this.data.sw, this.data.sh);
+ // var ctx = this.canvasContext;
+ this.globalData.renderer.ctxFillStyle(this.data.sc);
+ // ctx.fillStyle = this.data.sc;
+ this.globalData.renderer.ctxFillRect(0, 0, this.data.sw, this.data.sh);
+ // ctx.fillRect(0, 0, this.data.sw, this.data.sh);
//
};
diff --git a/player/js/elements/canvasElements/CVTextElement.js b/player/js/elements/canvasElements/CVTextElement.js
index b815e84..52ef05e 100644
--- a/player/js/elements/canvasElements/CVTextElement.js
+++ b/player/js/elements/canvasElements/CVTextElement.js
@@ -130,9 +130,12 @@
this.validateText();
var ctx = this.canvasContext;
ctx.font = this.values.fValue;
- ctx.lineCap = 'butt';
- ctx.lineJoin = 'miter';
- ctx.miterLimit = 4;
+ this.globalData.renderer.ctxLineCap('butt');
+ // ctx.lineCap = 'butt';
+ this.globalData.renderer.ctxLineJoin('miter');
+ // ctx.lineJoin = 'miter';
+ this.globalData.renderer.ctxMiterLimit(4);
+ // ctx.miterLimit = 4;
if (!this.data.singleShape) {
this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
@@ -155,23 +158,26 @@
var lastStrokeW = null;
var commands;
var pathArr;
+ var renderer = this.globalData.renderer;
for (i = 0; i < len; i += 1) {
if (!letters[i].n) {
renderedLetter = renderedLetters[i];
if (renderedLetter) {
- this.globalData.renderer.save();
- this.globalData.renderer.ctxTransform(renderedLetter.p);
- this.globalData.renderer.ctxOpacity(renderedLetter.o);
+ renderer.save();
+ renderer.ctxTransform(renderedLetter.p);
+ renderer.ctxOpacity(renderedLetter.o);
}
if (this.fill) {
if (renderedLetter && renderedLetter.fc) {
if (lastFill !== renderedLetter.fc) {
+ renderer.ctxFillStyle(renderedLetter.fc);
lastFill = renderedLetter.fc;
- ctx.fillStyle = renderedLetter.fc;
+ // ctx.fillStyle = renderedLetter.fc;
}
} else if (lastFill !== this.values.fill) {
lastFill = this.values.fill;
- ctx.fillStyle = this.values.fill;
+ renderer.ctxFillStyle(this.values.fill);
+ // ctx.fillStyle = this.values.fill;
}
commands = this.textSpans[i].elem;
jLen = commands.length;
@@ -185,27 +191,32 @@
}
}
this.globalData.canvasContext.closePath();
- this.globalData.canvasContext.fill();
+ renderer.ctxFill();
+ // this.globalData.canvasContext.fill();
/// ctx.fillText(this.textSpans[i].val,0,0);
}
if (this.stroke) {
if (renderedLetter && renderedLetter.sw) {
if (lastStrokeW !== renderedLetter.sw) {
lastStrokeW = renderedLetter.sw;
- ctx.lineWidth = renderedLetter.sw;
+ renderer.ctxLineWidth(renderedLetter.sw);
+ // ctx.lineWidth = renderedLetter.sw;
}
} else if (lastStrokeW !== this.values.sWidth) {
lastStrokeW = this.values.sWidth;
- ctx.lineWidth = this.values.sWidth;
+ renderer.ctxLineWidth(this.values.sWidth);
+ // ctx.lineWidth = this.values.sWidth;
}
if (renderedLetter && renderedLetter.sc) {
if (lastStroke !== renderedLetter.sc) {
lastStroke = renderedLetter.sc;
- ctx.strokeStyle = renderedLetter.sc;
+ renderer.ctxStrokeStyle(renderedLetter.sc);
+ // ctx.strokeStyle = renderedLetter.sc;
}
} else if (lastStroke !== this.values.stroke) {
lastStroke = this.values.stroke;
- ctx.strokeStyle = this.values.stroke;
+ renderer.ctxStrokeStyle(this.values.stroke);
+ // ctx.strokeStyle = this.values.stroke;
}
commands = this.textSpans[i].elem;
jLen = commands.length;
@@ -219,7 +230,8 @@
}
}
this.globalData.canvasContext.closePath();
- this.globalData.canvasContext.stroke();
+ renderer.ctxStroke();
+ // this.globalData.canvasContext.stroke();
/// ctx.strokeText(letters[i].val,0,0);
}
if (renderedLetter) {
diff --git a/player/js/renderers/CanvasRenderer.js b/player/js/renderers/CanvasRenderer.js
index 231d06f..0a7c988 100644
--- a/player/js/renderers/CanvasRenderer.js
+++ b/player/js/renderers/CanvasRenderer.js
@@ -36,6 +36,20 @@
this.transformMat = new Matrix();
this.completeLayers = false;
this.rendererType = 'canvas';
+ if (this.renderConfig.clearCanvas) {
+ this.ctxTransform = this.contextData.transform.bind(this.contextData);
+ this.ctxOpacity = this.contextData.opacity.bind(this.contextData);
+ this.ctxFillStyle = this.contextData.fillStyle.bind(this.contextData);
+ this.ctxStrokeStyle = this.contextData.strokeStyle.bind(this.contextData);
+ this.ctxLineWidth = this.contextData.lineWidth.bind(this.contextData);
+ this.ctxLineCap = this.contextData.lineCap.bind(this.contextData);
+ this.ctxLineJoin = this.contextData.lineJoin.bind(this.contextData);
+ this.ctxMiterLimit = this.contextData.miterLimit.bind(this.contextData);
+ this.ctxFill = this.contextData.fill.bind(this.contextData);
+ this.ctxFillRect = this.contextData.fillRect.bind(this.contextData);
+ this.ctxStroke = this.contextData.stroke.bind(this.contextData);
+ this.save = this.contextData.save.bind(this.contextData);
+ }
}
extendPrototype([CanvasRendererBase], CanvasRenderer);
diff --git a/player/js/renderers/CanvasRendererBase.js b/player/js/renderers/CanvasRendererBase.js
index 6c801ec..dd199f5 100644
--- a/player/js/renderers/CanvasRendererBase.js
+++ b/player/js/renderers/CanvasRendererBase.js
@@ -6,43 +6,13 @@
} from '../utils/helpers/arrays';
import createTag from '../utils/helpers/html_elements';
import SVGRenderer from './SVGRenderer';
-import Matrix from '../3rd_party/transformation-matrix';
import BaseRenderer from './BaseRenderer';
-import CVContextData from '../elements/canvasElements/CVContextData';
import CVShapeElement from '../elements/canvasElements/CVShapeElement';
import CVTextElement from '../elements/canvasElements/CVTextElement';
import CVImageElement from '../elements/canvasElements/CVImageElement';
import CVSolidElement from '../elements/canvasElements/CVSolidElement';
-function CanvasRendererBase(animationItem, config) {
- this.animationItem = animationItem;
- this.renderConfig = {
- clearCanvas: (config && config.clearCanvas !== undefined) ? config.clearCanvas : true,
- context: (config && config.context) || null,
- progressiveLoad: (config && config.progressiveLoad) || false,
- preserveAspectRatio: (config && config.preserveAspectRatio) || 'xMidYMid meet',
- imagePreserveAspectRatio: (config && config.imagePreserveAspectRatio) || 'xMidYMid slice',
- contentVisibility: (config && config.contentVisibility) || 'visible',
- className: (config && config.className) || '',
- id: (config && config.id) || '',
- };
- this.renderConfig.dpr = (config && config.dpr) || 1;
- if (this.animationItem.wrapper) {
- this.renderConfig.dpr = (config && config.dpr) || window.devicePixelRatio || 1;
- }
- this.renderedFrame = -1;
- this.globalData = {
- frameNum: -1,
- _mdf: false,
- renderConfig: this.renderConfig,
- currentGlobalAlpha: -1,
- };
- this.contextData = new CVContextData();
- this.elements = [];
- this.pendingElements = [];
- this.transformMat = new Matrix();
- this.completeLayers = false;
- this.rendererType = 'canvas';
+function CanvasRendererBase() {
}
extendPrototype([BaseRenderer], CanvasRendererBase);
@@ -68,39 +38,47 @@
if (props[0] === 1 && props[1] === 0 && props[4] === 0 && props[5] === 1 && props[12] === 0 && props[13] === 0) {
return;
}
- if (!this.renderConfig.clearCanvas) {
- this.canvasContext.transform(props[0], props[1], props[4], props[5], props[12], props[13]);
- return;
- }
- // Resetting the canvas transform matrix to the new transform
- this.transformMat.cloneFromProps(props);
- // Taking the last transform value from the stored stack of transforms
- var currentTransform = this.contextData.getTransform();
- // Applying the last transform value after the new transform to respect the order of transformations
- this.transformMat.multiply(currentTransform);
- // Storing the new transformed value in the stored transform
- currentTransform.cloneFromProps(this.transformMat.props);
- var trProps = currentTransform.props;
- // Applying the new transform to the canvas
- this.canvasContext.setTransform(trProps[0], trProps[1], trProps[4], trProps[5], trProps[12], trProps[13]);
+ this.canvasContext.transform(props[0], props[1], props[4], props[5], props[12], props[13]);
};
CanvasRendererBase.prototype.ctxOpacity = function (op) {
- /* if(op === 1){
- return;
- } */
- var currentOpacity = this.contextData.getOpacity();
- if (!this.renderConfig.clearCanvas) {
- this.canvasContext.globalAlpha *= op < 0 ? 0 : op;
- this.globalData.currentGlobalAlpha = currentOpacity;
- return;
- }
- currentOpacity *= op < 0 ? 0 : op;
- this.contextData.setOpacity(currentOpacity);
- if (this.globalData.currentGlobalAlpha !== currentOpacity) {
- this.canvasContext.globalAlpha = currentOpacity;
- this.globalData.currentGlobalAlpha = currentOpacity;
- }
+ this.canvasContext.globalAlpha *= op < 0 ? 0 : op;
+};
+
+CanvasRendererBase.prototype.ctxFillStyle = function (value) {
+ this.canvasContext.fillStyle = value;
+};
+
+CanvasRendererBase.prototype.ctxStrokeStyle = function (value) {
+ this.canvasContext.strokeStyle = value;
+};
+
+CanvasRendererBase.prototype.ctxLineWidth = function (value) {
+ this.canvasContext.lineWidth = value;
+};
+
+CanvasRendererBase.prototype.ctxLineCap = function (value) {
+ this.canvasContext.lineCap = value;
+};
+
+CanvasRendererBase.prototype.ctxLineJoin = function (value) {
+ this.canvasContext.lineJoin = value;
+};
+
+CanvasRendererBase.prototype.ctxMiterLimit = function (value) {
+ this.canvasContext.miterLimit = value;
+};
+
+CanvasRendererBase.prototype.ctxFill = function (rule) {
+ this.canvasContext.fill(rule);
+};
+
+CanvasRendererBase.prototype.ctxFillRect = function (x, y, w, h) {
+ this.canvasContext.fillRect(x, y, w, h);
+};
+
+CanvasRendererBase.prototype.ctxStroke = function () {
+ this.canvasContext.stroke();
};
CanvasRendererBase.prototype.reset = function () {
@@ -111,15 +89,8 @@
this.contextData.reset();
};
-CanvasRendererBase.prototype.save = function (actionFlag) {
- if (!this.renderConfig.clearCanvas) {
- this.canvasContext.save();
- return;
- }
- if (actionFlag) {
- this.canvasContext.save();
- }
- this.contextData.push();
+CanvasRendererBase.prototype.save = function () {
+ this.canvasContext.save();
};
CanvasRendererBase.prototype.restore = function (actionFlag) {
@@ -128,17 +99,9 @@
return;
}
if (actionFlag) {
- this.canvasContext.restore();
this.globalData.blendMode = 'source-over';
}
- var popped = this.contextData.pop();
- var transform = popped.transform;
- var opacity = popped.opacity;
- this.canvasContext.setTransform(transform[0], transform[1], transform[4], transform[5], transform[12], transform[13]);
- if (this.globalData.currentGlobalAlpha !== opacity) {
- this.canvasContext.globalAlpha = opacity;
- this.globalData.currentGlobalAlpha = opacity;
- }
+ this.contextData.restore(actionFlag);
};
CanvasRendererBase.prototype.configAnimation = function (animData) {
@@ -164,6 +127,7 @@
} else {
this.canvasContext = this.renderConfig.context;
}
+ this.contextData.setContext(this.canvasContext);
this.data = animData;
this.layers = animData.layers;
this.transformCanvas = {
@@ -300,7 +264,7 @@
this.checkLayers(num);
}
- for (i = 0; i < len; i += 1) {
+ for (i = len - 1; i >= 0; i -= 1) {
if (this.completeLayers || this.elements[i]) {
this.elements[i].prepareFrame(num - this.layers[i].st);
}