You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
297 lines
11 KiB
297 lines
11 KiB
import { __extends } from "tslib"; |
|
import * as util from '../core/util.js'; |
|
import { devicePixelRatio } from '../config.js'; |
|
import Eventful from '../core/Eventful.js'; |
|
import { getCanvasGradient } from './helper.js'; |
|
import { createCanvasPattern } from './graphic.js'; |
|
import BoundingRect from '../core/BoundingRect.js'; |
|
import { REDRAW_BIT } from '../graphic/constants.js'; |
|
import { platformApi } from '../core/platform.js'; |
|
function createDom(id, painter, dpr) { |
|
var newDom = platformApi.createCanvas(); |
|
var width = painter.getWidth(); |
|
var height = painter.getHeight(); |
|
var newDomStyle = newDom.style; |
|
if (newDomStyle) { |
|
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; |
|
} |
|
; |
|
var Layer = (function (_super) { |
|
__extends(Layer, _super); |
|
function Layer(id, painter, dpr) { |
|
var _this = _super.call(this) || this; |
|
_this.motionBlur = false; |
|
_this.lastFrameAlpha = 0.7; |
|
_this.dpr = 1; |
|
_this.virtual = false; |
|
_this.config = {}; |
|
_this.incremental = false; |
|
_this.zlevel = 0; |
|
_this.maxRepaintRectCount = 5; |
|
_this.__dirty = true; |
|
_this.__firstTimePaint = true; |
|
_this.__used = false; |
|
_this.__drawIndex = 0; |
|
_this.__startIndex = 0; |
|
_this.__endIndex = 0; |
|
_this.__prevStartIndex = null; |
|
_this.__prevEndIndex = null; |
|
var dom; |
|
dpr = dpr || devicePixelRatio; |
|
if (typeof id === 'string') { |
|
dom = createDom(id, painter, dpr); |
|
} |
|
else if (util.isObject(id)) { |
|
dom = id; |
|
id = dom.id; |
|
} |
|
_this.id = id; |
|
_this.dom = dom; |
|
var domStyle = dom.style; |
|
if (domStyle) { |
|
util.disableUserSelect(dom); |
|
dom.onselectstart = function () { return false; }; |
|
domStyle.padding = '0'; |
|
domStyle.margin = '0'; |
|
domStyle.borderWidth = '0'; |
|
} |
|
_this.painter = painter; |
|
_this.dpr = dpr; |
|
return _this; |
|
} |
|
Layer.prototype.getElementCount = function () { |
|
return this.__endIndex - this.__startIndex; |
|
}; |
|
Layer.prototype.afterBrush = function () { |
|
this.__prevStartIndex = this.__startIndex; |
|
this.__prevEndIndex = this.__endIndex; |
|
}; |
|
Layer.prototype.initContext = function () { |
|
this.ctx = this.dom.getContext('2d'); |
|
this.ctx.dpr = this.dpr; |
|
}; |
|
Layer.prototype.setUnpainted = function () { |
|
this.__firstTimePaint = true; |
|
}; |
|
Layer.prototype.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); |
|
} |
|
}; |
|
Layer.prototype.createRepaintRects = function (displayList, prevList, viewWidth, viewHeight) { |
|
if (this.__firstTimePaint) { |
|
this.__firstTimePaint = false; |
|
return null; |
|
} |
|
var mergedRepaintRects = []; |
|
var maxRepaintRectCount = this.maxRepaintRectCount; |
|
var full = false; |
|
var pendingRect = new BoundingRect(0, 0, 0, 0); |
|
function addRectToMergePool(rect) { |
|
if (!rect.isFinite() || rect.isZero()) { |
|
return; |
|
} |
|
if (mergedRepaintRects.length === 0) { |
|
var boundingRect = new BoundingRect(0, 0, 0, 0); |
|
boundingRect.copy(rect); |
|
mergedRepaintRects.push(boundingRect); |
|
} |
|
else { |
|
var isMerged = false; |
|
var minDeltaArea = Infinity; |
|
var bestRectToMergeIdx = 0; |
|
for (var i = 0; i < mergedRepaintRects.length; ++i) { |
|
var mergedRect = mergedRepaintRects[i]; |
|
if (mergedRect.intersect(rect)) { |
|
var pendingRect_1 = new BoundingRect(0, 0, 0, 0); |
|
pendingRect_1.copy(mergedRect); |
|
pendingRect_1.union(rect); |
|
mergedRepaintRects[i] = pendingRect_1; |
|
isMerged = true; |
|
break; |
|
} |
|
else if (full) { |
|
pendingRect.copy(rect); |
|
pendingRect.union(mergedRect); |
|
var aArea = rect.width * rect.height; |
|
var bArea = mergedRect.width * mergedRect.height; |
|
var pendingArea = pendingRect.width * pendingRect.height; |
|
var deltaArea = pendingArea - aArea - bArea; |
|
if (deltaArea < minDeltaArea) { |
|
minDeltaArea = deltaArea; |
|
bestRectToMergeIdx = i; |
|
} |
|
} |
|
} |
|
if (full) { |
|
mergedRepaintRects[bestRectToMergeIdx].union(rect); |
|
isMerged = true; |
|
} |
|
if (!isMerged) { |
|
var boundingRect = new BoundingRect(0, 0, 0, 0); |
|
boundingRect.copy(rect); |
|
mergedRepaintRects.push(boundingRect); |
|
} |
|
if (!full) { |
|
full = mergedRepaintRects.length >= maxRepaintRectCount; |
|
} |
|
} |
|
} |
|
for (var i = this.__startIndex; i < this.__endIndex; ++i) { |
|
var el = displayList[i]; |
|
if (el) { |
|
var shouldPaint = el.shouldBePainted(viewWidth, viewHeight, true, true); |
|
var prevRect = el.__isRendered && ((el.__dirty & REDRAW_BIT) || !shouldPaint) |
|
? el.getPrevPaintRect() |
|
: null; |
|
if (prevRect) { |
|
addRectToMergePool(prevRect); |
|
} |
|
var curRect = shouldPaint && ((el.__dirty & REDRAW_BIT) || !el.__isRendered) |
|
? el.getPaintRect() |
|
: null; |
|
if (curRect) { |
|
addRectToMergePool(curRect); |
|
} |
|
} |
|
} |
|
for (var i = this.__prevStartIndex; i < this.__prevEndIndex; ++i) { |
|
var el = prevList[i]; |
|
var shouldPaint = el.shouldBePainted(viewWidth, viewHeight, true, true); |
|
if (el && (!shouldPaint || !el.__zr) && el.__isRendered) { |
|
var prevRect = el.getPrevPaintRect(); |
|
if (prevRect) { |
|
addRectToMergePool(prevRect); |
|
} |
|
} |
|
} |
|
var hasIntersections; |
|
do { |
|
hasIntersections = false; |
|
for (var i = 0; i < mergedRepaintRects.length;) { |
|
if (mergedRepaintRects[i].isZero()) { |
|
mergedRepaintRects.splice(i, 1); |
|
continue; |
|
} |
|
for (var j = i + 1; j < mergedRepaintRects.length;) { |
|
if (mergedRepaintRects[i].intersect(mergedRepaintRects[j])) { |
|
hasIntersections = true; |
|
mergedRepaintRects[i].union(mergedRepaintRects[j]); |
|
mergedRepaintRects.splice(j, 1); |
|
} |
|
else { |
|
j++; |
|
} |
|
} |
|
i++; |
|
} |
|
} while (hasIntersections); |
|
this._paintRects = mergedRepaintRects; |
|
return mergedRepaintRects; |
|
}; |
|
Layer.prototype.debugGetPaintRects = function () { |
|
return (this._paintRects || []).slice(); |
|
}; |
|
Layer.prototype.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); |
|
} |
|
} |
|
}; |
|
Layer.prototype.clear = function (clearAll, clearColor, repaintRects) { |
|
var dom = this.dom; |
|
var ctx = this.ctx; |
|
var width = dom.width; |
|
var height = dom.height; |
|
clearColor = clearColor || this.clearColor; |
|
var haveMotionBLur = this.motionBlur && !clearAll; |
|
var lastFrameAlpha = this.lastFrameAlpha; |
|
var dpr = this.dpr; |
|
var self = this; |
|
if (haveMotionBLur) { |
|
if (!this.domBack) { |
|
this.createBackBuffer(); |
|
} |
|
this.ctxBack.globalCompositeOperation = 'copy'; |
|
this.ctxBack.drawImage(dom, 0, 0, width / dpr, height / dpr); |
|
} |
|
var domBack = this.domBack; |
|
function doClear(x, y, width, height) { |
|
ctx.clearRect(x, y, width, height); |
|
if (clearColor && clearColor !== 'transparent') { |
|
var clearColorGradientOrPattern = void 0; |
|
if (util.isGradientObject(clearColor)) { |
|
var shouldCache = clearColor.global || (clearColor.__width === width |
|
&& clearColor.__height === height); |
|
clearColorGradientOrPattern = shouldCache |
|
&& clearColor.__canvasGradient |
|
|| getCanvasGradient(ctx, clearColor, { |
|
x: 0, |
|
y: 0, |
|
width: width, |
|
height: height |
|
}); |
|
clearColor.__canvasGradient = clearColorGradientOrPattern; |
|
clearColor.__width = width; |
|
clearColor.__height = height; |
|
} |
|
else if (util.isImagePatternObject(clearColor)) { |
|
clearColor.scaleX = clearColor.scaleX || dpr; |
|
clearColor.scaleY = clearColor.scaleY || dpr; |
|
clearColorGradientOrPattern = createCanvasPattern(ctx, clearColor, { |
|
dirty: function () { |
|
self.setUnpainted(); |
|
self.__painter.refresh(); |
|
} |
|
}); |
|
} |
|
ctx.save(); |
|
ctx.fillStyle = clearColorGradientOrPattern || clearColor; |
|
ctx.fillRect(x, y, width, height); |
|
ctx.restore(); |
|
} |
|
if (haveMotionBLur) { |
|
ctx.save(); |
|
ctx.globalAlpha = lastFrameAlpha; |
|
ctx.drawImage(domBack, x, y, width, height); |
|
ctx.restore(); |
|
} |
|
} |
|
; |
|
if (!repaintRects || haveMotionBLur) { |
|
doClear(0, 0, width, height); |
|
} |
|
else if (repaintRects.length) { |
|
util.each(repaintRects, function (rect) { |
|
doClear(rect.x * dpr, rect.y * dpr, rect.width * dpr, rect.height * dpr); |
|
}); |
|
} |
|
}; |
|
return Layer; |
|
}(Eventful)); |
|
export default Layer;
|
|
|