前端初始化

This commit is contained in:
“hsc”
2026-08-21 15:36:24 +08:00
commit e4d8ecde13
14411 changed files with 2275932 additions and 0 deletions
+79
View File
@@ -0,0 +1,79 @@
import * as util from '../core/util';
import { ImagePatternObject } from '../graphic/Pattern';
import CanvasPainter from './Painter';
import { GradientObject } from '../graphic/Gradient';
import { IncrementalId, ZLevel, ZLevel2 } from '../core/types';
import Eventful from '../core/Eventful';
import Element, { ElementEventCallback } from '../Element';
import Displayable from '../graphic/Displayable';
import BoundingRect from '../core/BoundingRect';
export declare function isIncrementalLayer(layer: Layer): boolean;
export interface LayerConfig {
clearColor?: string | GradientObject | ImagePatternObject;
motionBlur?: boolean;
lastFrameAlpha?: number;
}
export interface LayerDrawCursor {
key: IncrementalId;
used: boolean;
drawIdx: number;
notClearIdx: number;
startIdx: number;
endIdx: number;
endIdxNew: number;
first: Element['id'];
last: Element['id'];
}
declare type LayerDrawCursorStartEnd = Pick<LayerDrawCursor, 'startIdx' | 'endIdx'>;
export default class Layer extends Eventful {
id: string;
dom: HTMLCanvasElement;
domBack: HTMLCanvasElement;
ctx: CanvasRenderingContext2D;
ctxBack: CanvasRenderingContext2D;
painter: CanvasPainter;
clearColor: string | GradientObject | ImagePatternObject;
motionBlur: boolean;
lastFrameAlpha: number;
dpr: number;
virtual: boolean;
config: {};
zlevel: ZLevel;
zlevel2: ZLevel2;
maxRepaintRectCount: number;
private _paintRects;
__dirty: boolean;
__firstTimePaint: boolean;
__cursorStack: IncrementalId[];
__cursors: util.HashMap<LayerDrawCursor, IncrementalId>;
__prevIdx: LayerDrawCursorStartEnd;
__builtin__: boolean;
constructor(id: string | HTMLCanvasElement, painter: CanvasPainter, dpr?: number);
afterBrush(): void;
initContext(): void;
setUnpainted(): void;
createBackBuffer(): void;
createRepaintRects(displayList: Displayable[], prevList: Displayable[], viewWidth: number, viewHeight: number): BoundingRect[];
debugGetPaintRects(): BoundingRect[];
resize(width: number, height: number): void;
clear(clearAll?: boolean, clearColor?: string | GradientObject | ImagePatternObject, repaintRects?: BoundingRect[]): void;
refresh: (clearColor?: string | GradientObject | ImagePatternObject) => void;
renderToCanvas: (ctx: CanvasRenderingContext2D) => void;
onclick: ElementEventCallback<unknown, this>;
ondblclick: ElementEventCallback<unknown, this>;
onmouseover: ElementEventCallback<unknown, this>;
onmouseout: ElementEventCallback<unknown, this>;
onmousemove: ElementEventCallback<unknown, this>;
onmousewheel: ElementEventCallback<unknown, this>;
onmousedown: ElementEventCallback<unknown, this>;
onmouseup: ElementEventCallback<unknown, this>;
oncontextmenu: ElementEventCallback<unknown, this>;
ondrag: ElementEventCallback<unknown, this>;
ondragstart: ElementEventCallback<unknown, this>;
ondragend: ElementEventCallback<unknown, this>;
ondragenter: ElementEventCallback<unknown, this>;
ondragleave: ElementEventCallback<unknown, this>;
ondragover: ElementEventCallback<unknown, this>;
ondrop: ElementEventCallback<unknown, this>;
}
export {};
+301
View File
@@ -0,0 +1,301 @@
import { __extends } from "tslib";
import * as util from '../core/util.js';
import { devicePixelRatio } from '../config.js';
import { INCREMENTAL_ID_FALSE, ZLEVEL2_NORMAL_BELOW } from '../core/types.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;
}
export function isIncrementalLayer(layer) {
return !layer.__cursors.get(INCREMENTAL_ID_FALSE);
}
function getStartEndFromCursor(layer) {
var cursor = layer.__cursors.get(INCREMENTAL_ID_FALSE);
return {
startIdx: cursor ? cursor.startIdx : 0,
endIdx: cursor ? cursor.endIdx : 0
};
}
;
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.zlevel = 0;
_this.zlevel2 = ZLEVEL2_NORMAL_BELOW;
_this.maxRepaintRectCount = 5;
_this.__dirty = true;
_this.__firstTimePaint = true;
_this.__prevIdx = { startIdx: 0, endIdx: 0 };
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.afterBrush = function () {
this.__prevIdx = getStartEndFromCursor(this);
};
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;
}
}
}
var se = getStartEndFromCursor(this);
for (var i = se.startIdx; i < se.endIdx; ++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);
}
}
}
var prevIdx = this.__prevIdx;
for (var i = prevIdx.startIdx; i < prevIdx.endIdx; ++i) {
var el = prevList[i];
var shouldPaint = el && 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;
+76
View File
@@ -0,0 +1,76 @@
import Layer, { LayerConfig } from './Layer';
import Displayable from '../graphic/Displayable';
import { ZLevel } from '../core/types';
import { GradientObject } from '../graphic/Gradient';
import { ImagePatternObject } from '../graphic/Pattern';
import Storage from '../Storage';
import { PainterBase } from '../PainterBase';
interface CanvasPainterOption {
devicePixelRatio?: number;
width?: number | string;
height?: number | string;
useDirtyRect?: boolean;
}
export declare type CanvasPainterRefreshOpt = {
paintAll?: boolean;
refresh?: boolean;
refreshHover?: boolean;
};
export default class CanvasPainter implements PainterBase {
type: string;
root: HTMLElement;
dpr: number;
storage: Storage;
private _i;
private _singleCanvas;
private _opts;
private _prevDisplayList;
private _layerConfig;
private _needsManuallyCompositing;
private _width;
private _height;
private _domRoot;
private _hoverLayerDirty;
private _redrawId;
private _backgroundColor;
constructor(root: HTMLElement, storage: Storage, opts: CanvasPainterOption, id: number);
getType(): string;
isSingleCanvas(): boolean;
getViewportRoot(): HTMLElement;
getViewportRootOffset(): {
offsetLeft: number;
offsetTop: number;
};
refresh(optOrPaintAll?: CanvasPainterRefreshOpt | CanvasPainterRefreshOpt['paintAll']): this;
private _paintHoverList;
getHoverLayer(): Layer;
paintOne(ctx: CanvasRenderingContext2D, el: Displayable): void;
private _paintList;
private _compositeManually;
private _doPaintList;
private _paintPerCursor;
private _paintPerCursorInRect;
getLayer(zlevel: ZLevel, virtual?: boolean): Layer;
private _ensureLayer;
insertLayer(zlevel: ZLevel, layer: Layer): void;
private _insertLayer;
eachLayer<T>(cb: (this: T, layer: Layer, zlevel: number) => void, context?: T): void;
eachBuiltinLayer<T>(cb: (this: T, layer: Layer, zlevel: number) => void, context?: T): void;
eachOtherLayer<T>(cb: (this: T, layer: Layer, z: number) => void, context?: T): void;
getLayers(): Record<string, Layer>;
private _updateLayerStatus;
clear(): this;
setBackgroundColor(backgroundColor: string | GradientObject | ImagePatternObject): void;
configLayer(zlevel: number, config: LayerConfig): void;
delLayer(zlevel: number): void;
resize(width?: number | string, height?: number | string): this;
clearLayer(zlevel: number): void;
dispose(): void;
getRenderedCanvas(opts?: {
backgroundColor?: string | GradientObject | ImagePatternObject;
pixelRatio?: number;
}): HTMLCanvasElement;
getWidth(): number;
getHeight(): number;
}
export {};
+743
View File
@@ -0,0 +1,743 @@
import { devicePixelRatio } from '../config.js';
import * as util from '../core/util.js';
import Layer, { isIncrementalLayer } from './Layer.js';
import requestAnimationFrame from '../animation/requestAnimationFrame.js';
import env from '../core/env.js';
import { ZLEVEL2_INCREMENTAL, ZLEVEL2_NORMAL_ABOVE, ZLEVEL2_NORMAL_BELOW } from '../core/types.js';
import { brush, brushLoopFinalize, brushSingle } from './graphic.js';
import { REDRAW_BIT } from '../graphic/constants.js';
import { getSize } from './helper.js';
import { platformApi } from '../core/platform.js';
var HOVER_LAYER_ZLEVEL = 1e5;
var CANVAS_ZLEVEL = 314159;
var HOVER_LAYER_DIRTY_NO = undefined;
var HOVER_LAYER_DIRTY_REPAINT_IF_EXISTING = 1;
var HOVER_LAYER_DIRTY_REPAINT = 2;
function isLayerValid(layer) {
if (!layer) {
return false;
}
if (layer.__builtin__) {
return true;
}
if (typeof (layer.resize) !== 'function'
|| typeof (layer.refresh) !== 'function') {
return false;
}
return true;
}
function createRoot(width, height) {
var domRoot = document.createElement('div');
domRoot.style.cssText = [
'position:relative',
'width:' + width + 'px',
'height:' + height + 'px',
'padding:0',
'margin:0',
'border-width:0'
].join(';') + ';';
return domRoot;
}
function createBuiltinLayer(id, painter, zlevel, zlevel2) {
var layer = new Layer(id, painter, painter.dpr);
layer.zlevel = zlevel;
layer.zlevel2 = zlevel2;
layer.__builtin__ = true;
resetLayerDrawCursors(layer);
return layer;
}
function resetLayerDrawCursors(layer) {
layer.__cursorStack = [];
layer.__cursors = util.createHashMap();
}
function resetLayerDrawCursor(cursor) {
cursor.startIdx = cursor.drawIdx = cursor.endIdx = cursor.endIdxNew = 0;
cursor.used = false;
cursor.first = cursor.last = NaN;
cursor.notClearIdx = -1;
return cursor;
}
function ensureLayerDrawCursor(layer, incrementalCompat) {
var cursors = layer.__cursors;
var incremental = +incrementalCompat;
return cursors.get(incremental)
|| (layer.__cursorStack.push(incremental),
cursors.set(incremental, resetLayerDrawCursor({ key: incremental })));
}
function eachCursorInLayer(layer, cb) {
var cursorStack = layer.__cursorStack;
for (var i = 0; i < cursorStack.length; i++) {
cb(layer.__cursors.get(cursorStack[i]));
}
}
function ensureLayerListInZLevel(internal, zlevel) {
var layers = internal.layers;
return layers[zlevel] || (layers[zlevel] = new Array(3));
}
function eachLayer(internal, cb, filter) {
var layerStack = internal.layerStack;
for (var i = 0; i < layerStack.length; i++) {
var zlevel = layerStack[i].zl;
var zlevel2 = layerStack[i].zl2;
var layer = internal.layers[zlevel][zlevel2];
if (!filter || ((!(filter & EACH_LAYER_BUILTIN) || layer.__builtin__)
&& (!(filter & EACH_LAYER_NOT_BUILTIN) || !layer.__builtin__)
&& (!(filter & EACH_LAYER_NOT_HOVER) || layer !== internal.hoverlayer))) {
cb(layer, zlevel, zlevel2, i);
}
}
}
var EACH_LAYER_BUILTIN = 1;
var EACH_LAYER_NOT_BUILTIN = 2;
var EACH_LAYER_NOT_HOVER = 4;
var EACH_LAYER_BUILTIN_NOT_HOVER = EACH_LAYER_BUILTIN | EACH_LAYER_NOT_HOVER;
var CanvasPainter = (function () {
function CanvasPainter(root, storage, opts, id) {
this.type = 'canvas';
this._prevDisplayList = [];
this._layerConfig = {};
this._needsManuallyCompositing = false;
this.type = 'canvas';
this._i = {
layerStack: [],
layers: []
};
var singleCanvas = !root.nodeName
|| root.nodeName.toUpperCase() === 'CANVAS';
this._opts = opts = util.extend({}, opts || {});
this.dpr = opts.devicePixelRatio || devicePixelRatio;
this._singleCanvas = singleCanvas;
this.root = root;
var rootStyle = root.style;
if (rootStyle) {
util.disableUserSelect(root);
root.innerHTML = '';
}
this.storage = storage;
this._prevDisplayList = [];
if (!singleCanvas) {
this._width = getSize(root, 0, opts);
this._height = getSize(root, 1, opts);
var domRoot = this._domRoot = createRoot(this._width, this._height);
root.appendChild(domRoot);
}
else {
var rootCanvas = root;
var width = rootCanvas.width;
var height = rootCanvas.height;
if (opts.width != null) {
width = opts.width;
}
if (opts.height != null) {
height = opts.height;
}
this.dpr = opts.devicePixelRatio || 1;
rootCanvas.width = width * this.dpr;
rootCanvas.height = height * this.dpr;
this._width = width;
this._height = height;
var singleLayer = createBuiltinLayer(rootCanvas, this, CANVAS_ZLEVEL, ZLEVEL2_NORMAL_BELOW);
singleLayer.initContext();
this._insertLayer(singleLayer, CANVAS_ZLEVEL, ZLEVEL2_NORMAL_BELOW, true);
this._domRoot = root;
}
}
CanvasPainter.prototype.getType = function () {
return 'canvas';
};
CanvasPainter.prototype.isSingleCanvas = function () {
return this._singleCanvas;
};
CanvasPainter.prototype.getViewportRoot = function () {
return this._domRoot;
};
CanvasPainter.prototype.getViewportRootOffset = function () {
var viewportRoot = this.getViewportRoot();
if (viewportRoot) {
return {
offsetLeft: viewportRoot.offsetLeft || 0,
offsetTop: viewportRoot.offsetTop || 0
};
}
};
CanvasPainter.prototype.refresh = function (optOrPaintAll) {
var opt;
if (optOrPaintAll && !util.isObject(optOrPaintAll)) {
opt = { paintAll: !!optOrPaintAll };
}
else {
opt = optOrPaintAll || {};
}
var refresh = util.retrieve2(opt.refresh, true);
var refreshHover = util.retrieve2(opt.refreshHover, false);
if (refreshHover) {
this._hoverLayerDirty = HOVER_LAYER_DIRTY_REPAINT;
}
if (!refresh) {
if (refreshHover) {
this._paintHoverList(this.storage.getDisplayList(false));
}
return this;
}
var list = this.storage.getDisplayList(true);
this._updateLayerStatus(list, opt.paintAll);
this._redrawId = Math.random();
var prevList = this._prevDisplayList;
this._paintList(list, prevList, this._redrawId);
var bgColor = this._backgroundColor;
eachLayer(this._i, function (layer, zlevel, zlevel2, idx) {
if (layer.refresh) {
layer.refresh(idx === 0 ? bgColor : null);
}
}, EACH_LAYER_NOT_BUILTIN);
if (this._opts.useDirtyRect) {
this._prevDisplayList = list.slice();
}
return this;
};
CanvasPainter.prototype._paintHoverList = function (list) {
var hoverLayer = this._i.hoverlayer;
var hoverLayerDirty = this._hoverLayerDirty;
this._hoverLayerDirty = HOVER_LAYER_DIRTY_NO;
if (hoverLayerDirty === HOVER_LAYER_DIRTY_NO) {
return;
}
if (!hoverLayer && hoverLayerDirty === HOVER_LAYER_DIRTY_REPAINT) {
hoverLayer = this._i.hoverlayer = this._ensureLayer(HOVER_LAYER_ZLEVEL);
}
if (!hoverLayer) {
return;
}
hoverLayer.clear();
var scope = {
inHover: true,
viewWidth: this._width,
viewHeight: this._height,
beforeBrushParam: {}
};
var ctx;
for (var i = 0, len = list.length; i < len; i++) {
var el = list[i];
if (!el.__inHover) {
continue;
}
if (!ctx) {
ctx = hoverLayer.ctx;
ctx.save();
}
var hoverStyle = el.__hoverStyle;
var originalStyle = void 0;
if (hoverStyle) {
originalStyle = el.style;
el.style = hoverStyle;
}
brush(ctx, el, scope);
if (hoverStyle) {
el.style = originalStyle;
}
}
if (ctx) {
brushLoopFinalize(ctx, scope);
ctx.restore();
}
};
CanvasPainter.prototype.getHoverLayer = function () {
return this._ensureLayer(HOVER_LAYER_ZLEVEL);
};
CanvasPainter.prototype.paintOne = function (ctx, el) {
brushSingle(ctx, el);
};
CanvasPainter.prototype._paintList = function (list, prevList, redrawId) {
if (this._redrawId !== redrawId) {
return;
}
var finished = this._doPaintList(list, prevList);
if (this._needsManuallyCompositing) {
this._compositeManually();
}
if (!finished) {
var self_1 = this;
requestAnimationFrame(function () {
self_1._paintList(list, prevList, redrawId);
});
}
else {
eachLayer(this._i, function (layer) {
layer.afterBrush && layer.afterBrush();
}, EACH_LAYER_BUILTIN_NOT_HOVER);
this._paintHoverList(list);
}
};
CanvasPainter.prototype._compositeManually = function () {
var ctx = this._ensureLayer(CANVAS_ZLEVEL).ctx;
var width = this._domRoot.width;
var height = this._domRoot.height;
ctx.clearRect(0, 0, width, height);
eachLayer(this._i, function (layer) {
if (layer.virtual) {
ctx.drawImage(layer.dom, 0, 0, width, height);
}
}, EACH_LAYER_BUILTIN);
};
CanvasPainter.prototype._doPaintList = function (list, prevList) {
var painter = this;
var finished = true;
eachLayer(this._i, function (layer) {
var needDraw = false;
eachCursorInLayer(layer, function (cursor) {
if (cursor.drawIdx < cursor.endIdx
|| cursor.notClearIdx >= 0) {
needDraw = true;
}
});
if (!needDraw && !layer.__dirty) {
return;
}
var repaintRects = (painter._opts.useDirtyRect && !isIncrementalLayer(layer))
? layer.createRepaintRects(list, prevList, painter._width, painter._height) : null;
var firstLayerKey = painter._i.layerStack[0];
var contentRetained = true;
if (layer.__dirty) {
contentRetained = false;
layer.__dirty = false;
var clearColor = (layer.zlevel === firstLayerKey.zl && layer.zlevel2 === firstLayerKey.zl2)
? painter._backgroundColor : null;
layer.clear(false, clearColor, repaintRects);
}
eachCursorInLayer(layer, function (cursor) {
var cursorFinished = painter._paintPerCursor(layer, cursor, list, repaintRects, contentRetained);
finished = finished && cursorFinished;
});
}, EACH_LAYER_BUILTIN_NOT_HOVER);
if (env.wxa) {
eachLayer(this._i, function (layer) {
if (layer && layer.ctx && layer.ctx.draw) {
layer.ctx.draw();
}
});
}
return finished;
};
CanvasPainter.prototype._paintPerCursor = function (layer, layerCursor, list, repaintRects, contentRetained) {
var ctx = layer.ctx;
if (repaintRects) {
if (!repaintRects.length) {
layerCursor.drawIdx = layerCursor.endIdx;
}
else {
var dpr = this.dpr;
for (var r = 0; r < repaintRects.length; ++r) {
var rect = repaintRects[r];
ctx.save();
ctx.beginPath();
ctx.rect(rect.x * dpr, rect.y * dpr, rect.width * dpr, rect.height * dpr);
ctx.clip();
this._paintPerCursorInRect(layer, layerCursor, list, rect, contentRetained);
ctx.restore();
}
}
}
else {
ctx.save();
this._paintPerCursorInRect(layer, layerCursor, list, null, contentRetained);
ctx.restore();
}
return layerCursor.drawIdx >= layerCursor.endIdx;
};
CanvasPainter.prototype._paintPerCursorInRect = function (layer, layerCursor, list, repaintRect, contentRetained) {
var scope = {
inHover: false,
allClipped: false,
prevEl: null,
viewWidth: this._width,
viewHeight: this._height,
beforeBrushParam: { contentRetained: contentRetained }
};
var ctx = layer.ctx;
var useTimer = isIncrementalLayer(layer);
var startTime = useTimer && platformApi.getTime();
var drawIdxBegin = layerCursor.drawIdx;
var notClearIdx = layerCursor.notClearIdx;
var idx = notClearIdx >= 0 ? Math.min(notClearIdx, drawIdxBegin) : drawIdxBegin;
for (; idx < layerCursor.endIdx; idx++) {
var el = list[idx];
if (idx < drawIdxBegin && !el.notClear) {
continue;
}
if (el.__inHover) {
this._hoverLayerDirty = HOVER_LAYER_DIRTY_REPAINT;
}
if (repaintRect != null) {
var paintRect = el.getPaintRect();
if (paintRect && paintRect.intersect(repaintRect)) {
brush(ctx, el, scope);
el.setPrevPaintRect(paintRect);
}
}
else {
brush(ctx, el, scope);
}
if (useTimer) {
var dTime = platformApi.getTime() - startTime;
if (dTime > 15) {
idx++;
break;
}
}
}
brushLoopFinalize(ctx, scope);
layerCursor.drawIdx = Math.max(idx, drawIdxBegin);
};
CanvasPainter.prototype.getLayer = function (zlevel, virtual) {
return this._ensureLayer(zlevel, 0, virtual);
};
CanvasPainter.prototype._ensureLayer = function (zlevel, zlevel2, virtual) {
zlevel2 = zlevel2 || 0;
var singleCanvas = this._singleCanvas;
if (singleCanvas && !this._needsManuallyCompositing) {
zlevel = CANVAS_ZLEVEL;
zlevel2 = 0;
}
var layer = ensureLayerListInZLevel(this._i, zlevel)[zlevel2];
if (!layer) {
layer = createBuiltinLayer('zr_' + zlevel + '.' + zlevel2, this, zlevel, zlevel2);
if (this._layerConfig[zlevel]) {
util.merge(layer, this._layerConfig[zlevel], true);
}
if (virtual
|| (singleCanvas && zlevel !== CANVAS_ZLEVEL)) {
layer.virtual = true;
}
this._insertLayer(layer, zlevel, zlevel2, false);
layer.initContext();
}
return layer;
};
CanvasPainter.prototype.insertLayer = function (zlevel, layer) {
this._insertLayer(layer, zlevel, 0, false);
};
CanvasPainter.prototype._insertLayer = function (layer, zlevel, zlevel2, suppressDOMInsert) {
var internal = this._i;
var layersMap = internal.layers;
var layerStack = internal.layerStack;
var domRoot = this._domRoot;
var prevLayer = null;
if (layersMap[zlevel] && layersMap[zlevel][zlevel2]) {
if (process.env.NODE_ENV !== 'production') {
util.logError('ZLevel ' + zlevel + '.' + zlevel2 + ' has been used already');
}
return;
}
if (!isLayerValid(layer)) {
if (process.env.NODE_ENV !== 'production') {
util.logError('Layer of zlevel ' + zlevel + ' is not valid');
}
return;
}
var len = layerStack.length;
var i = 0;
while (i < len
&& (layerStack[i].zl < zlevel
|| (layerStack[i].zl === zlevel && layerStack[i].zl2 < zlevel2))) {
i++;
}
if (i > 0) {
prevLayer = ensureLayerListInZLevel(internal, layerStack[i - 1].zl)[layerStack[i - 1].zl2];
}
layerStack.splice(i, 0, { zl: zlevel, zl2: zlevel2 });
ensureLayerListInZLevel(internal, zlevel)[zlevel2] = layer;
if (!suppressDOMInsert && !layer.virtual) {
if (prevLayer) {
var prevDom = prevLayer.dom;
if (prevDom.nextSibling) {
domRoot.insertBefore(layer.dom, prevDom.nextSibling);
}
else {
domRoot.appendChild(layer.dom);
}
}
else {
if (domRoot.firstChild) {
domRoot.insertBefore(layer.dom, domRoot.firstChild);
}
else {
domRoot.appendChild(layer.dom);
}
}
}
layer.painter || (layer.painter = this);
};
CanvasPainter.prototype.eachLayer = function (cb, context) {
return eachLayer(this._i, function (layer, zlevel) {
cb.call(context, layer, zlevel);
});
};
CanvasPainter.prototype.eachBuiltinLayer = function (cb, context) {
return eachLayer(this._i, function (layer, zlevel) {
cb.call(context, layer, zlevel);
}, EACH_LAYER_BUILTIN);
};
CanvasPainter.prototype.eachOtherLayer = function (cb, context) {
return eachLayer(this._i, function (layer, zlevel) {
cb.call(context, layer, zlevel);
}, EACH_LAYER_NOT_BUILTIN);
};
CanvasPainter.prototype.getLayers = function () {
var layers = {};
eachLayer(this._i, function (layer, zlevel, zlevel2) {
layers[layer.id] = layer;
});
return layers;
};
CanvasPainter.prototype._updateLayerStatus = function (list, paintAll) {
var painter = this;
if (painter._singleCanvas) {
for (var i = 1; i < list.length; i++) {
var el = list[i];
if (el.zlevel !== list[i - 1].zlevel || el.incremental) {
painter._needsManuallyCompositing = true;
break;
}
}
}
eachLayer(painter._i, function (layer) {
layer.__dirty = false;
eachCursorInLayer(layer, function (cursor) {
cursor.used = false;
cursor.endIdxNew = 0;
cursor.notClearIdx = -1;
});
}, EACH_LAYER_BUILTIN_NOT_HOVER);
var prevZLevel;
var currLayer = null;
var currCursor = null;
var aboveIncrementalInCurrZLevel = false;
for (var idx = 0, len = list.length; idx < len; idx++) {
var el = list[idx];
var zlevel = el.zlevel;
var elIncremental = el.incremental;
var zlevel2 = void 0;
if (prevZLevel !== zlevel) {
prevZLevel = zlevel;
aboveIncrementalInCurrZLevel = false;
}
if (elIncremental) {
aboveIncrementalInCurrZLevel = true;
zlevel2 = ZLEVEL2_INCREMENTAL;
}
else {
zlevel2 = aboveIncrementalInCurrZLevel ? ZLEVEL2_NORMAL_ABOVE : ZLEVEL2_NORMAL_BELOW;
}
if (!currLayer || zlevel !== currLayer.zlevel || zlevel2 !== currLayer.zlevel2) {
currLayer = painter._ensureLayer(zlevel, zlevel2);
currCursor = null;
if (!currLayer.__builtin__) {
util.logError('ZLevel ' + zlevel + ' has been used by unknown layer ' + currLayer.id);
continue;
}
}
if (!currCursor || elIncremental !== currCursor.key) {
currCursor = ensureLayerDrawCursor(currLayer, elIncremental);
if (!currCursor.used) {
currCursor.used = true;
if (!paintAll && currCursor.first === el.id) {
var idxShift = idx - currCursor.startIdx;
currCursor.startIdx = idx;
currCursor.drawIdx += idxShift;
currCursor.endIdx += idxShift;
}
else {
currLayer.__dirty = true;
currCursor.first = el.id;
currCursor.startIdx = currCursor.drawIdx = idx;
currCursor.endIdx = idx + 1;
}
}
}
currCursor.endIdxNew = idx + 1;
if ((el.__dirty & REDRAW_BIT)
&& !el.__inHover) {
if (!elIncremental
|| (!el.notClear && idx < currCursor.drawIdx)) {
currLayer.__dirty = true;
}
if (elIncremental && el.notClear && currCursor.notClearIdx < 0) {
currCursor.notClearIdx = idx;
}
}
}
eachLayer(painter._i, function (layer) {
var cursorStack = layer.__cursorStack;
var cursors = layer.__cursors;
for (var i = cursorStack.length - 1; i >= 0; i--) {
var cursor = cursors.get(cursorStack[i]);
if (!cursor.used) {
layer.__dirty = true;
cursors.removeKey(cursorStack[i]);
cursorStack.splice(i, 1);
}
else {
var endIdxNew = cursor.endIdxNew;
if (isIncrementalLayer(layer)
? endIdxNew < cursor.drawIdx
: (endIdxNew !== cursor.endIdx
|| !endIdxNew
|| list[endIdxNew - 1].id !== cursor.last)) {
layer.__dirty = true;
}
cursor.endIdx = cursor.endIdxNew;
cursor.last = endIdxNew ? list[endIdxNew - 1].id : NaN;
}
}
if (layer.__dirty) {
eachCursorInLayer(layer, function (cursor) {
cursor.drawIdx = cursor.startIdx;
});
if (painter._hoverLayerDirty === HOVER_LAYER_DIRTY_NO) {
painter._hoverLayerDirty = HOVER_LAYER_DIRTY_REPAINT_IF_EXISTING;
}
}
}, EACH_LAYER_BUILTIN_NOT_HOVER);
};
CanvasPainter.prototype.clear = function () {
eachLayer(this._i, function (layer) {
layer.clear();
resetLayerDrawCursors(layer);
}, EACH_LAYER_BUILTIN);
return this;
};
CanvasPainter.prototype.setBackgroundColor = function (backgroundColor) {
this._backgroundColor = backgroundColor;
eachLayer(this._i, function (layer) {
layer.setUnpainted();
});
};
CanvasPainter.prototype.configLayer = function (zlevel, config) {
if (config) {
var layerConfig_1 = this._layerConfig;
if (!layerConfig_1[zlevel]) {
layerConfig_1[zlevel] = config;
}
else {
util.merge(layerConfig_1[zlevel], config, true);
}
eachLayer(this._i, function (layer, zlevel) {
util.merge(layer, layerConfig_1[zlevel], true);
});
}
};
CanvasPainter.prototype.delLayer = function (zlevel) {
var layerStack = this._i.layerStack;
var layersMap = this._i.layers;
for (var i = layerStack.length - 1; i >= 0; i--) {
var key = layerStack[i];
if (key.zl === zlevel) {
var layer = layersMap[zlevel][key.zl2];
if (layer.__builtin__) {
continue;
}
layerStack.splice(i, 1);
layersMap[zlevel][key.zl2] = undefined;
if (!layer.virtual) {
var parentNode = layer.dom.parentNode;
parentNode && parentNode.removeChild(layer.dom);
}
}
}
};
CanvasPainter.prototype.resize = function (width, height) {
if (!this._domRoot.style) {
if (width == null || height == null) {
return;
}
this._width = width;
this._height = height;
this._ensureLayer(CANVAS_ZLEVEL).resize(width, height);
}
else {
var domRoot = this._domRoot;
domRoot.style.display = 'none';
var opts = this._opts;
var root = this.root;
width != null && (opts.width = width);
height != null && (opts.height = height);
width = getSize(root, 0, opts);
height = getSize(root, 1, opts);
domRoot.style.display = '';
if (this._width !== width || height !== this._height) {
domRoot.style.width = width + 'px';
domRoot.style.height = height + 'px';
eachLayer(this._i, function (layer) {
layer.resize(width, height);
});
this.refresh({ paintAll: true });
}
this._width = width;
this._height = height;
}
return this;
};
CanvasPainter.prototype.clearLayer = function (zlevel) {
util.each(this._i.layers[zlevel], function (layer) {
if (layer && !layer.__builtin__) {
layer.clear();
}
});
};
CanvasPainter.prototype.dispose = function () {
this.root.innerHTML = '';
this.root =
this.storage =
this._domRoot =
this._i = null;
};
CanvasPainter.prototype.getRenderedCanvas = function (opts) {
opts = opts || {};
if (this._singleCanvas && !this._compositeManually) {
return this._i.layers[CANVAS_ZLEVEL][0].dom;
}
var imageLayer = new Layer('image', this, opts.pixelRatio || this.dpr);
imageLayer.initContext();
imageLayer.clear(false, opts.backgroundColor || this._backgroundColor);
var ctx = imageLayer.ctx;
if (opts.pixelRatio <= this.dpr) {
this.refresh();
var width_1 = imageLayer.dom.width;
var height_1 = imageLayer.dom.height;
eachLayer(this._i, function (layer) {
if (layer.__builtin__) {
ctx.drawImage(layer.dom, 0, 0, width_1, height_1);
}
else if (layer.renderToCanvas) {
ctx.save();
layer.renderToCanvas(ctx);
ctx.restore();
}
});
}
else {
var scope = {
inHover: false,
viewWidth: this._width,
viewHeight: this._height,
beforeBrushParam: {}
};
var displayList = this.storage.getDisplayList(true);
for (var i = 0, len = displayList.length; i < len; i++) {
var el = displayList[i];
brush(ctx, el, scope);
}
brushLoopFinalize(ctx, scope);
}
return imageLayer.dom;
};
CanvasPainter.prototype.getWidth = function () {
return this._width;
};
CanvasPainter.prototype.getHeight = function () {
return this._height;
};
return CanvasPainter;
}());
export default CanvasPainter;
;
+1
View File
@@ -0,0 +1 @@
export {};
+3
View File
@@ -0,0 +1,3 @@
import { registerPainter } from '../zrender.js';
import Painter from './Painter.js';
registerPainter('canvas', Painter);
+4
View File
@@ -0,0 +1,4 @@
import Path from '../graphic/Path';
import TSpan from '../graphic/TSpan';
export declare function normalizeLineDash(lineType: any, lineWidth?: number): number[] | false;
export declare function getLineDash(el: Path | TSpan): [number[] | false, number];
+27
View File
@@ -0,0 +1,27 @@
import { isArray, isNumber, map } from '../core/util.js';
export function normalizeLineDash(lineType, lineWidth) {
if (!lineType || lineType === 'solid' || !(lineWidth > 0)) {
return null;
}
return lineType === 'dashed'
? [4 * lineWidth, 2 * lineWidth]
: lineType === 'dotted'
? [lineWidth]
: isNumber(lineType)
? [lineType] : isArray(lineType) ? lineType : null;
}
export function getLineDash(el) {
var style = el.style;
var lineDash = style.lineDash && style.lineWidth > 0 && normalizeLineDash(style.lineDash, style.lineWidth);
var lineDashOffset = style.lineDashOffset;
if (lineDash) {
var lineScale_1 = (style.strokeNoScale && el.getLineScale) ? el.getLineScale() : 1;
if (lineScale_1 && lineScale_1 !== 1) {
lineDash = map(lineDash, function (rawVal) {
return rawVal / lineScale_1;
});
lineDashOffset /= lineScale_1;
}
}
return [lineDash, lineDashOffset];
}
+21
View File
@@ -0,0 +1,21 @@
import Displayable, { BeforeBrushParam } from '../graphic/Displayable';
import { ImagePatternObject } from '../graphic/Pattern';
import Path from '../graphic/Path';
export declare function createCanvasPattern(this: void, ctx: CanvasRenderingContext2D, pattern: ImagePatternObject, el: {
dirty: () => void;
}): CanvasPattern;
export declare type BrushScope = {
inHover: boolean;
viewWidth: number;
viewHeight: number;
prevElClipPaths?: Path[];
prevEl?: Displayable;
allClipped?: boolean;
batchFill?: boolean;
batchStroke?: boolean;
lastDrawType?: number;
beforeBrushParam: BeforeBrushParam;
};
export declare function brushSingle(ctx: CanvasRenderingContext2D, el: Displayable): void;
export declare function brush(ctx: CanvasRenderingContext2D, el: Displayable, scope: BrushScope): void;
export declare function brushLoopFinalize(ctx: CanvasRenderingContext2D, scope: BrushScope): void;
+573
View File
@@ -0,0 +1,573 @@
import { DEFAULT_COMMON_STYLE } from '../graphic/Displayable.js';
import PathProxy from '../core/PathProxy.js';
import { createOrUpdateImage, isImageReady } from '../graphic/helper/image.js';
import { getCanvasGradient, isClipPathChanged } from './helper.js';
import Path from '../graphic/Path.js';
import ZRImage from '../graphic/Image.js';
import TSpan from '../graphic/TSpan.js';
import { RADIAN_TO_DEGREE } from '../core/util.js';
import { getLineDash } from './dashStyle.js';
import { REDRAW_BIT, SHAPE_CHANGED_BIT } from '../graphic/constants.js';
import { DEFAULT_FONT } from '../core/platform.js';
var pathProxyForDraw = new PathProxy(true);
function styleHasStroke(style) {
var stroke = style.stroke;
return !(stroke == null || stroke === 'none' || !(style.lineWidth > 0));
}
function isValidStrokeFillStyle(strokeOrFill) {
return typeof strokeOrFill === 'string' && strokeOrFill !== 'none';
}
function styleHasFill(style) {
var fill = style.fill;
return fill != null && fill !== 'none';
}
function doFillPath(ctx, style) {
if (style.fillOpacity != null && style.fillOpacity !== 1) {
var originalGlobalAlpha = ctx.globalAlpha;
ctx.globalAlpha = style.fillOpacity * style.opacity;
ctx.fill();
ctx.globalAlpha = originalGlobalAlpha;
}
else {
ctx.fill();
}
}
function doStrokePath(ctx, style) {
if (style.strokeOpacity != null && style.strokeOpacity !== 1) {
var originalGlobalAlpha = ctx.globalAlpha;
ctx.globalAlpha = style.strokeOpacity * style.opacity;
ctx.stroke();
ctx.globalAlpha = originalGlobalAlpha;
}
else {
ctx.stroke();
}
}
export function createCanvasPattern(ctx, pattern, el) {
var image = createOrUpdateImage(pattern.image, pattern.__image, el);
if (isImageReady(image)) {
var canvasPattern = ctx.createPattern(image, pattern.repeat || 'repeat');
if (typeof DOMMatrix === 'function'
&& canvasPattern
&& canvasPattern.setTransform) {
var matrix = new DOMMatrix();
matrix.translateSelf((pattern.x || 0), (pattern.y || 0));
matrix.rotateSelf(0, 0, (pattern.rotation || 0) * RADIAN_TO_DEGREE);
matrix.scaleSelf((pattern.scaleX || 1), (pattern.scaleY || 1));
canvasPattern.setTransform(matrix);
}
return canvasPattern;
}
}
function brushPath(ctx, el, style, canBatch, scope) {
var _a;
var hasStroke = styleHasStroke(style);
var hasFill = styleHasFill(style);
var strokePercent = style.strokePercent;
var strokePart = strokePercent < 1;
var firstDraw = !el.path;
if ((!el.silent || strokePart) && firstDraw) {
el.createPathProxy();
}
var path = el.path || pathProxyForDraw;
var dirtyFlag = el.__dirty;
if (!canBatch) {
var fill = style.fill;
var stroke = style.stroke;
var hasFillGradient = hasFill && !!fill.colorStops;
var hasStrokeGradient = hasStroke && !!stroke.colorStops;
var hasFillPattern = hasFill && !!fill.image;
var hasStrokePattern = hasStroke && !!stroke.image;
var fillGradient = void 0;
var strokeGradient = void 0;
var fillPattern = void 0;
var strokePattern = void 0;
var rect = void 0;
if (hasFillGradient || hasStrokeGradient) {
rect = el.getBoundingRect();
}
if (hasFillGradient) {
fillGradient = dirtyFlag
? getCanvasGradient(ctx, fill, rect)
: el.__canvasFillGradient;
el.__canvasFillGradient = fillGradient;
}
if (hasStrokeGradient) {
strokeGradient = dirtyFlag
? getCanvasGradient(ctx, stroke, rect)
: el.__canvasStrokeGradient;
el.__canvasStrokeGradient = strokeGradient;
}
if (hasFillPattern) {
fillPattern = (dirtyFlag || !el.__canvasFillPattern)
? createCanvasPattern(ctx, fill, el)
: el.__canvasFillPattern;
el.__canvasFillPattern = fillPattern;
}
if (hasStrokePattern) {
strokePattern = (dirtyFlag || !el.__canvasStrokePattern)
? createCanvasPattern(ctx, stroke, el)
: el.__canvasStrokePattern;
el.__canvasStrokePattern = strokePattern;
}
if (hasFillGradient) {
ctx.fillStyle = fillGradient;
}
else if (hasFillPattern) {
if (fillPattern) {
ctx.fillStyle = fillPattern;
}
else {
hasFill = false;
}
}
if (hasStrokeGradient) {
ctx.strokeStyle = strokeGradient;
}
else if (hasStrokePattern) {
if (strokePattern) {
ctx.strokeStyle = strokePattern;
}
else {
hasStroke = false;
}
}
}
var scale = el.getGlobalScale();
path.setScale(scale[0], scale[1], el.segmentIgnoreThreshold);
var lineDash;
var lineDashOffset;
if (ctx.setLineDash && style.lineDash) {
_a = getLineDash(el), lineDash = _a[0], lineDashOffset = _a[1];
}
var needsRebuild = true;
if (firstDraw || (dirtyFlag & SHAPE_CHANGED_BIT)) {
path.setDPR(ctx.dpr);
if (strokePart) {
path.setContext(null);
}
else {
path.setContext(ctx);
needsRebuild = false;
}
path.reset();
el.buildPath(path, el.shape, canBatch);
path.toStatic();
el.pathUpdated();
}
if (needsRebuild) {
path.rebuildPath(ctx, strokePart ? strokePercent : 1);
}
if (lineDash) {
ctx.setLineDash(lineDash);
ctx.lineDashOffset = lineDashOffset;
}
if (!canBatch) {
if (style.strokeFirst) {
if (hasStroke) {
doStrokePath(ctx, style);
}
if (hasFill) {
doFillPath(ctx, style);
}
}
else {
if (hasFill) {
doFillPath(ctx, style);
}
if (hasStroke) {
doStrokePath(ctx, style);
}
}
}
else {
scope.batchFill = hasFill;
scope.batchStroke = hasStroke;
}
if (lineDash) {
ctx.setLineDash([]);
}
}
function brushImage(ctx, el, style) {
var image = el.__image = createOrUpdateImage(style.image, el.__image, el, el.onload);
if (!image || !isImageReady(image)) {
return;
}
var x = style.x || 0;
var y = style.y || 0;
var width = el.getWidth();
var height = el.getHeight();
var aspect = image.width / image.height;
if (width == null && height != null) {
width = height * aspect;
}
else if (height == null && width != null) {
height = width / aspect;
}
else if (width == null && height == null) {
width = image.width;
height = image.height;
}
if (style.sWidth && style.sHeight) {
var sx = style.sx || 0;
var sy = style.sy || 0;
ctx.drawImage(image, sx, sy, style.sWidth, style.sHeight, x, y, width, height);
}
else if (style.sx && style.sy) {
var sx = style.sx;
var sy = style.sy;
var sWidth = width - sx;
var sHeight = height - sy;
ctx.drawImage(image, sx, sy, sWidth, sHeight, x, y, width, height);
}
else {
ctx.drawImage(image, x, y, width, height);
}
}
function brushText(ctx, el, style) {
var _a;
var text = style.text;
text != null && (text += '');
if (text) {
ctx.font = style.font || DEFAULT_FONT;
ctx.textAlign = style.textAlign;
ctx.textBaseline = style.textBaseline;
var lineDash = void 0;
var lineDashOffset = void 0;
if (ctx.setLineDash && style.lineDash) {
_a = getLineDash(el), lineDash = _a[0], lineDashOffset = _a[1];
}
if (lineDash) {
ctx.setLineDash(lineDash);
ctx.lineDashOffset = lineDashOffset;
}
if (style.strokeFirst) {
if (styleHasStroke(style)) {
ctx.strokeText(text, style.x, style.y);
}
if (styleHasFill(style)) {
ctx.fillText(text, style.x, style.y);
}
}
else {
if (styleHasFill(style)) {
ctx.fillText(text, style.x, style.y);
}
if (styleHasStroke(style)) {
ctx.strokeText(text, style.x, style.y);
}
}
if (lineDash) {
ctx.setLineDash([]);
}
}
}
var SHADOW_NUMBER_PROPS = ['shadowBlur', 'shadowOffsetX', 'shadowOffsetY'];
var STROKE_PROPS = [
['lineCap', 'butt'], ['lineJoin', 'miter'], ['miterLimit', 10]
];
function bindCommonProps(ctx, style, prevStyle, forceSetAll, scope) {
var styleChanged = false;
if (!forceSetAll) {
prevStyle = prevStyle || {};
if (style === prevStyle) {
return false;
}
}
if (forceSetAll || style.opacity !== prevStyle.opacity) {
flushPathDrawn(ctx, scope);
styleChanged = true;
var opacity = Math.max(Math.min(style.opacity, 1), 0);
ctx.globalAlpha = isNaN(opacity) ? DEFAULT_COMMON_STYLE.opacity : opacity;
}
if (forceSetAll || style.blend !== prevStyle.blend) {
if (!styleChanged) {
flushPathDrawn(ctx, scope);
styleChanged = true;
}
ctx.globalCompositeOperation = style.blend || DEFAULT_COMMON_STYLE.blend;
}
for (var i = 0; i < SHADOW_NUMBER_PROPS.length; i++) {
var propName = SHADOW_NUMBER_PROPS[i];
if (forceSetAll || style[propName] !== prevStyle[propName]) {
if (!styleChanged) {
flushPathDrawn(ctx, scope);
styleChanged = true;
}
ctx[propName] = ctx.dpr * (style[propName] || 0);
}
}
if (forceSetAll || style.shadowColor !== prevStyle.shadowColor) {
if (!styleChanged) {
flushPathDrawn(ctx, scope);
styleChanged = true;
}
ctx.shadowColor = style.shadowColor || DEFAULT_COMMON_STYLE.shadowColor;
}
return styleChanged;
}
function bindPathAndTextCommonStyle(ctx, el, prevEl, forceSetAll, scope) {
var style = el.style;
var prevStyle = forceSetAll
? null
: (prevEl && prevEl.style || {});
if (style === prevStyle) {
return false;
}
var styleChanged = bindCommonProps(ctx, style, prevStyle, forceSetAll, scope);
if (forceSetAll || style.fill !== prevStyle.fill) {
if (!styleChanged) {
flushPathDrawn(ctx, scope);
styleChanged = true;
}
isValidStrokeFillStyle(style.fill) && (ctx.fillStyle = style.fill);
}
if (forceSetAll || style.stroke !== prevStyle.stroke) {
if (!styleChanged) {
flushPathDrawn(ctx, scope);
styleChanged = true;
}
isValidStrokeFillStyle(style.stroke) && (ctx.strokeStyle = style.stroke);
}
if (forceSetAll || style.opacity !== prevStyle.opacity) {
if (!styleChanged) {
flushPathDrawn(ctx, scope);
styleChanged = true;
}
ctx.globalAlpha = style.opacity == null ? 1 : style.opacity;
}
if (el.hasStroke()) {
var lineWidth = style.lineWidth;
var newLineWidth = lineWidth / ((style.strokeNoScale && el.getLineScale) ? el.getLineScale() : 1);
if (ctx.lineWidth !== newLineWidth) {
if (!styleChanged) {
flushPathDrawn(ctx, scope);
styleChanged = true;
}
ctx.lineWidth = newLineWidth;
}
}
for (var i = 0; i < STROKE_PROPS.length; i++) {
var prop = STROKE_PROPS[i];
var propName = prop[0];
if (forceSetAll || style[propName] !== prevStyle[propName]) {
if (!styleChanged) {
flushPathDrawn(ctx, scope);
styleChanged = true;
}
ctx[propName] = style[propName] || prop[1];
}
}
return styleChanged;
}
function bindImageStyle(ctx, el, prevEl, forceSetAll, scope) {
return bindCommonProps(ctx, el.style, prevEl && prevEl.style, forceSetAll, scope);
}
function setContextTransform(ctx, el) {
var m = el.transform;
var dpr = ctx.dpr || 1;
if (m) {
ctx.setTransform(dpr * m[0], dpr * m[1], dpr * m[2], dpr * m[3], dpr * m[4], dpr * m[5]);
}
else {
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
}
}
function updateClipStatus(clipPaths, ctx, scope) {
var allClipped = false;
for (var i = 0; i < clipPaths.length; i++) {
var clipPath = clipPaths[i];
allClipped = allClipped || clipPath.isZeroArea();
setContextTransform(ctx, clipPath);
ctx.beginPath();
clipPath.buildPath(ctx, clipPath.shape);
ctx.clip();
}
scope.allClipped = allClipped;
}
function isTransformChanged(m0, m1) {
if (m0 && m1) {
return m0[0] !== m1[0]
|| m0[1] !== m1[1]
|| m0[2] !== m1[2]
|| m0[3] !== m1[3]
|| m0[4] !== m1[4]
|| m0[5] !== m1[5];
}
else if (!m0 && !m1) {
return false;
}
return true;
}
var DRAW_TYPE_PATH = 1;
var DRAW_TYPE_IMAGE = 2;
var DRAW_TYPE_TEXT = 3;
var DRAW_TYPE_INCREMENTAL = 4;
function canPathBatch(style) {
var hasFill = styleHasFill(style);
var hasStroke = styleHasStroke(style);
return !(style.lineDash
|| !(+hasFill ^ +hasStroke)
|| (hasFill && typeof style.fill !== 'string')
|| (hasStroke && typeof style.stroke !== 'string')
|| style.strokePercent < 1
|| style.strokeOpacity < 1
|| style.fillOpacity < 1);
}
function flushPathDrawn(ctx, scope) {
if (scope.batchFill) {
scope.batchFill = false;
ctx.fill();
}
if (scope.batchStroke) {
scope.batchStroke = false;
ctx.stroke();
}
}
export function brushSingle(ctx, el) {
var scope = { inHover: false, viewWidth: 0, viewHeight: 0, beforeBrushParam: {} };
brush(ctx, el, scope);
brushLoopFinalize(ctx, scope);
}
export function brush(ctx, el, scope) {
var m = el.transform;
if (!el.shouldBePainted(scope.viewWidth, scope.viewHeight, false, false)) {
el.__dirty &= ~REDRAW_BIT;
el.__isRendered = false;
return;
}
var clipPaths = el.__clipPaths;
var prevElClipPaths = scope.prevElClipPaths;
var style = el.style;
var forceSetTransform = false;
var forceSetStyle = false;
if (!prevElClipPaths || isClipPathChanged(clipPaths, prevElClipPaths)) {
if (prevElClipPaths) {
flushPathDrawn(ctx, scope);
ctx.restore();
forceSetStyle = forceSetTransform = true;
scope.prevElClipPaths = null;
scope.allClipped = false;
scope.prevEl = null;
}
if (clipPaths && clipPaths.length) {
flushPathDrawn(ctx, scope);
ctx.save();
updateClipStatus(clipPaths, ctx, scope);
forceSetTransform = true;
scope.prevElClipPaths = clipPaths;
}
}
if (scope.allClipped) {
el.__dirty &= ~REDRAW_BIT;
el.__isRendered = false;
return;
}
el.beforeBrush && el.beforeBrush(scope.beforeBrushParam);
el.innerBeforeBrush();
var prevEl = scope.prevEl;
if (!prevEl) {
forceSetStyle = forceSetTransform = true;
}
var canBatchPath = el instanceof Path
&& el.autoBatch
&& canPathBatch(style);
if (forceSetTransform || isTransformChanged(m, prevEl.transform)) {
flushPathDrawn(ctx, scope);
setContextTransform(ctx, el);
}
else if (!canBatchPath) {
flushPathDrawn(ctx, scope);
}
if (el instanceof Path) {
if (scope.lastDrawType !== DRAW_TYPE_PATH) {
forceSetStyle = true;
scope.lastDrawType = DRAW_TYPE_PATH;
}
bindPathAndTextCommonStyle(ctx, el, prevEl, forceSetStyle, scope);
if (!canBatchPath || (!scope.batchFill && !scope.batchStroke)) {
ctx.beginPath();
}
brushPath(ctx, el, style, canBatchPath, scope);
}
else {
if (el instanceof TSpan) {
if (scope.lastDrawType !== DRAW_TYPE_TEXT) {
forceSetStyle = true;
scope.lastDrawType = DRAW_TYPE_TEXT;
}
bindPathAndTextCommonStyle(ctx, el, prevEl, forceSetStyle, scope);
brushText(ctx, el, style);
}
else if (el instanceof ZRImage) {
if (scope.lastDrawType !== DRAW_TYPE_IMAGE) {
forceSetStyle = true;
scope.lastDrawType = DRAW_TYPE_IMAGE;
}
bindImageStyle(ctx, el, prevEl, forceSetStyle, scope);
brushImage(ctx, el, style);
}
else if (el.getTemporalDisplayables) {
if (scope.lastDrawType !== DRAW_TYPE_INCREMENTAL) {
forceSetStyle = true;
scope.lastDrawType = DRAW_TYPE_INCREMENTAL;
}
brushIncremental(ctx, el, scope);
}
}
el.innerAfterBrush();
if (el.afterBrush) {
if (canBatchPath) {
flushPathDrawn(ctx, scope);
}
el.afterBrush();
}
scope.prevEl = el;
el.__dirty = 0;
el.__isRendered = true;
}
export function brushLoopFinalize(ctx, scope) {
flushPathDrawn(ctx, scope);
if (scope.prevElClipPaths) {
ctx.restore();
}
}
function brushIncremental(ctx, el, scope) {
var displayables = el.getDisplayables();
var temporalDisplayables = el.getTemporalDisplayables();
ctx.save();
var innerScope = {
prevElClipPaths: null,
prevEl: null,
allClipped: false,
viewWidth: scope.viewWidth,
viewHeight: scope.viewHeight,
inHover: scope.inHover,
beforeBrushParam: {}
};
var i;
var len;
for (i = el.getCursor(), len = displayables.length; i < len; i++) {
var displayable = displayables[i];
displayable.beforeBrush && displayable.beforeBrush(scope.beforeBrushParam);
displayable.innerBeforeBrush();
brush(ctx, displayable, innerScope);
displayable.innerAfterBrush();
displayable.afterBrush && displayable.afterBrush();
innerScope.prevEl = displayable;
}
brushLoopFinalize(ctx, innerScope);
for (var i_1 = 0, len_1 = temporalDisplayables.length; i_1 < len_1; i_1++) {
var displayable = temporalDisplayables[i_1];
displayable.beforeBrush && displayable.beforeBrush(scope.beforeBrushParam);
displayable.innerBeforeBrush();
brush(ctx, displayable, innerScope);
displayable.innerAfterBrush();
displayable.afterBrush && displayable.afterBrush();
innerScope.prevEl = displayable;
}
brushLoopFinalize(ctx, innerScope);
el.clearTemporalDisplayables();
el.notClear = true;
ctx.restore();
}
+13
View File
@@ -0,0 +1,13 @@
import { LinearGradientObject } from '../graphic/LinearGradient';
import { RadialGradientObject } from '../graphic/RadialGradient';
import { GradientObject } from '../graphic/Gradient';
import { RectLike } from '../core/BoundingRect';
import Path from '../graphic/Path';
export declare function createLinearGradient(this: void, ctx: CanvasRenderingContext2D, obj: LinearGradientObject, rect: RectLike): CanvasGradient;
export declare function createRadialGradient(this: void, ctx: CanvasRenderingContext2D, obj: RadialGradientObject, rect: RectLike): CanvasGradient;
export declare function getCanvasGradient(this: void, ctx: CanvasRenderingContext2D, obj: GradientObject, rect: RectLike): CanvasGradient;
export declare function isClipPathChanged(clipPaths: Path[], prevClipPaths: Path[]): boolean;
export declare function getSize(root: HTMLElement, whIdx: number, opts: {
width?: number | string;
height?: number | string;
}): number;
+79
View File
@@ -0,0 +1,79 @@
function isSafeNum(num) {
return isFinite(num);
}
export function createLinearGradient(ctx, obj, rect) {
var x = obj.x == null ? 0 : obj.x;
var x2 = obj.x2 == null ? 1 : obj.x2;
var y = obj.y == null ? 0 : obj.y;
var y2 = obj.y2 == null ? 0 : obj.y2;
if (!obj.global) {
x = x * rect.width + rect.x;
x2 = x2 * rect.width + rect.x;
y = y * rect.height + rect.y;
y2 = y2 * rect.height + rect.y;
}
x = isSafeNum(x) ? x : 0;
x2 = isSafeNum(x2) ? x2 : 1;
y = isSafeNum(y) ? y : 0;
y2 = isSafeNum(y2) ? y2 : 0;
var canvasGradient = ctx.createLinearGradient(x, y, x2, y2);
return canvasGradient;
}
export function createRadialGradient(ctx, obj, rect) {
var width = rect.width;
var height = rect.height;
var min = Math.min(width, height);
var x = obj.x == null ? 0.5 : obj.x;
var y = obj.y == null ? 0.5 : obj.y;
var r = obj.r == null ? 0.5 : obj.r;
if (!obj.global) {
x = x * width + rect.x;
y = y * height + rect.y;
r = r * min;
}
x = isSafeNum(x) ? x : 0.5;
y = isSafeNum(y) ? y : 0.5;
r = r >= 0 && isSafeNum(r) ? r : 0.5;
var canvasGradient = ctx.createRadialGradient(x, y, 0, x, y, r);
return canvasGradient;
}
export function getCanvasGradient(ctx, obj, rect) {
var canvasGradient = obj.type === 'radial'
? createRadialGradient(ctx, obj, rect)
: createLinearGradient(ctx, obj, rect);
var colorStops = obj.colorStops;
for (var i = 0; i < colorStops.length; i++) {
canvasGradient.addColorStop(colorStops[i].offset, colorStops[i].color);
}
return canvasGradient;
}
export function isClipPathChanged(clipPaths, prevClipPaths) {
if (clipPaths === prevClipPaths || (!clipPaths && !prevClipPaths)) {
return false;
}
if (!clipPaths || !prevClipPaths || (clipPaths.length !== prevClipPaths.length)) {
return true;
}
for (var i = 0; i < clipPaths.length; i++) {
if (clipPaths[i] !== prevClipPaths[i]) {
return true;
}
}
return false;
}
function parseInt10(val) {
return parseInt(val, 10);
}
export function getSize(root, whIdx, opts) {
var wh = ['width', 'height'][whIdx];
var cwh = ['clientWidth', 'clientHeight'][whIdx];
var plt = ['paddingLeft', 'paddingTop'][whIdx];
var prb = ['paddingRight', 'paddingBottom'][whIdx];
if (opts[wh] != null && opts[wh] !== 'auto') {
return parseFloat(opts[wh]);
}
var stl = document.defaultView.getComputedStyle(root);
return ((root[cwh] || parseInt10(stl[wh]) || parseInt10(root.style[wh]))
- (parseInt10(stl[plt]) || 0)
- (parseInt10(stl[prb]) || 0)) || 0;
}