235 lines
5.4 KiB
JavaScript
235 lines
5.4 KiB
JavaScript
|
var util = require("./core/util");
|
|||
|
|
|||
|
var _config = require("./config");
|
|||
|
|
|||
|
var devicePixelRatio = _config.devicePixelRatio;
|
|||
|
|
|||
|
var Style = require("./graphic/Style");
|
|||
|
|
|||
|
var Pattern = require("./graphic/Pattern");
|
|||
|
|
|||
|
/**
|
|||
|
* @module zrender/Layer
|
|||
|
* @author pissang(https://www.github.com/pissang)
|
|||
|
*/
|
|||
|
function returnFalse() {
|
|||
|
return false;
|
|||
|
}
|
|||
|
/**
|
|||
|
* 创建dom
|
|||
|
*
|
|||
|
* @inner
|
|||
|
* @param {string} id dom id 待用
|
|||
|
* @param {Painter} painter painter instance
|
|||
|
* @param {number} number
|
|||
|
*/
|
|||
|
|
|||
|
|
|||
|
function createDom(id, painter, dpr) {
|
|||
|
var newDom = util.createCanvas();
|
|||
|
var width = painter.getWidth();
|
|||
|
var height = painter.getHeight();
|
|||
|
var newDomStyle = newDom.style;
|
|||
|
|
|||
|
if (newDomStyle) {
|
|||
|
// In node or some other non-browser environment
|
|||
|
newDomStyle.position = 'absolute';
|
|||
|
newDomStyle.left = 0;
|
|||
|
newDomStyle.top = 0;
|
|||
|
newDomStyle.width = width + 'px';
|
|||
|
newDomStyle.height = height + 'px';
|
|||
|
newDom.setAttribute('data-zr-dom-id', id);
|
|||
|
}
|
|||
|
|
|||
|
newDom.width = width * dpr;
|
|||
|
newDom.height = height * dpr;
|
|||
|
return newDom;
|
|||
|
}
|
|||
|
/**
|
|||
|
* @alias module:zrender/Layer
|
|||
|
* @constructor
|
|||
|
* @extends module:zrender/mixin/Transformable
|
|||
|
* @param {string} id
|
|||
|
* @param {module:zrender/Painter} painter
|
|||
|
* @param {number} [dpr]
|
|||
|
*/
|
|||
|
|
|||
|
|
|||
|
var Layer = function (id, painter, dpr) {
|
|||
|
var dom;
|
|||
|
dpr = dpr || devicePixelRatio;
|
|||
|
|
|||
|
if (typeof id === 'string') {
|
|||
|
dom = createDom(id, painter, dpr);
|
|||
|
} // Not using isDom because in node it will return false
|
|||
|
else if (util.isObject(id)) {
|
|||
|
dom = id;
|
|||
|
id = dom.id;
|
|||
|
}
|
|||
|
|
|||
|
this.id = id;
|
|||
|
this.dom = dom;
|
|||
|
var domStyle = dom.style;
|
|||
|
|
|||
|
if (domStyle) {
|
|||
|
// Not in node
|
|||
|
dom.onselectstart = returnFalse; // 避免页面选中的尴尬
|
|||
|
|
|||
|
domStyle['-webkit-user-select'] = 'none';
|
|||
|
domStyle['user-select'] = 'none';
|
|||
|
domStyle['-webkit-touch-callout'] = 'none';
|
|||
|
domStyle['-webkit-tap-highlight-color'] = 'rgba(0,0,0,0)';
|
|||
|
domStyle['padding'] = 0; // eslint-disable-line dot-notation
|
|||
|
|
|||
|
domStyle['margin'] = 0; // eslint-disable-line dot-notation
|
|||
|
|
|||
|
domStyle['border-width'] = 0;
|
|||
|
}
|
|||
|
|
|||
|
this.domBack = null;
|
|||
|
this.ctxBack = null;
|
|||
|
this.painter = painter;
|
|||
|
this.config = null; // Configs
|
|||
|
|
|||
|
/**
|
|||
|
* 每次清空画布的颜色
|
|||
|
* @type {string}
|
|||
|
* @default 0
|
|||
|
*/
|
|||
|
|
|||
|
this.clearColor = 0;
|
|||
|
/**
|
|||
|
* 是否开启动态模糊
|
|||
|
* @type {boolean}
|
|||
|
* @default false
|
|||
|
*/
|
|||
|
|
|||
|
this.motionBlur = false;
|
|||
|
/**
|
|||
|
* 在开启动态模糊的时候使用,与上一帧混合的alpha值,值越大尾迹越明显
|
|||
|
* @type {number}
|
|||
|
* @default 0.7
|
|||
|
*/
|
|||
|
|
|||
|
this.lastFrameAlpha = 0.7;
|
|||
|
/**
|
|||
|
* Layer dpr
|
|||
|
* @type {number}
|
|||
|
*/
|
|||
|
|
|||
|
this.dpr = dpr;
|
|||
|
};
|
|||
|
|
|||
|
Layer.prototype = {
|
|||
|
constructor: Layer,
|
|||
|
__dirty: true,
|
|||
|
__used: false,
|
|||
|
__drawIndex: 0,
|
|||
|
__startIndex: 0,
|
|||
|
__endIndex: 0,
|
|||
|
incremental: false,
|
|||
|
getElementCount: function () {
|
|||
|
return this.__endIndex - this.__startIndex;
|
|||
|
},
|
|||
|
initContext: function () {
|
|||
|
this.ctx = this.dom.getContext('2d');
|
|||
|
this.ctx.dpr = this.dpr;
|
|||
|
},
|
|||
|
createBackBuffer: function () {
|
|||
|
var dpr = this.dpr;
|
|||
|
this.domBack = createDom('back-' + this.id, this.painter, dpr);
|
|||
|
this.ctxBack = this.domBack.getContext('2d');
|
|||
|
|
|||
|
if (dpr !== 1) {
|
|||
|
this.ctxBack.scale(dpr, dpr);
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
/**
|
|||
|
* @param {number} width
|
|||
|
* @param {number} height
|
|||
|
*/
|
|||
|
resize: function (width, height) {
|
|||
|
var dpr = this.dpr;
|
|||
|
var dom = this.dom;
|
|||
|
var domStyle = dom.style;
|
|||
|
var domBack = this.domBack;
|
|||
|
|
|||
|
if (domStyle) {
|
|||
|
domStyle.width = width + 'px';
|
|||
|
domStyle.height = height + 'px';
|
|||
|
}
|
|||
|
|
|||
|
dom.width = width * dpr;
|
|||
|
dom.height = height * dpr;
|
|||
|
|
|||
|
if (domBack) {
|
|||
|
domBack.width = width * dpr;
|
|||
|
domBack.height = height * dpr;
|
|||
|
|
|||
|
if (dpr !== 1) {
|
|||
|
this.ctxBack.scale(dpr, dpr);
|
|||
|
}
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
/**
|
|||
|
* 清空该层画布
|
|||
|
* @param {boolean} [clearAll]=false Clear all with out motion blur
|
|||
|
* @param {Color} [clearColor]
|
|||
|
*/
|
|||
|
clear: function (clearAll, clearColor) {
|
|||
|
var dom = this.dom;
|
|||
|
var ctx = this.ctx;
|
|||
|
var width = dom.width;
|
|||
|
var height = dom.height;
|
|||
|
var clearColor = clearColor || this.clearColor;
|
|||
|
var haveMotionBLur = this.motionBlur && !clearAll;
|
|||
|
var lastFrameAlpha = this.lastFrameAlpha;
|
|||
|
var dpr = this.dpr;
|
|||
|
|
|||
|
if (haveMotionBLur) {
|
|||
|
if (!this.domBack) {
|
|||
|
this.createBackBuffer();
|
|||
|
}
|
|||
|
|
|||
|
this.ctxBack.globalCompositeOperation = 'copy';
|
|||
|
this.ctxBack.drawImage(dom, 0, 0, width / dpr, height / dpr);
|
|||
|
}
|
|||
|
|
|||
|
ctx.clearRect(0, 0, width, height);
|
|||
|
|
|||
|
if (clearColor && clearColor !== 'transparent') {
|
|||
|
var clearColorGradientOrPattern; // Gradient
|
|||
|
|
|||
|
if (clearColor.colorStops) {
|
|||
|
// Cache canvas gradient
|
|||
|
clearColorGradientOrPattern = clearColor.__canvasGradient || Style.getGradient(ctx, clearColor, {
|
|||
|
x: 0,
|
|||
|
y: 0,
|
|||
|
width: width,
|
|||
|
height: height
|
|||
|
});
|
|||
|
clearColor.__canvasGradient = clearColorGradientOrPattern;
|
|||
|
} // Pattern
|
|||
|
else if (clearColor.image) {
|
|||
|
clearColorGradientOrPattern = Pattern.prototype.getCanvasPattern.call(clearColor, ctx);
|
|||
|
}
|
|||
|
|
|||
|
ctx.save();
|
|||
|
ctx.fillStyle = clearColorGradientOrPattern || clearColor;
|
|||
|
ctx.fillRect(0, 0, width, height);
|
|||
|
ctx.restore();
|
|||
|
}
|
|||
|
|
|||
|
if (haveMotionBLur) {
|
|||
|
var domBack = this.domBack;
|
|||
|
ctx.save();
|
|||
|
ctx.globalAlpha = lastFrameAlpha;
|
|||
|
ctx.drawImage(domBack, 0, 0, width, height);
|
|||
|
ctx.restore();
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
var _default = Layer;
|
|||
|
module.exports = _default;
|