@antv/g-plugin-canvas-renderer
Advanced tools
Comparing version 1.7.35 to 1.7.36
@@ -5,50 +5,2 @@ import { ElementEvent, AABB, CustomEvent, CanvasEvent, Shape, runtime, isPattern, Rect, GradientType, AbstractRendererPlugin } from '@antv/g-lite'; | ||
function _iterableToArrayLimit(arr, i) { | ||
var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"]; | ||
if (null != _i) { | ||
var _s, | ||
_e, | ||
_x, | ||
_r, | ||
_arr = [], | ||
_n = !0, | ||
_d = !1; | ||
try { | ||
if (_x = (_i = _i.call(arr)).next, 0 === i) { | ||
if (Object(_i) !== _i) return; | ||
_n = !1; | ||
} else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0); | ||
} catch (err) { | ||
_d = !0, _e = err; | ||
} finally { | ||
try { | ||
if (!_n && null != _i.return && (_r = _i.return(), Object(_r) !== _r)) return; | ||
} finally { | ||
if (_d) throw _e; | ||
} | ||
} | ||
return _arr; | ||
} | ||
} | ||
function ownKeys(object, enumerableOnly) { | ||
var keys = Object.keys(object); | ||
if (Object.getOwnPropertySymbols) { | ||
var symbols = Object.getOwnPropertySymbols(object); | ||
enumerableOnly && (symbols = symbols.filter(function (sym) { | ||
return Object.getOwnPropertyDescriptor(object, sym).enumerable; | ||
})), keys.push.apply(keys, symbols); | ||
} | ||
return keys; | ||
} | ||
function _objectSpread2(target) { | ||
for (var i = 1; i < arguments.length; i++) { | ||
var source = null != arguments[i] ? arguments[i] : {}; | ||
i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { | ||
_defineProperty(target, key, source[key]); | ||
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { | ||
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); | ||
}); | ||
} | ||
return target; | ||
} | ||
function _regeneratorRuntime() { | ||
@@ -385,60 +337,21 @@ _regeneratorRuntime = function () { | ||
} | ||
function _classCallCheck(instance, Constructor) { | ||
if (!(instance instanceof Constructor)) { | ||
throw new TypeError("Cannot call a class as a function"); | ||
} | ||
} | ||
function _defineProperties(target, props) { | ||
for (var i = 0; i < props.length; i++) { | ||
var descriptor = props[i]; | ||
descriptor.enumerable = descriptor.enumerable || false; | ||
descriptor.configurable = true; | ||
if ("value" in descriptor) descriptor.writable = true; | ||
Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); | ||
} | ||
} | ||
function _createClass(Constructor, protoProps, staticProps) { | ||
if (protoProps) _defineProperties(Constructor.prototype, protoProps); | ||
if (staticProps) _defineProperties(Constructor, staticProps); | ||
Object.defineProperty(Constructor, "prototype", { | ||
writable: false | ||
}); | ||
return Constructor; | ||
} | ||
function _defineProperty(obj, key, value) { | ||
key = _toPropertyKey(key); | ||
if (key in obj) { | ||
Object.defineProperty(obj, key, { | ||
value: value, | ||
enumerable: true, | ||
configurable: true, | ||
writable: true | ||
}); | ||
} else { | ||
obj[key] = value; | ||
} | ||
return obj; | ||
} | ||
function _inherits(subClass, superClass) { | ||
if (typeof superClass !== "function" && superClass !== null) { | ||
throw new TypeError("Super expression must either be null or a function"); | ||
} | ||
subClass.prototype = Object.create(superClass && superClass.prototype, { | ||
constructor: { | ||
value: subClass, | ||
writable: true, | ||
configurable: true | ||
function _extends() { | ||
_extends = Object.assign ? Object.assign.bind() : function (target) { | ||
for (var i = 1; i < arguments.length; i++) { | ||
var source = arguments[i]; | ||
for (var key in source) { | ||
if (Object.prototype.hasOwnProperty.call(source, key)) { | ||
target[key] = source[key]; | ||
} | ||
} | ||
} | ||
}); | ||
Object.defineProperty(subClass, "prototype", { | ||
writable: false | ||
}); | ||
if (superClass) _setPrototypeOf(subClass, superClass); | ||
} | ||
function _getPrototypeOf(o) { | ||
_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { | ||
return o.__proto__ || Object.getPrototypeOf(o); | ||
return target; | ||
}; | ||
return _getPrototypeOf(o); | ||
return _extends.apply(this, arguments); | ||
} | ||
function _inheritsLoose(subClass, superClass) { | ||
subClass.prototype = Object.create(superClass.prototype); | ||
subClass.prototype.constructor = subClass; | ||
_setPrototypeOf(subClass, superClass); | ||
} | ||
function _setPrototypeOf(o, p) { | ||
@@ -451,89 +364,2 @@ _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { | ||
} | ||
function _isNativeReflectConstruct() { | ||
if (typeof Reflect === "undefined" || !Reflect.construct) return false; | ||
if (Reflect.construct.sham) return false; | ||
if (typeof Proxy === "function") return true; | ||
try { | ||
Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); | ||
return true; | ||
} catch (e) { | ||
return false; | ||
} | ||
} | ||
function _assertThisInitialized(self) { | ||
if (self === void 0) { | ||
throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); | ||
} | ||
return self; | ||
} | ||
function _possibleConstructorReturn(self, call) { | ||
if (call && (typeof call === "object" || typeof call === "function")) { | ||
return call; | ||
} else if (call !== void 0) { | ||
throw new TypeError("Derived constructors may only return object or undefined"); | ||
} | ||
return _assertThisInitialized(self); | ||
} | ||
function _createSuper(Derived) { | ||
var hasNativeReflectConstruct = _isNativeReflectConstruct(); | ||
return function _createSuperInternal() { | ||
var Super = _getPrototypeOf(Derived), | ||
result; | ||
if (hasNativeReflectConstruct) { | ||
var NewTarget = _getPrototypeOf(this).constructor; | ||
result = Reflect.construct(Super, arguments, NewTarget); | ||
} else { | ||
result = Super.apply(this, arguments); | ||
} | ||
return _possibleConstructorReturn(this, result); | ||
}; | ||
} | ||
function _slicedToArray(arr, i) { | ||
return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); | ||
} | ||
function _toConsumableArray(arr) { | ||
return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); | ||
} | ||
function _arrayWithoutHoles(arr) { | ||
if (Array.isArray(arr)) return _arrayLikeToArray(arr); | ||
} | ||
function _arrayWithHoles(arr) { | ||
if (Array.isArray(arr)) return arr; | ||
} | ||
function _iterableToArray(iter) { | ||
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); | ||
} | ||
function _unsupportedIterableToArray(o, minLen) { | ||
if (!o) return; | ||
if (typeof o === "string") return _arrayLikeToArray(o, minLen); | ||
var n = Object.prototype.toString.call(o).slice(8, -1); | ||
if (n === "Object" && o.constructor) n = o.constructor.name; | ||
if (n === "Map" || n === "Set") return Array.from(o); | ||
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); | ||
} | ||
function _arrayLikeToArray(arr, len) { | ||
if (len == null || len > arr.length) len = arr.length; | ||
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; | ||
return arr2; | ||
} | ||
function _nonIterableSpread() { | ||
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); | ||
} | ||
function _nonIterableRest() { | ||
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); | ||
} | ||
function _toPrimitive(input, hint) { | ||
if (typeof input !== "object" || input === null) return input; | ||
var prim = input[Symbol.toPrimitive]; | ||
if (prim !== undefined) { | ||
var res = prim.call(input, hint || "default"); | ||
if (typeof res !== "object") return res; | ||
throw new TypeError("@@toPrimitive must return a primitive value."); | ||
} | ||
return (hint === "string" ? String : Number)(input); | ||
} | ||
function _toPropertyKey(arg) { | ||
var key = _toPrimitive(arg, "string"); | ||
return typeof key === "symbol" ? key : String(key); | ||
} | ||
@@ -551,3 +377,2 @@ /** | ||
function CanvasRendererPlugin(canvasRendererPluginOptions) { | ||
_classCallCheck(this, CanvasRendererPlugin); | ||
this.canvasRendererPluginOptions = void 0; | ||
@@ -570,409 +395,387 @@ this.context = void 0; | ||
} | ||
_createClass(CanvasRendererPlugin, [{ | ||
key: "apply", | ||
value: function apply(context) { | ||
var _this = this; | ||
this.context = context; | ||
var config = context.config, | ||
camera = context.camera, | ||
renderingService = context.renderingService, | ||
renderingContext = context.renderingContext, | ||
rBushRoot = context.rBushRoot, | ||
pathGeneratorFactory = context.pathGeneratorFactory; | ||
this.rBush = rBushRoot; | ||
this.pathGeneratorFactory = pathGeneratorFactory; | ||
var contextService = context.contextService; | ||
var canvas = renderingContext.root.ownerDocument.defaultView; | ||
var handleUnmounted = function handleUnmounted(e) { | ||
var object = e.target; | ||
// remove r-bush node | ||
// @ts-ignore | ||
var rBushNode = object.rBushNode; | ||
if (rBushNode.aabb) { | ||
// save removed aabbs for dirty-rectangle rendering later | ||
_this.removedRBushNodeAABBs.push(rBushNode.aabb); | ||
} | ||
}; | ||
var handleCulled = function handleCulled(e) { | ||
var object = e.target; | ||
// @ts-ignore | ||
var rBushNode = object.rBushNode; | ||
if (rBushNode.aabb) { | ||
// save removed aabbs for dirty-rectangle rendering later | ||
_this.removedRBushNodeAABBs.push(rBushNode.aabb); | ||
} | ||
}; | ||
renderingService.hooks.init.tapPromise(CanvasRendererPlugin.tag, /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() { | ||
var dpr, width, height, context; | ||
return _regeneratorRuntime().wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
canvas.addEventListener(ElementEvent.UNMOUNTED, handleUnmounted); | ||
canvas.addEventListener(ElementEvent.CULLED, handleCulled); | ||
// clear fullscreen | ||
dpr = contextService.getDPR(); | ||
width = config.width, height = config.height; | ||
context = contextService.getContext(); | ||
_this.clearRect(context, 0, 0, width * dpr, height * dpr, config.background); | ||
case 6: | ||
case "end": | ||
return _context.stop(); | ||
} | ||
var _proto = CanvasRendererPlugin.prototype; | ||
_proto.apply = function apply(context) { | ||
var _this = this; | ||
this.context = context; | ||
var config = context.config, | ||
camera = context.camera, | ||
renderingService = context.renderingService, | ||
renderingContext = context.renderingContext, | ||
rBushRoot = context.rBushRoot, | ||
pathGeneratorFactory = context.pathGeneratorFactory; | ||
this.rBush = rBushRoot; | ||
this.pathGeneratorFactory = pathGeneratorFactory; | ||
var contextService = context.contextService; | ||
var canvas = renderingContext.root.ownerDocument.defaultView; | ||
var handleUnmounted = function handleUnmounted(e) { | ||
var object = e.target; | ||
// remove r-bush node | ||
// @ts-ignore | ||
var rBushNode = object.rBushNode; | ||
if (rBushNode.aabb) { | ||
// save removed aabbs for dirty-rectangle rendering later | ||
_this.removedRBushNodeAABBs.push(rBushNode.aabb); | ||
} | ||
}; | ||
var handleCulled = function handleCulled(e) { | ||
var object = e.target; | ||
// @ts-ignore | ||
var rBushNode = object.rBushNode; | ||
if (rBushNode.aabb) { | ||
// save removed aabbs for dirty-rectangle rendering later | ||
_this.removedRBushNodeAABBs.push(rBushNode.aabb); | ||
} | ||
}; | ||
renderingService.hooks.init.tapPromise(CanvasRendererPlugin.tag, /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() { | ||
var dpr, width, height, context; | ||
return _regeneratorRuntime().wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
canvas.addEventListener(ElementEvent.UNMOUNTED, handleUnmounted); | ||
canvas.addEventListener(ElementEvent.CULLED, handleCulled); | ||
// clear fullscreen | ||
dpr = contextService.getDPR(); | ||
width = config.width, height = config.height; | ||
context = contextService.getContext(); | ||
_this.clearRect(context, 0, 0, width * dpr, height * dpr, config.background); | ||
case 6: | ||
case "end": | ||
return _context.stop(); | ||
} | ||
}, _callee); | ||
}))); | ||
renderingService.hooks.destroy.tap(CanvasRendererPlugin.tag, function () { | ||
canvas.removeEventListener(ElementEvent.UNMOUNTED, handleUnmounted); | ||
canvas.removeEventListener(ElementEvent.CULLED, handleCulled); | ||
}); | ||
renderingService.hooks.beginFrame.tap(CanvasRendererPlugin.tag, function () { | ||
var context = contextService.getContext(); | ||
var dpr = contextService.getDPR(); | ||
var width = config.width, | ||
height = config.height; | ||
var _this$canvasRendererP = _this.canvasRendererPluginOptions, | ||
dirtyObjectNumThreshold = _this$canvasRendererP.dirtyObjectNumThreshold, | ||
dirtyObjectRatioThreshold = _this$canvasRendererP.dirtyObjectRatioThreshold; | ||
// some heuristic conditions such as 80% object changed | ||
var _renderingService$get = renderingService.getStats(), | ||
total = _renderingService$get.total, | ||
rendered = _renderingService$get.rendered; | ||
var ratio = rendered / total; | ||
_this.clearFullScreen = renderingService.disableDirtyRectangleRendering() || rendered > dirtyObjectNumThreshold && ratio > dirtyObjectRatioThreshold; | ||
if (context) { | ||
context.resetTransform(); | ||
if (_this.clearFullScreen) { | ||
_this.clearRect(context, 0, 0, width * dpr, height * dpr, config.background); | ||
} | ||
} | ||
}); | ||
var renderByZIndex = function renderByZIndex(object, context) { | ||
if (object.isVisible() && !object.isCulled()) { | ||
_this.renderDisplayObject(object, context, _this.context, _this.restoreStack); | ||
// if we did a full screen rendering last frame | ||
_this.saveDirtyAABB(object); | ||
} | ||
var sorted = object.sortable.sorted || object.childNodes; | ||
// should account for z-index | ||
sorted.forEach(function (child) { | ||
renderByZIndex(child, context); | ||
}); | ||
}; | ||
// render at the end of frame | ||
renderingService.hooks.endFrame.tap(CanvasRendererPlugin.tag, function () { | ||
var context = contextService.getContext(); | ||
// clear & clip dirty rectangle | ||
var dpr = contextService.getDPR(); | ||
mat4.fromScaling(_this.dprMatrix, vec3.fromValues(dpr, dpr, 1)); | ||
mat4.multiply(_this.vpMatrix, _this.dprMatrix, camera.getOrthoMatrix()); | ||
}, _callee); | ||
}))); | ||
renderingService.hooks.destroy.tap(CanvasRendererPlugin.tag, function () { | ||
canvas.removeEventListener(ElementEvent.UNMOUNTED, handleUnmounted); | ||
canvas.removeEventListener(ElementEvent.CULLED, handleCulled); | ||
}); | ||
renderingService.hooks.beginFrame.tap(CanvasRendererPlugin.tag, function () { | ||
var context = contextService.getContext(); | ||
var dpr = contextService.getDPR(); | ||
var width = config.width, | ||
height = config.height; | ||
var _this$canvasRendererP = _this.canvasRendererPluginOptions, | ||
dirtyObjectNumThreshold = _this$canvasRendererP.dirtyObjectNumThreshold, | ||
dirtyObjectRatioThreshold = _this$canvasRendererP.dirtyObjectRatioThreshold; | ||
// some heuristic conditions such as 80% object changed | ||
var _renderingService$get = renderingService.getStats(), | ||
total = _renderingService$get.total, | ||
rendered = _renderingService$get.rendered; | ||
var ratio = rendered / total; | ||
_this.clearFullScreen = renderingService.disableDirtyRectangleRendering() || rendered > dirtyObjectNumThreshold && ratio > dirtyObjectRatioThreshold; | ||
if (context) { | ||
context.resetTransform(); | ||
if (_this.clearFullScreen) { | ||
renderByZIndex(renderingContext.root, context); | ||
} else { | ||
// merge removed AABB | ||
var dirtyRenderBounds = _this.safeMergeAABB.apply(_this, [_this.mergeDirtyAABBs(_this.renderQueue)].concat(_toConsumableArray(_this.removedRBushNodeAABBs.map(function (_ref2) { | ||
var minX = _ref2.minX, | ||
minY = _ref2.minY, | ||
maxX = _ref2.maxX, | ||
maxY = _ref2.maxY; | ||
var aabb = new AABB(); | ||
aabb.setMinMax(vec3.fromValues(minX, minY, 0), vec3.fromValues(maxX, maxY, 0)); | ||
return aabb; | ||
})))); | ||
_this.removedRBushNodeAABBs = []; | ||
if (AABB.isEmpty(dirtyRenderBounds)) { | ||
_this.renderQueue = []; | ||
return; | ||
} | ||
var dirtyRect = _this.convertAABB2Rect(dirtyRenderBounds); | ||
var x = dirtyRect.x, | ||
y = dirtyRect.y, | ||
width = dirtyRect.width, | ||
height = dirtyRect.height; | ||
var tl = vec3.transformMat4(_this.vec3a, vec3.fromValues(x, y, 0), _this.vpMatrix); | ||
var tr = vec3.transformMat4(_this.vec3b, vec3.fromValues(x + width, y, 0), _this.vpMatrix); | ||
var bl = vec3.transformMat4(_this.vec3c, vec3.fromValues(x, y + height, 0), _this.vpMatrix); | ||
var br = vec3.transformMat4(_this.vec3d, vec3.fromValues(x + width, y + height, 0), _this.vpMatrix); | ||
var minx = Math.min(tl[0], tr[0], br[0], bl[0]); | ||
var miny = Math.min(tl[1], tr[1], br[1], bl[1]); | ||
var maxx = Math.max(tl[0], tr[0], br[0], bl[0]); | ||
var maxy = Math.max(tl[1], tr[1], br[1], bl[1]); | ||
var ix = Math.floor(minx); | ||
var iy = Math.floor(miny); | ||
var iwidth = Math.ceil(maxx - minx); | ||
var iheight = Math.ceil(maxy - miny); | ||
context.save(); | ||
_this.clearRect(context, ix, iy, iwidth, iheight, config.background); | ||
context.beginPath(); | ||
context.rect(ix, iy, iwidth, iheight); | ||
context.clip(); | ||
// @see https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Transformations | ||
context.setTransform(_this.vpMatrix[0], _this.vpMatrix[1], _this.vpMatrix[4], _this.vpMatrix[5], _this.vpMatrix[12], _this.vpMatrix[13]); | ||
// draw dirty rectangle | ||
var _config$renderer$getC = config.renderer.getConfig(), | ||
enableDirtyRectangleRenderingDebug = _config$renderer$getC.enableDirtyRectangleRenderingDebug; | ||
if (enableDirtyRectangleRenderingDebug) { | ||
canvas.dispatchEvent(new CustomEvent(CanvasEvent.DIRTY_RECTANGLE, { | ||
dirtyRect: { | ||
x: ix, | ||
y: iy, | ||
width: iwidth, | ||
height: iheight | ||
} | ||
})); | ||
} | ||
// search objects intersect with dirty rectangle | ||
var dirtyObjects = _this.searchDirtyObjects(dirtyRenderBounds); | ||
// do rendering | ||
dirtyObjects | ||
// sort by z-index | ||
.sort(function (a, b) { | ||
return a.sortable.renderOrder - b.sortable.renderOrder; | ||
}).forEach(function (object) { | ||
// culled object should not be rendered | ||
if (object && object.isVisible() && !object.isCulled()) { | ||
_this.renderDisplayObject(object, context, _this.context, _this.restoreStack); | ||
} | ||
}); | ||
context.restore(); | ||
// save dirty AABBs in last frame | ||
_this.renderQueue.forEach(function (object) { | ||
_this.saveDirtyAABB(object); | ||
}); | ||
// clear queue | ||
_this.renderQueue = []; | ||
_this.clearRect(context, 0, 0, width * dpr, height * dpr, config.background); | ||
} | ||
// pop restore stack, eg. root -> parent -> child | ||
_this.restoreStack.forEach(function () { | ||
context.restore(); | ||
}); | ||
// clear restore stack | ||
_this.restoreStack = []; | ||
}); | ||
renderingService.hooks.render.tap(CanvasRendererPlugin.tag, function (object) { | ||
if (!_this.clearFullScreen) { | ||
// render at the end of frame | ||
_this.renderQueue.push(object); | ||
} | ||
}); | ||
} | ||
}, { | ||
key: "clearRect", | ||
value: function clearRect(context, x, y, width, height, background) { | ||
// clearRect is faster than fillRect @see https://stackoverflow.com/a/30830253 | ||
context.clearRect(x, y, width, height); | ||
if (background) { | ||
context.fillStyle = background; | ||
context.fillRect(x, y, width, height); | ||
} | ||
} | ||
}, { | ||
key: "renderDisplayObject", | ||
value: function renderDisplayObject(object, context, canvasContext, restoreStack) { | ||
var nodeName = object.nodeName; | ||
// restore to its ancestor | ||
var parent = restoreStack[restoreStack.length - 1]; | ||
if (parent && !(object.compareDocumentPosition(parent) & Node.DOCUMENT_POSITION_CONTAINS)) { | ||
context.restore(); | ||
restoreStack.pop(); | ||
}); | ||
var renderByZIndex = function renderByZIndex(object, context) { | ||
if (object.isVisible() && !object.isCulled()) { | ||
_this.renderDisplayObject(object, context, _this.context, _this.restoreStack); | ||
// if we did a full screen rendering last frame | ||
_this.saveDirtyAABB(object); | ||
} | ||
// @ts-ignore | ||
var styleRenderer = this.context.styleRendererFactory[nodeName]; | ||
var generatePath = this.pathGeneratorFactory[nodeName]; | ||
// clip path | ||
var clipPath = object.parsedStyle.clipPath; | ||
if (clipPath) { | ||
this.applyWorldTransform(context, clipPath); | ||
// generate path in local space | ||
var _generatePath = this.pathGeneratorFactory[clipPath.nodeName]; | ||
if (_generatePath) { | ||
context.save(); | ||
// save clip | ||
restoreStack.push(object); | ||
context.beginPath(); | ||
_generatePath(context, clipPath.parsedStyle); | ||
context.closePath(); | ||
context.clip(); | ||
var sorted = object.sortable.sorted || object.childNodes; | ||
// should account for z-index | ||
sorted.forEach(function (child) { | ||
renderByZIndex(child, context); | ||
}); | ||
}; | ||
// render at the end of frame | ||
renderingService.hooks.endFrame.tap(CanvasRendererPlugin.tag, function () { | ||
var context = contextService.getContext(); | ||
// clear & clip dirty rectangle | ||
var dpr = contextService.getDPR(); | ||
mat4.fromScaling(_this.dprMatrix, vec3.fromValues(dpr, dpr, 1)); | ||
mat4.multiply(_this.vpMatrix, _this.dprMatrix, camera.getOrthoMatrix()); | ||
if (_this.clearFullScreen) { | ||
renderByZIndex(renderingContext.root, context); | ||
} else { | ||
// merge removed AABB | ||
var dirtyRenderBounds = _this.safeMergeAABB.apply(_this, [_this.mergeDirtyAABBs(_this.renderQueue)].concat(_this.removedRBushNodeAABBs.map(function (_ref2) { | ||
var minX = _ref2.minX, | ||
minY = _ref2.minY, | ||
maxX = _ref2.maxX, | ||
maxY = _ref2.maxY; | ||
var aabb = new AABB(); | ||
aabb.setMinMax(vec3.fromValues(minX, minY, 0), vec3.fromValues(maxX, maxY, 0)); | ||
return aabb; | ||
}))); | ||
_this.removedRBushNodeAABBs = []; | ||
if (AABB.isEmpty(dirtyRenderBounds)) { | ||
_this.renderQueue = []; | ||
return; | ||
} | ||
} | ||
// fill & stroke | ||
if (styleRenderer) { | ||
this.applyWorldTransform(context, object); | ||
var dirtyRect = _this.convertAABB2Rect(dirtyRenderBounds); | ||
var x = dirtyRect.x, | ||
y = dirtyRect.y, | ||
width = dirtyRect.width, | ||
height = dirtyRect.height; | ||
var tl = vec3.transformMat4(_this.vec3a, vec3.fromValues(x, y, 0), _this.vpMatrix); | ||
var tr = vec3.transformMat4(_this.vec3b, vec3.fromValues(x + width, y, 0), _this.vpMatrix); | ||
var bl = vec3.transformMat4(_this.vec3c, vec3.fromValues(x, y + height, 0), _this.vpMatrix); | ||
var br = vec3.transformMat4(_this.vec3d, vec3.fromValues(x + width, y + height, 0), _this.vpMatrix); | ||
var minx = Math.min(tl[0], tr[0], br[0], bl[0]); | ||
var miny = Math.min(tl[1], tr[1], br[1], bl[1]); | ||
var maxx = Math.max(tl[0], tr[0], br[0], bl[0]); | ||
var maxy = Math.max(tl[1], tr[1], br[1], bl[1]); | ||
var ix = Math.floor(minx); | ||
var iy = Math.floor(miny); | ||
var iwidth = Math.ceil(maxx - minx); | ||
var iheight = Math.ceil(maxy - miny); | ||
context.save(); | ||
// apply attributes to context | ||
this.applyAttributesToContext(context, object); | ||
} | ||
if (generatePath) { | ||
_this.clearRect(context, ix, iy, iwidth, iheight, config.background); | ||
context.beginPath(); | ||
generatePath(context, object.parsedStyle); | ||
if (object.nodeName !== Shape.LINE && object.nodeName !== Shape.PATH && object.nodeName !== Shape.POLYLINE) { | ||
context.closePath(); | ||
context.rect(ix, iy, iwidth, iheight); | ||
context.clip(); | ||
// @see https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Transformations | ||
context.setTransform(_this.vpMatrix[0], _this.vpMatrix[1], _this.vpMatrix[4], _this.vpMatrix[5], _this.vpMatrix[12], _this.vpMatrix[13]); | ||
// draw dirty rectangle | ||
var _config$renderer$getC = config.renderer.getConfig(), | ||
enableDirtyRectangleRenderingDebug = _config$renderer$getC.enableDirtyRectangleRenderingDebug; | ||
if (enableDirtyRectangleRenderingDebug) { | ||
canvas.dispatchEvent(new CustomEvent(CanvasEvent.DIRTY_RECTANGLE, { | ||
dirtyRect: { | ||
x: ix, | ||
y: iy, | ||
width: iwidth, | ||
height: iheight | ||
} | ||
})); | ||
} | ||
// search objects intersect with dirty rectangle | ||
var dirtyObjects = _this.searchDirtyObjects(dirtyRenderBounds); | ||
// do rendering | ||
dirtyObjects | ||
// sort by z-index | ||
.sort(function (a, b) { | ||
return a.sortable.renderOrder - b.sortable.renderOrder; | ||
}).forEach(function (object) { | ||
// culled object should not be rendered | ||
if (object && object.isVisible() && !object.isCulled()) { | ||
_this.renderDisplayObject(object, context, _this.context, _this.restoreStack); | ||
} | ||
}); | ||
context.restore(); | ||
// save dirty AABBs in last frame | ||
_this.renderQueue.forEach(function (object) { | ||
_this.saveDirtyAABB(object); | ||
}); | ||
// clear queue | ||
_this.renderQueue = []; | ||
} | ||
// fill & stroke | ||
if (styleRenderer) { | ||
styleRenderer.render(context, object.parsedStyle, object, canvasContext, this); | ||
// restore applied attributes, eg. shadowBlur shadowColor... | ||
// pop restore stack, eg. root -> parent -> child | ||
_this.restoreStack.forEach(function () { | ||
context.restore(); | ||
}); | ||
// clear restore stack | ||
_this.restoreStack = []; | ||
}); | ||
renderingService.hooks.render.tap(CanvasRendererPlugin.tag, function (object) { | ||
if (!_this.clearFullScreen) { | ||
// render at the end of frame | ||
_this.renderQueue.push(object); | ||
} | ||
// finish rendering, clear dirty flag | ||
object.renderable.dirty = false; | ||
}); | ||
}; | ||
_proto.clearRect = function clearRect(context, x, y, width, height, background) { | ||
// clearRect is faster than fillRect @see https://stackoverflow.com/a/30830253 | ||
context.clearRect(x, y, width, height); | ||
if (background) { | ||
context.fillStyle = background; | ||
context.fillRect(x, y, width, height); | ||
} | ||
}, { | ||
key: "convertAABB2Rect", | ||
value: function convertAABB2Rect(aabb) { | ||
var min = aabb.getMin(); | ||
var max = aabb.getMax(); | ||
// expand the rectangle a bit to avoid artifacts | ||
// @see https://www.yuque.com/antv/ou292n/bi8nix#ExvCu | ||
var minX = Math.floor(min[0]); | ||
var minY = Math.floor(min[1]); | ||
var maxX = Math.ceil(max[0]); | ||
var maxY = Math.ceil(max[1]); | ||
var width = maxX - minX; | ||
var height = maxY - minY; | ||
return { | ||
x: minX, | ||
y: minY, | ||
width: width, | ||
height: height | ||
}; | ||
}; | ||
_proto.renderDisplayObject = function renderDisplayObject(object, context, canvasContext, restoreStack) { | ||
var nodeName = object.nodeName; | ||
// restore to its ancestor | ||
var parent = restoreStack[restoreStack.length - 1]; | ||
if (parent && !(object.compareDocumentPosition(parent) & Node.DOCUMENT_POSITION_CONTAINS)) { | ||
context.restore(); | ||
restoreStack.pop(); | ||
} | ||
/** | ||
* TODO: merge dirty rectangles with some strategies. | ||
* For now, we just simply merge all the rectangles into one. | ||
* @see https://idom.me/articles/841.html | ||
*/ | ||
}, { | ||
key: "mergeDirtyAABBs", | ||
value: function mergeDirtyAABBs(dirtyObjects) { | ||
// merge into a big AABB | ||
// TODO: skip descendant if ancestor is caculated, but compareNodePosition is really slow | ||
var aabb = new AABB(); | ||
dirtyObjects.forEach(function (object) { | ||
var renderBounds = object.getRenderBounds(); | ||
aabb.add(renderBounds); | ||
var dirtyRenderBounds = object.renderable.dirtyRenderBounds; | ||
if (dirtyRenderBounds) { | ||
aabb.add(dirtyRenderBounds); | ||
} | ||
}); | ||
return aabb; | ||
// @ts-ignore | ||
var styleRenderer = this.context.styleRendererFactory[nodeName]; | ||
var generatePath = this.pathGeneratorFactory[nodeName]; | ||
// clip path | ||
var clipPath = object.parsedStyle.clipPath; | ||
if (clipPath) { | ||
this.applyWorldTransform(context, clipPath); | ||
// generate path in local space | ||
var _generatePath = this.pathGeneratorFactory[clipPath.nodeName]; | ||
if (_generatePath) { | ||
context.save(); | ||
// save clip | ||
restoreStack.push(object); | ||
context.beginPath(); | ||
_generatePath(context, clipPath.parsedStyle); | ||
context.closePath(); | ||
context.clip(); | ||
} | ||
} | ||
}, { | ||
key: "searchDirtyObjects", | ||
value: function searchDirtyObjects(dirtyRectangle) { | ||
// search in r-tree, get all affected nodes | ||
var _dirtyRectangle$getMi = dirtyRectangle.getMin(), | ||
_dirtyRectangle$getMi2 = _slicedToArray(_dirtyRectangle$getMi, 2), | ||
minX = _dirtyRectangle$getMi2[0], | ||
minY = _dirtyRectangle$getMi2[1]; | ||
var _dirtyRectangle$getMa = dirtyRectangle.getMax(), | ||
_dirtyRectangle$getMa2 = _slicedToArray(_dirtyRectangle$getMa, 2), | ||
maxX = _dirtyRectangle$getMa2[0], | ||
maxY = _dirtyRectangle$getMa2[1]; | ||
var rBushNodes = this.rBush.search({ | ||
minX: minX, | ||
minY: minY, | ||
maxX: maxX, | ||
maxY: maxY | ||
}); | ||
return rBushNodes.map(function (_ref3) { | ||
var id = _ref3.id; | ||
return runtime.displayObjectPool.getByEntity(id); | ||
}); | ||
// fill & stroke | ||
if (styleRenderer) { | ||
this.applyWorldTransform(context, object); | ||
context.save(); | ||
// apply attributes to context | ||
this.applyAttributesToContext(context, object); | ||
} | ||
}, { | ||
key: "saveDirtyAABB", | ||
value: function saveDirtyAABB(object) { | ||
var renderable = object.renderable; | ||
if (!renderable.dirtyRenderBounds) { | ||
renderable.dirtyRenderBounds = new AABB(); | ||
if (generatePath) { | ||
context.beginPath(); | ||
generatePath(context, object.parsedStyle); | ||
if (object.nodeName !== Shape.LINE && object.nodeName !== Shape.PATH && object.nodeName !== Shape.POLYLINE) { | ||
context.closePath(); | ||
} | ||
} | ||
// fill & stroke | ||
if (styleRenderer) { | ||
styleRenderer.render(context, object.parsedStyle, object, canvasContext, this); | ||
// restore applied attributes, eg. shadowBlur shadowColor... | ||
context.restore(); | ||
} | ||
// finish rendering, clear dirty flag | ||
object.renderable.dirty = false; | ||
}; | ||
_proto.convertAABB2Rect = function convertAABB2Rect(aabb) { | ||
var min = aabb.getMin(); | ||
var max = aabb.getMax(); | ||
// expand the rectangle a bit to avoid artifacts | ||
// @see https://www.yuque.com/antv/ou292n/bi8nix#ExvCu | ||
var minX = Math.floor(min[0]); | ||
var minY = Math.floor(min[1]); | ||
var maxX = Math.ceil(max[0]); | ||
var maxY = Math.ceil(max[1]); | ||
var width = maxX - minX; | ||
var height = maxY - minY; | ||
return { | ||
x: minX, | ||
y: minY, | ||
width: width, | ||
height: height | ||
}; | ||
} | ||
/** | ||
* TODO: merge dirty rectangles with some strategies. | ||
* For now, we just simply merge all the rectangles into one. | ||
* @see https://idom.me/articles/841.html | ||
*/; | ||
_proto.mergeDirtyAABBs = function mergeDirtyAABBs(dirtyObjects) { | ||
// merge into a big AABB | ||
// TODO: skip descendant if ancestor is caculated, but compareNodePosition is really slow | ||
var aabb = new AABB(); | ||
dirtyObjects.forEach(function (object) { | ||
var renderBounds = object.getRenderBounds(); | ||
if (renderBounds) { | ||
// save last dirty aabb | ||
renderable.dirtyRenderBounds.update(renderBounds.center, renderBounds.halfExtents); | ||
aabb.add(renderBounds); | ||
var dirtyRenderBounds = object.renderable.dirtyRenderBounds; | ||
if (dirtyRenderBounds) { | ||
aabb.add(dirtyRenderBounds); | ||
} | ||
}); | ||
return aabb; | ||
}; | ||
_proto.searchDirtyObjects = function searchDirtyObjects(dirtyRectangle) { | ||
// search in r-tree, get all affected nodes | ||
var _dirtyRectangle$getMi = dirtyRectangle.getMin(), | ||
minX = _dirtyRectangle$getMi[0], | ||
minY = _dirtyRectangle$getMi[1]; | ||
var _dirtyRectangle$getMa = dirtyRectangle.getMax(), | ||
maxX = _dirtyRectangle$getMa[0], | ||
maxY = _dirtyRectangle$getMa[1]; | ||
var rBushNodes = this.rBush.search({ | ||
minX: minX, | ||
minY: minY, | ||
maxX: maxX, | ||
maxY: maxY | ||
}); | ||
return rBushNodes.map(function (_ref3) { | ||
var id = _ref3.id; | ||
return runtime.displayObjectPool.getByEntity(id); | ||
}); | ||
}; | ||
_proto.saveDirtyAABB = function saveDirtyAABB(object) { | ||
var renderable = object.renderable; | ||
if (!renderable.dirtyRenderBounds) { | ||
renderable.dirtyRenderBounds = new AABB(); | ||
} | ||
/** | ||
* TODO: batch the same global attributes | ||
*/ | ||
}, { | ||
key: "applyAttributesToContext", | ||
value: function applyAttributesToContext(context, object) { | ||
var _object$parsedStyle = object.parsedStyle, | ||
stroke = _object$parsedStyle.stroke, | ||
fill = _object$parsedStyle.fill, | ||
opacity = _object$parsedStyle.opacity, | ||
lineDash = _object$parsedStyle.lineDash, | ||
lineDashOffset = _object$parsedStyle.lineDashOffset; | ||
// @see https://developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D/setLineDash | ||
if (lineDash) { | ||
context.setLineDash(lineDash); | ||
} | ||
// @see https://developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D/lineDashOffset | ||
if (!isNil(lineDashOffset)) { | ||
context.lineDashOffset = lineDashOffset; | ||
} | ||
if (!isNil(opacity)) { | ||
context.globalAlpha *= opacity; | ||
} | ||
if (!isNil(stroke) && !Array.isArray(stroke) && !stroke.isNone) { | ||
context.strokeStyle = object.attributes.stroke; | ||
} | ||
if (!isNil(fill) && !Array.isArray(fill) && !fill.isNone) { | ||
context.fillStyle = object.attributes.fill; | ||
} | ||
var renderBounds = object.getRenderBounds(); | ||
if (renderBounds) { | ||
// save last dirty aabb | ||
renderable.dirtyRenderBounds.update(renderBounds.center, renderBounds.halfExtents); | ||
} | ||
}, { | ||
key: "applyWorldTransform", | ||
value: function applyWorldTransform(context, object, matrix) { | ||
var tx = 0; | ||
var ty = 0; | ||
var _ref4 = object.parsedStyle || {}, | ||
anchor = _ref4.anchor; | ||
var anchorX = anchor && anchor[0] || 0; | ||
var anchorY = anchor && anchor[1] || 0; | ||
if (anchorX !== 0 || anchorY !== 0) { | ||
var bounds = object.getGeometryBounds(); | ||
var width = bounds && bounds.halfExtents[0] * 2 || 0; | ||
var height = bounds && bounds.halfExtents[1] * 2 || 0; | ||
tx = -(anchorX * width); | ||
ty = -(anchorY * height); | ||
} | ||
// apply clip shape's RTS | ||
if (matrix) { | ||
mat4.copy(this.tmpMat4, object.getLocalTransform()); | ||
this.vec3a[0] = tx; | ||
this.vec3a[1] = ty; | ||
this.vec3a[2] = 0; | ||
mat4.translate(this.tmpMat4, this.tmpMat4, this.vec3a); | ||
mat4.multiply(this.tmpMat4, matrix, this.tmpMat4); | ||
mat4.multiply(this.tmpMat4, this.vpMatrix, this.tmpMat4); | ||
} else { | ||
// apply RTS transformation in world space | ||
mat4.copy(this.tmpMat4, object.getWorldTransform()); | ||
this.vec3a[0] = tx; | ||
this.vec3a[1] = ty; | ||
this.vec3a[2] = 0; | ||
mat4.translate(this.tmpMat4, this.tmpMat4, this.vec3a); | ||
mat4.multiply(this.tmpMat4, this.vpMatrix, this.tmpMat4); | ||
} | ||
// @see https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Transformations | ||
context.setTransform(this.tmpMat4[0], this.tmpMat4[1], this.tmpMat4[4], this.tmpMat4[5], this.tmpMat4[12], this.tmpMat4[13]); | ||
} | ||
/** | ||
* TODO: batch the same global attributes | ||
*/; | ||
_proto.applyAttributesToContext = function applyAttributesToContext(context, object) { | ||
var _object$parsedStyle = object.parsedStyle, | ||
stroke = _object$parsedStyle.stroke, | ||
fill = _object$parsedStyle.fill, | ||
opacity = _object$parsedStyle.opacity, | ||
lineDash = _object$parsedStyle.lineDash, | ||
lineDashOffset = _object$parsedStyle.lineDashOffset; | ||
// @see https://developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D/setLineDash | ||
if (lineDash) { | ||
context.setLineDash(lineDash); | ||
} | ||
}, { | ||
key: "safeMergeAABB", | ||
value: function safeMergeAABB() { | ||
var merged = new AABB(); | ||
for (var _len = arguments.length, aabbs = new Array(_len), _key = 0; _key < _len; _key++) { | ||
aabbs[_key] = arguments[_key]; | ||
} | ||
aabbs.forEach(function (aabb) { | ||
merged.add(aabb); | ||
}); | ||
return merged; | ||
// @see https://developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D/lineDashOffset | ||
if (!isNil(lineDashOffset)) { | ||
context.lineDashOffset = lineDashOffset; | ||
} | ||
}]); | ||
if (!isNil(opacity)) { | ||
context.globalAlpha *= opacity; | ||
} | ||
if (!isNil(stroke) && !Array.isArray(stroke) && !stroke.isNone) { | ||
context.strokeStyle = object.attributes.stroke; | ||
} | ||
if (!isNil(fill) && !Array.isArray(fill) && !fill.isNone) { | ||
context.fillStyle = object.attributes.fill; | ||
} | ||
}; | ||
_proto.applyWorldTransform = function applyWorldTransform(context, object, matrix) { | ||
var tx = 0; | ||
var ty = 0; | ||
var _ref4 = object.parsedStyle || {}, | ||
anchor = _ref4.anchor; | ||
var anchorX = anchor && anchor[0] || 0; | ||
var anchorY = anchor && anchor[1] || 0; | ||
if (anchorX !== 0 || anchorY !== 0) { | ||
var bounds = object.getGeometryBounds(); | ||
var width = bounds && bounds.halfExtents[0] * 2 || 0; | ||
var height = bounds && bounds.halfExtents[1] * 2 || 0; | ||
tx = -(anchorX * width); | ||
ty = -(anchorY * height); | ||
} | ||
// apply clip shape's RTS | ||
if (matrix) { | ||
mat4.copy(this.tmpMat4, object.getLocalTransform()); | ||
this.vec3a[0] = tx; | ||
this.vec3a[1] = ty; | ||
this.vec3a[2] = 0; | ||
mat4.translate(this.tmpMat4, this.tmpMat4, this.vec3a); | ||
mat4.multiply(this.tmpMat4, matrix, this.tmpMat4); | ||
mat4.multiply(this.tmpMat4, this.vpMatrix, this.tmpMat4); | ||
} else { | ||
// apply RTS transformation in world space | ||
mat4.copy(this.tmpMat4, object.getWorldTransform()); | ||
this.vec3a[0] = tx; | ||
this.vec3a[1] = ty; | ||
this.vec3a[2] = 0; | ||
mat4.translate(this.tmpMat4, this.tmpMat4, this.vec3a); | ||
mat4.multiply(this.tmpMat4, this.vpMatrix, this.tmpMat4); | ||
} | ||
// @see https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Transformations | ||
context.setTransform(this.tmpMat4[0], this.tmpMat4[1], this.tmpMat4[4], this.tmpMat4[5], this.tmpMat4[12], this.tmpMat4[13]); | ||
}; | ||
_proto.safeMergeAABB = function safeMergeAABB() { | ||
var merged = new AABB(); | ||
for (var _len = arguments.length, aabbs = new Array(_len), _key = 0; _key < _len; _key++) { | ||
aabbs[_key] = arguments[_key]; | ||
} | ||
aabbs.forEach(function (aabb) { | ||
merged.add(aabb); | ||
}); | ||
return merged; | ||
}; | ||
return CanvasRendererPlugin; | ||
@@ -984,163 +787,150 @@ }(); | ||
function DefaultRenderer(imagePool) { | ||
_classCallCheck(this, DefaultRenderer); | ||
this.imagePool = void 0; | ||
this.imagePool = imagePool; | ||
} | ||
_createClass(DefaultRenderer, [{ | ||
key: "render", | ||
value: function render(context, parsedStyle, object, canvasContext, plugin) { | ||
var fill = parsedStyle.fill, | ||
fillRule = parsedStyle.fillRule, | ||
opacity = parsedStyle.opacity, | ||
fillOpacity = parsedStyle.fillOpacity, | ||
stroke = parsedStyle.stroke, | ||
strokeOpacity = parsedStyle.strokeOpacity, | ||
lineWidth = parsedStyle.lineWidth, | ||
lineCap = parsedStyle.lineCap, | ||
lineJoin = parsedStyle.lineJoin, | ||
shadowType = parsedStyle.shadowType, | ||
shadowColor = parsedStyle.shadowColor, | ||
shadowBlur = parsedStyle.shadowBlur, | ||
filter = parsedStyle.filter, | ||
miterLimit = parsedStyle.miterLimit; | ||
var hasFill = !isNil(fill) && !fill.isNone; | ||
var hasStroke = !isNil(stroke) && !stroke.isNone && lineWidth > 0; | ||
var isFillTransparent = fill.alpha === 0; | ||
var hasFilter = !!(filter && filter.length); | ||
var hasShadow = !isNil(shadowColor) && shadowBlur > 0; | ||
var nodeName = object.nodeName; | ||
var isInnerShadow = shadowType === 'inner'; | ||
var shouldDrawShadowWithStroke = hasStroke && hasShadow && (nodeName === Shape.PATH || nodeName === Shape.LINE || nodeName === Shape.POLYLINE || isFillTransparent || isInnerShadow); | ||
if (hasFill) { | ||
context.globalAlpha = opacity * fillOpacity; | ||
if (!shouldDrawShadowWithStroke) { | ||
setShadowAndFilter(object, context, hasShadow); | ||
} | ||
this.fill(context, object, fill, fillRule, canvasContext, plugin); | ||
if (!shouldDrawShadowWithStroke) { | ||
this.clearShadowAndFilter(context, hasFilter, hasShadow); | ||
} | ||
var _proto = DefaultRenderer.prototype; | ||
_proto.render = function render(context, parsedStyle, object, canvasContext, plugin) { | ||
var fill = parsedStyle.fill, | ||
fillRule = parsedStyle.fillRule, | ||
opacity = parsedStyle.opacity, | ||
fillOpacity = parsedStyle.fillOpacity, | ||
stroke = parsedStyle.stroke, | ||
strokeOpacity = parsedStyle.strokeOpacity, | ||
lineWidth = parsedStyle.lineWidth, | ||
lineCap = parsedStyle.lineCap, | ||
lineJoin = parsedStyle.lineJoin, | ||
shadowType = parsedStyle.shadowType, | ||
shadowColor = parsedStyle.shadowColor, | ||
shadowBlur = parsedStyle.shadowBlur, | ||
filter = parsedStyle.filter, | ||
miterLimit = parsedStyle.miterLimit; | ||
var hasFill = !isNil(fill) && !fill.isNone; | ||
var hasStroke = !isNil(stroke) && !stroke.isNone && lineWidth > 0; | ||
var isFillTransparent = fill.alpha === 0; | ||
var hasFilter = !!(filter && filter.length); | ||
var hasShadow = !isNil(shadowColor) && shadowBlur > 0; | ||
var nodeName = object.nodeName; | ||
var isInnerShadow = shadowType === 'inner'; | ||
var shouldDrawShadowWithStroke = hasStroke && hasShadow && (nodeName === Shape.PATH || nodeName === Shape.LINE || nodeName === Shape.POLYLINE || isFillTransparent || isInnerShadow); | ||
if (hasFill) { | ||
context.globalAlpha = opacity * fillOpacity; | ||
if (!shouldDrawShadowWithStroke) { | ||
setShadowAndFilter(object, context, hasShadow); | ||
} | ||
if (hasStroke) { | ||
context.globalAlpha = opacity * strokeOpacity; | ||
context.lineWidth = lineWidth; | ||
if (!isNil(miterLimit)) { | ||
context.miterLimit = miterLimit; | ||
} | ||
if (!isNil(lineCap)) { | ||
context.lineCap = lineCap; | ||
} | ||
if (!isNil(lineJoin)) { | ||
context.lineJoin = lineJoin; | ||
} | ||
if (shouldDrawShadowWithStroke) { | ||
if (isInnerShadow) { | ||
context.globalCompositeOperation = 'source-atop'; | ||
} | ||
setShadowAndFilter(object, context, true); | ||
if (isInnerShadow) { | ||
this.stroke(context, object, stroke, canvasContext, plugin); | ||
context.globalCompositeOperation = 'source-over'; | ||
this.clearShadowAndFilter(context, hasFilter, true); | ||
} | ||
} | ||
this.stroke(context, object, stroke, canvasContext, plugin); | ||
this.fill(context, object, fill, fillRule, canvasContext, plugin); | ||
if (!shouldDrawShadowWithStroke) { | ||
this.clearShadowAndFilter(context, hasFilter, hasShadow); | ||
} | ||
} | ||
}, { | ||
key: "clearShadowAndFilter", | ||
value: function clearShadowAndFilter(context, hasFilter, hasShadow) { | ||
if (hasShadow) { | ||
context.shadowColor = 'transparent'; | ||
context.shadowBlur = 0; | ||
if (hasStroke) { | ||
context.globalAlpha = opacity * strokeOpacity; | ||
context.lineWidth = lineWidth; | ||
if (!isNil(miterLimit)) { | ||
context.miterLimit = miterLimit; | ||
} | ||
if (hasFilter) { | ||
// save drop-shadow filter | ||
var oldFilter = context.filter; | ||
if (!isNil(oldFilter) && oldFilter.indexOf('drop-shadow') > -1) { | ||
context.filter = oldFilter.replace(/drop-shadow\([^)]*\)/, '').trim() || 'none'; | ||
if (!isNil(lineCap)) { | ||
context.lineCap = lineCap; | ||
} | ||
if (!isNil(lineJoin)) { | ||
context.lineJoin = lineJoin; | ||
} | ||
if (shouldDrawShadowWithStroke) { | ||
if (isInnerShadow) { | ||
context.globalCompositeOperation = 'source-atop'; | ||
} | ||
setShadowAndFilter(object, context, true); | ||
if (isInnerShadow) { | ||
this.stroke(context, object, stroke, canvasContext, plugin); | ||
context.globalCompositeOperation = 'source-over'; | ||
this.clearShadowAndFilter(context, hasFilter, true); | ||
} | ||
} | ||
this.stroke(context, object, stroke, canvasContext, plugin); | ||
} | ||
}, { | ||
key: "fill", | ||
value: function fill(context, object, _fill, fillRule, canvasContext, plugin) { | ||
var _this = this; | ||
if (Array.isArray(_fill)) { | ||
_fill.forEach(function (gradient) { | ||
context.fillStyle = _this.getColor(gradient, object, context); | ||
context.fill(fillRule); | ||
}); | ||
} else { | ||
if (isPattern(_fill)) { | ||
context.fillStyle = this.getPattern(_fill, object, context, canvasContext, plugin); | ||
} | ||
}; | ||
_proto.clearShadowAndFilter = function clearShadowAndFilter(context, hasFilter, hasShadow) { | ||
if (hasShadow) { | ||
context.shadowColor = 'transparent'; | ||
context.shadowBlur = 0; | ||
} | ||
if (hasFilter) { | ||
// save drop-shadow filter | ||
var oldFilter = context.filter; | ||
if (!isNil(oldFilter) && oldFilter.indexOf('drop-shadow') > -1) { | ||
context.filter = oldFilter.replace(/drop-shadow\([^)]*\)/, '').trim() || 'none'; | ||
} | ||
} | ||
}; | ||
_proto.fill = function fill(context, object, _fill, fillRule, canvasContext, plugin) { | ||
var _this = this; | ||
if (Array.isArray(_fill)) { | ||
_fill.forEach(function (gradient) { | ||
context.fillStyle = _this.getColor(gradient, object, context); | ||
context.fill(fillRule); | ||
}); | ||
} else { | ||
if (isPattern(_fill)) { | ||
context.fillStyle = this.getPattern(_fill, object, context, canvasContext, plugin); | ||
} | ||
context.fill(fillRule); | ||
} | ||
}, { | ||
key: "stroke", | ||
value: function stroke(context, object, _stroke, canvasContext, plugin) { | ||
var _this2 = this; | ||
if (Array.isArray(_stroke)) { | ||
_stroke.forEach(function (gradient) { | ||
context.strokeStyle = _this2.getColor(gradient, object, context); | ||
context.stroke(); | ||
}); | ||
} else { | ||
if (isPattern(_stroke)) { | ||
context.strokeStyle = this.getPattern(_stroke, object, context, canvasContext, plugin); | ||
} | ||
}; | ||
_proto.stroke = function stroke(context, object, _stroke, canvasContext, plugin) { | ||
var _this2 = this; | ||
if (Array.isArray(_stroke)) { | ||
_stroke.forEach(function (gradient) { | ||
context.strokeStyle = _this2.getColor(gradient, object, context); | ||
context.stroke(); | ||
}); | ||
} else { | ||
if (isPattern(_stroke)) { | ||
context.strokeStyle = this.getPattern(_stroke, object, context, canvasContext, plugin); | ||
} | ||
context.stroke(); | ||
} | ||
}, { | ||
key: "getPattern", | ||
value: function getPattern(pattern, object, context, canvasContext, plugin) { | ||
var $offscreenCanvas; | ||
var dpr; | ||
if (pattern.image instanceof Rect) { | ||
var _pattern$image$parsed = pattern.image.parsedStyle, | ||
width = _pattern$image$parsed.width, | ||
height = _pattern$image$parsed.height; | ||
dpr = canvasContext.contextService.getDPR(); | ||
var offscreenCanvas = canvasContext.config.offscreenCanvas; | ||
$offscreenCanvas = runtime.offscreenCanvas.getOrCreateCanvas(offscreenCanvas); | ||
$offscreenCanvas.width = width * dpr; | ||
$offscreenCanvas.height = height * dpr; | ||
var offscreenCanvasContext = runtime.offscreenCanvas.getOrCreateContext(offscreenCanvas); | ||
var restoreStack = []; | ||
// offscreenCanvasContext.scale(1 / dpr, 1 / dpr); | ||
pattern.image.forEach(function (object) { | ||
plugin.renderDisplayObject(object, offscreenCanvasContext, canvasContext, restoreStack); | ||
}); | ||
restoreStack.forEach(function () { | ||
offscreenCanvasContext.restore(); | ||
}); | ||
} | ||
var canvasPattern = this.imagePool.getOrCreatePatternSync(pattern, context, $offscreenCanvas, dpr, function () { | ||
// set dirty rectangle flag | ||
object.renderable.dirty = true; | ||
canvasContext.renderingService.dirtify(); | ||
}; | ||
_proto.getPattern = function getPattern(pattern, object, context, canvasContext, plugin) { | ||
var $offscreenCanvas; | ||
var dpr; | ||
if (pattern.image instanceof Rect) { | ||
var _pattern$image$parsed = pattern.image.parsedStyle, | ||
width = _pattern$image$parsed.width, | ||
height = _pattern$image$parsed.height; | ||
dpr = canvasContext.contextService.getDPR(); | ||
var offscreenCanvas = canvasContext.config.offscreenCanvas; | ||
$offscreenCanvas = runtime.offscreenCanvas.getOrCreateCanvas(offscreenCanvas); | ||
$offscreenCanvas.width = width * dpr; | ||
$offscreenCanvas.height = height * dpr; | ||
var offscreenCanvasContext = runtime.offscreenCanvas.getOrCreateContext(offscreenCanvas); | ||
var restoreStack = []; | ||
// offscreenCanvasContext.scale(1 / dpr, 1 / dpr); | ||
pattern.image.forEach(function (object) { | ||
plugin.renderDisplayObject(object, offscreenCanvasContext, canvasContext, restoreStack); | ||
}); | ||
return canvasPattern; | ||
restoreStack.forEach(function () { | ||
offscreenCanvasContext.restore(); | ||
}); | ||
} | ||
}, { | ||
key: "getColor", | ||
value: function getColor(parsedColor, object, context) { | ||
var color; | ||
if (parsedColor.type === GradientType.LinearGradient || parsedColor.type === GradientType.RadialGradient) { | ||
var bounds = object.getGeometryBounds(); | ||
var width = bounds && bounds.halfExtents[0] * 2 || 1; | ||
var height = bounds && bounds.halfExtents[1] * 2 || 1; | ||
color = this.imagePool.getOrCreateGradient(_objectSpread2(_objectSpread2({ | ||
type: parsedColor.type | ||
}, parsedColor.value), {}, { | ||
width: width, | ||
height: height | ||
}), context); | ||
} | ||
return color; | ||
var canvasPattern = this.imagePool.getOrCreatePatternSync(pattern, context, $offscreenCanvas, dpr, function () { | ||
// set dirty rectangle flag | ||
object.renderable.dirty = true; | ||
canvasContext.renderingService.dirtify(); | ||
}); | ||
return canvasPattern; | ||
}; | ||
_proto.getColor = function getColor(parsedColor, object, context) { | ||
var color; | ||
if (parsedColor.type === GradientType.LinearGradient || parsedColor.type === GradientType.RadialGradient) { | ||
var bounds = object.getGeometryBounds(); | ||
var width = bounds && bounds.halfExtents[0] * 2 || 1; | ||
var height = bounds && bounds.halfExtents[1] * 2 || 1; | ||
color = this.imagePool.getOrCreateGradient(_extends({ | ||
type: parsedColor.type | ||
}, parsedColor.value, { | ||
width: width, | ||
height: height | ||
}), context); | ||
} | ||
}]); | ||
return color; | ||
}; | ||
return DefaultRenderer; | ||
@@ -1172,36 +962,33 @@ }(); | ||
function ImageRenderer(imagePool) { | ||
_classCallCheck(this, ImageRenderer); | ||
this.imagePool = void 0; | ||
this.imagePool = imagePool; | ||
} | ||
_createClass(ImageRenderer, [{ | ||
key: "render", | ||
value: function render(context, parsedStyle, object) { | ||
var width = parsedStyle.width, | ||
height = parsedStyle.height, | ||
img = parsedStyle.img, | ||
shadowColor = parsedStyle.shadowColor, | ||
shadowBlur = parsedStyle.shadowBlur; | ||
var image; | ||
var iw = width; | ||
var ih = height; | ||
if (isString(img)) { | ||
// image has been loaded in `mounted` hook | ||
image = this.imagePool.getImageSync(img); | ||
} else { | ||
iw || (iw = img.width); | ||
ih || (ih = img.height); | ||
image = img; | ||
} | ||
if (image) { | ||
var hasShadow = !isNil(shadowColor) && shadowBlur > 0; | ||
setShadowAndFilter(object, context, hasShadow); | ||
// node-canvas will throw the following err: | ||
// Error: Image given has not completed loading | ||
try { | ||
context.drawImage(image, 0, 0, iw, ih); | ||
} catch (e) {} | ||
} | ||
var _proto = ImageRenderer.prototype; | ||
_proto.render = function render(context, parsedStyle, object) { | ||
var width = parsedStyle.width, | ||
height = parsedStyle.height, | ||
img = parsedStyle.img, | ||
shadowColor = parsedStyle.shadowColor, | ||
shadowBlur = parsedStyle.shadowBlur; | ||
var image; | ||
var iw = width; | ||
var ih = height; | ||
if (isString(img)) { | ||
// image has been loaded in `mounted` hook | ||
image = this.imagePool.getImageSync(img); | ||
} else { | ||
iw || (iw = img.width); | ||
ih || (ih = img.height); | ||
image = img; | ||
} | ||
}]); | ||
if (image) { | ||
var hasShadow = !isNil(shadowColor) && shadowBlur > 0; | ||
setShadowAndFilter(object, context, hasShadow); | ||
// node-canvas will throw the following err: | ||
// Error: Image given has not completed loading | ||
try { | ||
context.drawImage(image, 0, 0, iw, ih); | ||
} catch (e) {} | ||
} | ||
}; | ||
return ImageRenderer; | ||
@@ -1211,132 +998,124 @@ }(); | ||
var TextRenderer = /*#__PURE__*/function () { | ||
function TextRenderer() { | ||
_classCallCheck(this, TextRenderer); | ||
} | ||
_createClass(TextRenderer, [{ | ||
key: "render", | ||
value: function render(context, parsedStyle, object) { | ||
var lineWidth = parsedStyle.lineWidth, | ||
textAlign = parsedStyle.textAlign, | ||
textBaseline = parsedStyle.textBaseline, | ||
lineJoin = parsedStyle.lineJoin, | ||
miterLimit = parsedStyle.miterLimit, | ||
letterSpacing = parsedStyle.letterSpacing, | ||
stroke = parsedStyle.stroke, | ||
fill = parsedStyle.fill, | ||
fillOpacity = parsedStyle.fillOpacity, | ||
strokeOpacity = parsedStyle.strokeOpacity, | ||
opacity = parsedStyle.opacity, | ||
metrics = parsedStyle.metrics, | ||
dx = parsedStyle.dx, | ||
dy = parsedStyle.dy, | ||
shadowColor = parsedStyle.shadowColor, | ||
shadowBlur = parsedStyle.shadowBlur; | ||
var font = metrics.font, | ||
lines = metrics.lines, | ||
height = metrics.height, | ||
lineHeight = metrics.lineHeight, | ||
lineMetrics = metrics.lineMetrics; | ||
context.font = font; | ||
context.lineWidth = lineWidth; | ||
context.textAlign = textAlign === 'middle' ? 'center' : textAlign; | ||
context.textBaseline = textBaseline; | ||
context.lineJoin = lineJoin; | ||
if (!isNil(miterLimit)) { | ||
context.miterLimit = miterLimit; | ||
} | ||
var linePositionY = 0; | ||
// handle vertical text baseline | ||
if (textBaseline === 'middle') { | ||
linePositionY = -height / 2 - lineHeight / 2; | ||
} else if (textBaseline === 'bottom' || textBaseline === 'alphabetic' || textBaseline === 'ideographic') { | ||
linePositionY = -height; | ||
} else if (textBaseline === 'top' || textBaseline === 'hanging') { | ||
linePositionY = -lineHeight; | ||
} | ||
// account for dx & dy | ||
var offsetX = dx || 0; | ||
linePositionY += dy || 0; | ||
var hasShadow = !isNil(shadowColor) && shadowBlur > 0; | ||
setShadowAndFilter(object, context, hasShadow); | ||
// draw lines line by line | ||
for (var i = 0; i < lines.length; i++) { | ||
var linePositionX = lineWidth / 2 + offsetX; | ||
linePositionY += lineHeight; | ||
// no need to re-position X, cause we already set text align | ||
// @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textAlign | ||
if (!isNil(stroke) && !stroke.isNone && lineWidth) { | ||
this.drawLetterSpacing(context, lines[i], lineMetrics[i], textAlign, linePositionX, linePositionY, letterSpacing, fillOpacity, strokeOpacity, opacity, true); | ||
} | ||
if (!isNil(fill)) { | ||
this.drawLetterSpacing(context, lines[i], lineMetrics[i], textAlign, linePositionX, linePositionY, letterSpacing, fillOpacity, strokeOpacity, opacity); | ||
} | ||
} | ||
function TextRenderer() {} | ||
var _proto = TextRenderer.prototype; | ||
_proto.render = function render(context, parsedStyle, object) { | ||
var lineWidth = parsedStyle.lineWidth, | ||
textAlign = parsedStyle.textAlign, | ||
textBaseline = parsedStyle.textBaseline, | ||
lineJoin = parsedStyle.lineJoin, | ||
miterLimit = parsedStyle.miterLimit, | ||
letterSpacing = parsedStyle.letterSpacing, | ||
stroke = parsedStyle.stroke, | ||
fill = parsedStyle.fill, | ||
fillOpacity = parsedStyle.fillOpacity, | ||
strokeOpacity = parsedStyle.strokeOpacity, | ||
opacity = parsedStyle.opacity, | ||
metrics = parsedStyle.metrics, | ||
dx = parsedStyle.dx, | ||
dy = parsedStyle.dy, | ||
shadowColor = parsedStyle.shadowColor, | ||
shadowBlur = parsedStyle.shadowBlur; | ||
var font = metrics.font, | ||
lines = metrics.lines, | ||
height = metrics.height, | ||
lineHeight = metrics.lineHeight, | ||
lineMetrics = metrics.lineMetrics; | ||
context.font = font; | ||
context.lineWidth = lineWidth; | ||
context.textAlign = textAlign === 'middle' ? 'center' : textAlign; | ||
context.textBaseline = textBaseline; | ||
context.lineJoin = lineJoin; | ||
if (!isNil(miterLimit)) { | ||
context.miterLimit = miterLimit; | ||
} | ||
}, { | ||
key: "drawLetterSpacing", | ||
value: function drawLetterSpacing(context, text, lineMetrics, textAlign, x, y, letterSpacing, fillOpacity, strokeOpacity, opacity) { | ||
var isStroke = arguments.length > 10 && arguments[10] !== undefined ? arguments[10] : false; | ||
// letterSpacing of 0 means normal, render all texts directly | ||
if (letterSpacing === 0) { | ||
if (isStroke) { | ||
this.strokeText(context, text, x, y, strokeOpacity); | ||
} else { | ||
this.fillText(context, text, x, y, fillOpacity, opacity); | ||
} | ||
return; | ||
var linePositionY = 0; | ||
// handle vertical text baseline | ||
if (textBaseline === 'middle') { | ||
linePositionY = -height / 2 - lineHeight / 2; | ||
} else if (textBaseline === 'bottom' || textBaseline === 'alphabetic' || textBaseline === 'ideographic') { | ||
linePositionY = -height; | ||
} else if (textBaseline === 'top' || textBaseline === 'hanging') { | ||
linePositionY = -lineHeight; | ||
} | ||
// account for dx & dy | ||
var offsetX = dx || 0; | ||
linePositionY += dy || 0; | ||
var hasShadow = !isNil(shadowColor) && shadowBlur > 0; | ||
setShadowAndFilter(object, context, hasShadow); | ||
// draw lines line by line | ||
for (var i = 0; i < lines.length; i++) { | ||
var linePositionX = lineWidth / 2 + offsetX; | ||
linePositionY += lineHeight; | ||
// no need to re-position X, cause we already set text align | ||
// @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textAlign | ||
if (!isNil(stroke) && !stroke.isNone && lineWidth) { | ||
this.drawLetterSpacing(context, lines[i], lineMetrics[i], textAlign, linePositionX, linePositionY, letterSpacing, fillOpacity, strokeOpacity, opacity, true); | ||
} | ||
// draw text using left align | ||
var currentTextAlign = context.textAlign; | ||
context.textAlign = 'left'; | ||
var currentPosition = x; | ||
if (textAlign === 'center' || textAlign === 'middle') { | ||
currentPosition = x - lineMetrics.width / 2; | ||
} else if (textAlign === 'right' || textAlign === 'end') { | ||
currentPosition = x - lineMetrics.width; | ||
if (!isNil(fill)) { | ||
this.drawLetterSpacing(context, lines[i], lineMetrics[i], textAlign, linePositionX, linePositionY, letterSpacing, fillOpacity, strokeOpacity, opacity); | ||
} | ||
var stringArray = Array.from(text); | ||
var previousWidth = context.measureText(text).width; | ||
var currentWidth = 0; | ||
for (var i = 0; i < stringArray.length; ++i) { | ||
var currentChar = stringArray[i]; | ||
if (isStroke) { | ||
this.strokeText(context, currentChar, currentPosition, y, strokeOpacity); | ||
} else { | ||
this.fillText(context, currentChar, currentPosition, y, fillOpacity, opacity); | ||
} | ||
currentWidth = context.measureText(text.substring(i + 1)).width; | ||
currentPosition += previousWidth - currentWidth + letterSpacing; | ||
previousWidth = currentWidth; | ||
} | ||
context.textAlign = currentTextAlign; | ||
} | ||
}, { | ||
key: "fillText", | ||
value: function fillText(context, text, x, y, fillOpacity, opacity) { | ||
var currentGlobalAlpha; | ||
var applyOpacity = !isNil(fillOpacity) && fillOpacity !== 1; | ||
if (applyOpacity) { | ||
currentGlobalAlpha = context.globalAlpha; | ||
context.globalAlpha = fillOpacity * opacity; | ||
}; | ||
_proto.drawLetterSpacing = function drawLetterSpacing(context, text, lineMetrics, textAlign, x, y, letterSpacing, fillOpacity, strokeOpacity, opacity, isStroke) { | ||
if (isStroke === void 0) { | ||
isStroke = false; | ||
} | ||
// letterSpacing of 0 means normal, render all texts directly | ||
if (letterSpacing === 0) { | ||
if (isStroke) { | ||
this.strokeText(context, text, x, y, strokeOpacity); | ||
} else { | ||
this.fillText(context, text, x, y, fillOpacity, opacity); | ||
} | ||
context.fillText(text, x, y); | ||
if (applyOpacity) { | ||
context.globalAlpha = currentGlobalAlpha; | ||
} | ||
return; | ||
} | ||
}, { | ||
key: "strokeText", | ||
value: function strokeText(context, text, x, y, strokeOpacity) { | ||
var currentGlobalAlpha; | ||
var applyOpacity = !isNil(strokeOpacity) && strokeOpacity !== 1; | ||
if (applyOpacity) { | ||
currentGlobalAlpha = context.globalAlpha; | ||
context.globalAlpha = strokeOpacity; | ||
// draw text using left align | ||
var currentTextAlign = context.textAlign; | ||
context.textAlign = 'left'; | ||
var currentPosition = x; | ||
if (textAlign === 'center' || textAlign === 'middle') { | ||
currentPosition = x - lineMetrics.width / 2; | ||
} else if (textAlign === 'right' || textAlign === 'end') { | ||
currentPosition = x - lineMetrics.width; | ||
} | ||
var stringArray = Array.from(text); | ||
var previousWidth = context.measureText(text).width; | ||
var currentWidth = 0; | ||
for (var i = 0; i < stringArray.length; ++i) { | ||
var currentChar = stringArray[i]; | ||
if (isStroke) { | ||
this.strokeText(context, currentChar, currentPosition, y, strokeOpacity); | ||
} else { | ||
this.fillText(context, currentChar, currentPosition, y, fillOpacity, opacity); | ||
} | ||
context.strokeText(text, x, y); | ||
if (applyOpacity) { | ||
context.globalAlpha = currentGlobalAlpha; | ||
} | ||
currentWidth = context.measureText(text.substring(i + 1)).width; | ||
currentPosition += previousWidth - currentWidth + letterSpacing; | ||
previousWidth = currentWidth; | ||
} | ||
}]); | ||
context.textAlign = currentTextAlign; | ||
}; | ||
_proto.fillText = function fillText(context, text, x, y, fillOpacity, opacity) { | ||
var currentGlobalAlpha; | ||
var applyOpacity = !isNil(fillOpacity) && fillOpacity !== 1; | ||
if (applyOpacity) { | ||
currentGlobalAlpha = context.globalAlpha; | ||
context.globalAlpha = fillOpacity * opacity; | ||
} | ||
context.fillText(text, x, y); | ||
if (applyOpacity) { | ||
context.globalAlpha = currentGlobalAlpha; | ||
} | ||
}; | ||
_proto.strokeText = function strokeText(context, text, x, y, strokeOpacity) { | ||
var currentGlobalAlpha; | ||
var applyOpacity = !isNil(strokeOpacity) && strokeOpacity !== 1; | ||
if (applyOpacity) { | ||
currentGlobalAlpha = context.globalAlpha; | ||
context.globalAlpha = strokeOpacity; | ||
} | ||
context.strokeText(text, x, y); | ||
if (applyOpacity) { | ||
context.globalAlpha = currentGlobalAlpha; | ||
} | ||
}; | ||
return TextRenderer; | ||
@@ -1346,79 +1125,65 @@ }(); | ||
var RectRenderer = /*#__PURE__*/function (_DefaultRenderer) { | ||
_inherits(RectRenderer, _DefaultRenderer); | ||
var _super = _createSuper(RectRenderer); | ||
_inheritsLoose(RectRenderer, _DefaultRenderer); | ||
function RectRenderer() { | ||
_classCallCheck(this, RectRenderer); | ||
return _super.apply(this, arguments); | ||
return _DefaultRenderer.apply(this, arguments) || this; | ||
} | ||
return _createClass(RectRenderer); | ||
return RectRenderer; | ||
}(DefaultRenderer); | ||
var CircleRenderer = /*#__PURE__*/function (_DefaultRenderer) { | ||
_inherits(CircleRenderer, _DefaultRenderer); | ||
var _super = _createSuper(CircleRenderer); | ||
_inheritsLoose(CircleRenderer, _DefaultRenderer); | ||
function CircleRenderer() { | ||
_classCallCheck(this, CircleRenderer); | ||
return _super.apply(this, arguments); | ||
return _DefaultRenderer.apply(this, arguments) || this; | ||
} | ||
return _createClass(CircleRenderer); | ||
return CircleRenderer; | ||
}(DefaultRenderer); | ||
var EllipseRenderer = /*#__PURE__*/function (_DefaultRenderer) { | ||
_inherits(EllipseRenderer, _DefaultRenderer); | ||
var _super = _createSuper(EllipseRenderer); | ||
_inheritsLoose(EllipseRenderer, _DefaultRenderer); | ||
function EllipseRenderer() { | ||
_classCallCheck(this, EllipseRenderer); | ||
return _super.apply(this, arguments); | ||
return _DefaultRenderer.apply(this, arguments) || this; | ||
} | ||
return _createClass(EllipseRenderer); | ||
return EllipseRenderer; | ||
}(DefaultRenderer); | ||
var LineRenderer = /*#__PURE__*/function (_DefaultRenderer) { | ||
_inherits(LineRenderer, _DefaultRenderer); | ||
var _super = _createSuper(LineRenderer); | ||
_inheritsLoose(LineRenderer, _DefaultRenderer); | ||
function LineRenderer() { | ||
_classCallCheck(this, LineRenderer); | ||
return _super.apply(this, arguments); | ||
return _DefaultRenderer.apply(this, arguments) || this; | ||
} | ||
return _createClass(LineRenderer); | ||
return LineRenderer; | ||
}(DefaultRenderer); | ||
var PolylineRenderer = /*#__PURE__*/function (_DefaultRenderer) { | ||
_inherits(PolylineRenderer, _DefaultRenderer); | ||
var _super = _createSuper(PolylineRenderer); | ||
_inheritsLoose(PolylineRenderer, _DefaultRenderer); | ||
function PolylineRenderer() { | ||
_classCallCheck(this, PolylineRenderer); | ||
return _super.apply(this, arguments); | ||
return _DefaultRenderer.apply(this, arguments) || this; | ||
} | ||
return _createClass(PolylineRenderer); | ||
return PolylineRenderer; | ||
}(DefaultRenderer); | ||
var PolygonRenderer = /*#__PURE__*/function (_DefaultRenderer) { | ||
_inherits(PolygonRenderer, _DefaultRenderer); | ||
var _super = _createSuper(PolygonRenderer); | ||
_inheritsLoose(PolygonRenderer, _DefaultRenderer); | ||
function PolygonRenderer() { | ||
_classCallCheck(this, PolygonRenderer); | ||
return _super.apply(this, arguments); | ||
return _DefaultRenderer.apply(this, arguments) || this; | ||
} | ||
return _createClass(PolygonRenderer); | ||
return PolygonRenderer; | ||
}(DefaultRenderer); | ||
var PathRenderer = /*#__PURE__*/function (_DefaultRenderer) { | ||
_inherits(PathRenderer, _DefaultRenderer); | ||
var _super = _createSuper(PathRenderer); | ||
_inheritsLoose(PathRenderer, _DefaultRenderer); | ||
function PathRenderer() { | ||
_classCallCheck(this, PathRenderer); | ||
return _super.apply(this, arguments); | ||
return _DefaultRenderer.apply(this, arguments) || this; | ||
} | ||
return _createClass(PathRenderer); | ||
return PathRenderer; | ||
}(DefaultRenderer); | ||
var Plugin = /*#__PURE__*/function (_AbstractRendererPlug) { | ||
_inherits(Plugin, _AbstractRendererPlug); | ||
var _super = _createSuper(Plugin); | ||
function Plugin() { | ||
_inheritsLoose(Plugin, _AbstractRendererPlug); | ||
function Plugin(options) { | ||
var _this; | ||
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; | ||
_classCallCheck(this, Plugin); | ||
_this = _super.call(this); | ||
if (options === void 0) { | ||
options = {}; | ||
} | ||
_this = _AbstractRendererPlug.call(this) || this; | ||
_this.options = void 0; | ||
@@ -1429,26 +1194,22 @@ _this.name = 'canvas-renderer'; | ||
} | ||
_createClass(Plugin, [{ | ||
key: "init", | ||
value: function init() { | ||
var _defaultStyleRenderer; | ||
var canvasRendererPluginOptions = _objectSpread2({ | ||
dirtyObjectNumThreshold: 500, | ||
dirtyObjectRatioThreshold: 0.8 | ||
}, this.options); | ||
// @ts-ignore | ||
var imagePool = this.context.imagePool; | ||
var defaultRenderer = new DefaultRenderer(imagePool); | ||
var defaultStyleRendererFactory = (_defaultStyleRenderer = {}, _defineProperty(_defaultStyleRenderer, Shape.CIRCLE, defaultRenderer), _defineProperty(_defaultStyleRenderer, Shape.ELLIPSE, defaultRenderer), _defineProperty(_defaultStyleRenderer, Shape.RECT, defaultRenderer), _defineProperty(_defaultStyleRenderer, Shape.IMAGE, new ImageRenderer(imagePool)), _defineProperty(_defaultStyleRenderer, Shape.TEXT, new TextRenderer()), _defineProperty(_defaultStyleRenderer, Shape.LINE, defaultRenderer), _defineProperty(_defaultStyleRenderer, Shape.POLYLINE, defaultRenderer), _defineProperty(_defaultStyleRenderer, Shape.POLYGON, defaultRenderer), _defineProperty(_defaultStyleRenderer, Shape.PATH, defaultRenderer), _defineProperty(_defaultStyleRenderer, Shape.GROUP, undefined), _defineProperty(_defaultStyleRenderer, Shape.HTML, undefined), _defineProperty(_defaultStyleRenderer, Shape.MESH, undefined), _defaultStyleRenderer); | ||
this.context.defaultStyleRendererFactory = defaultStyleRendererFactory; | ||
this.context.styleRendererFactory = defaultStyleRendererFactory; | ||
this.addRenderingPlugin(new CanvasRendererPlugin(canvasRendererPluginOptions)); | ||
} | ||
}, { | ||
key: "destroy", | ||
value: function destroy() { | ||
this.removeAllRenderingPlugins(); | ||
delete this.context.defaultStyleRendererFactory; | ||
delete this.context.styleRendererFactory; | ||
} | ||
}]); | ||
var _proto = Plugin.prototype; | ||
_proto.init = function init() { | ||
var _defaultStyleRenderer; | ||
var canvasRendererPluginOptions = _extends({ | ||
dirtyObjectNumThreshold: 500, | ||
dirtyObjectRatioThreshold: 0.8 | ||
}, this.options); | ||
// @ts-ignore | ||
var imagePool = this.context.imagePool; | ||
var defaultRenderer = new DefaultRenderer(imagePool); | ||
var defaultStyleRendererFactory = (_defaultStyleRenderer = {}, _defaultStyleRenderer[Shape.CIRCLE] = defaultRenderer, _defaultStyleRenderer[Shape.ELLIPSE] = defaultRenderer, _defaultStyleRenderer[Shape.RECT] = defaultRenderer, _defaultStyleRenderer[Shape.IMAGE] = new ImageRenderer(imagePool), _defaultStyleRenderer[Shape.TEXT] = new TextRenderer(), _defaultStyleRenderer[Shape.LINE] = defaultRenderer, _defaultStyleRenderer[Shape.POLYLINE] = defaultRenderer, _defaultStyleRenderer[Shape.POLYGON] = defaultRenderer, _defaultStyleRenderer[Shape.PATH] = defaultRenderer, _defaultStyleRenderer[Shape.GROUP] = undefined, _defaultStyleRenderer[Shape.HTML] = undefined, _defaultStyleRenderer[Shape.MESH] = undefined, _defaultStyleRenderer); | ||
this.context.defaultStyleRendererFactory = defaultStyleRendererFactory; | ||
this.context.styleRendererFactory = defaultStyleRendererFactory; | ||
this.addRenderingPlugin(new CanvasRendererPlugin(canvasRendererPluginOptions)); | ||
}; | ||
_proto.destroy = function destroy() { | ||
this.removeAllRenderingPlugins(); | ||
delete this.context.defaultStyleRendererFactory; | ||
delete this.context.styleRendererFactory; | ||
}; | ||
return Plugin; | ||
@@ -1455,0 +1216,0 @@ }(AbstractRendererPlugin); |
1627
dist/index.js
@@ -9,50 +9,2 @@ 'use strict'; | ||
function _iterableToArrayLimit(arr, i) { | ||
var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"]; | ||
if (null != _i) { | ||
var _s, | ||
_e, | ||
_x, | ||
_r, | ||
_arr = [], | ||
_n = !0, | ||
_d = !1; | ||
try { | ||
if (_x = (_i = _i.call(arr)).next, 0 === i) { | ||
if (Object(_i) !== _i) return; | ||
_n = !1; | ||
} else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0); | ||
} catch (err) { | ||
_d = !0, _e = err; | ||
} finally { | ||
try { | ||
if (!_n && null != _i.return && (_r = _i.return(), Object(_r) !== _r)) return; | ||
} finally { | ||
if (_d) throw _e; | ||
} | ||
} | ||
return _arr; | ||
} | ||
} | ||
function ownKeys(object, enumerableOnly) { | ||
var keys = Object.keys(object); | ||
if (Object.getOwnPropertySymbols) { | ||
var symbols = Object.getOwnPropertySymbols(object); | ||
enumerableOnly && (symbols = symbols.filter(function (sym) { | ||
return Object.getOwnPropertyDescriptor(object, sym).enumerable; | ||
})), keys.push.apply(keys, symbols); | ||
} | ||
return keys; | ||
} | ||
function _objectSpread2(target) { | ||
for (var i = 1; i < arguments.length; i++) { | ||
var source = null != arguments[i] ? arguments[i] : {}; | ||
i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { | ||
_defineProperty(target, key, source[key]); | ||
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { | ||
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); | ||
}); | ||
} | ||
return target; | ||
} | ||
function _regeneratorRuntime() { | ||
@@ -389,60 +341,21 @@ _regeneratorRuntime = function () { | ||
} | ||
function _classCallCheck(instance, Constructor) { | ||
if (!(instance instanceof Constructor)) { | ||
throw new TypeError("Cannot call a class as a function"); | ||
} | ||
} | ||
function _defineProperties(target, props) { | ||
for (var i = 0; i < props.length; i++) { | ||
var descriptor = props[i]; | ||
descriptor.enumerable = descriptor.enumerable || false; | ||
descriptor.configurable = true; | ||
if ("value" in descriptor) descriptor.writable = true; | ||
Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); | ||
} | ||
} | ||
function _createClass(Constructor, protoProps, staticProps) { | ||
if (protoProps) _defineProperties(Constructor.prototype, protoProps); | ||
if (staticProps) _defineProperties(Constructor, staticProps); | ||
Object.defineProperty(Constructor, "prototype", { | ||
writable: false | ||
}); | ||
return Constructor; | ||
} | ||
function _defineProperty(obj, key, value) { | ||
key = _toPropertyKey(key); | ||
if (key in obj) { | ||
Object.defineProperty(obj, key, { | ||
value: value, | ||
enumerable: true, | ||
configurable: true, | ||
writable: true | ||
}); | ||
} else { | ||
obj[key] = value; | ||
} | ||
return obj; | ||
} | ||
function _inherits(subClass, superClass) { | ||
if (typeof superClass !== "function" && superClass !== null) { | ||
throw new TypeError("Super expression must either be null or a function"); | ||
} | ||
subClass.prototype = Object.create(superClass && superClass.prototype, { | ||
constructor: { | ||
value: subClass, | ||
writable: true, | ||
configurable: true | ||
function _extends() { | ||
_extends = Object.assign ? Object.assign.bind() : function (target) { | ||
for (var i = 1; i < arguments.length; i++) { | ||
var source = arguments[i]; | ||
for (var key in source) { | ||
if (Object.prototype.hasOwnProperty.call(source, key)) { | ||
target[key] = source[key]; | ||
} | ||
} | ||
} | ||
}); | ||
Object.defineProperty(subClass, "prototype", { | ||
writable: false | ||
}); | ||
if (superClass) _setPrototypeOf(subClass, superClass); | ||
} | ||
function _getPrototypeOf(o) { | ||
_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { | ||
return o.__proto__ || Object.getPrototypeOf(o); | ||
return target; | ||
}; | ||
return _getPrototypeOf(o); | ||
return _extends.apply(this, arguments); | ||
} | ||
function _inheritsLoose(subClass, superClass) { | ||
subClass.prototype = Object.create(superClass.prototype); | ||
subClass.prototype.constructor = subClass; | ||
_setPrototypeOf(subClass, superClass); | ||
} | ||
function _setPrototypeOf(o, p) { | ||
@@ -455,89 +368,2 @@ _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { | ||
} | ||
function _isNativeReflectConstruct() { | ||
if (typeof Reflect === "undefined" || !Reflect.construct) return false; | ||
if (Reflect.construct.sham) return false; | ||
if (typeof Proxy === "function") return true; | ||
try { | ||
Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); | ||
return true; | ||
} catch (e) { | ||
return false; | ||
} | ||
} | ||
function _assertThisInitialized(self) { | ||
if (self === void 0) { | ||
throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); | ||
} | ||
return self; | ||
} | ||
function _possibleConstructorReturn(self, call) { | ||
if (call && (typeof call === "object" || typeof call === "function")) { | ||
return call; | ||
} else if (call !== void 0) { | ||
throw new TypeError("Derived constructors may only return object or undefined"); | ||
} | ||
return _assertThisInitialized(self); | ||
} | ||
function _createSuper(Derived) { | ||
var hasNativeReflectConstruct = _isNativeReflectConstruct(); | ||
return function _createSuperInternal() { | ||
var Super = _getPrototypeOf(Derived), | ||
result; | ||
if (hasNativeReflectConstruct) { | ||
var NewTarget = _getPrototypeOf(this).constructor; | ||
result = Reflect.construct(Super, arguments, NewTarget); | ||
} else { | ||
result = Super.apply(this, arguments); | ||
} | ||
return _possibleConstructorReturn(this, result); | ||
}; | ||
} | ||
function _slicedToArray(arr, i) { | ||
return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); | ||
} | ||
function _toConsumableArray(arr) { | ||
return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); | ||
} | ||
function _arrayWithoutHoles(arr) { | ||
if (Array.isArray(arr)) return _arrayLikeToArray(arr); | ||
} | ||
function _arrayWithHoles(arr) { | ||
if (Array.isArray(arr)) return arr; | ||
} | ||
function _iterableToArray(iter) { | ||
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); | ||
} | ||
function _unsupportedIterableToArray(o, minLen) { | ||
if (!o) return; | ||
if (typeof o === "string") return _arrayLikeToArray(o, minLen); | ||
var n = Object.prototype.toString.call(o).slice(8, -1); | ||
if (n === "Object" && o.constructor) n = o.constructor.name; | ||
if (n === "Map" || n === "Set") return Array.from(o); | ||
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); | ||
} | ||
function _arrayLikeToArray(arr, len) { | ||
if (len == null || len > arr.length) len = arr.length; | ||
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; | ||
return arr2; | ||
} | ||
function _nonIterableSpread() { | ||
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); | ||
} | ||
function _nonIterableRest() { | ||
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); | ||
} | ||
function _toPrimitive(input, hint) { | ||
if (typeof input !== "object" || input === null) return input; | ||
var prim = input[Symbol.toPrimitive]; | ||
if (prim !== undefined) { | ||
var res = prim.call(input, hint || "default"); | ||
if (typeof res !== "object") return res; | ||
throw new TypeError("@@toPrimitive must return a primitive value."); | ||
} | ||
return (hint === "string" ? String : Number)(input); | ||
} | ||
function _toPropertyKey(arg) { | ||
var key = _toPrimitive(arg, "string"); | ||
return typeof key === "symbol" ? key : String(key); | ||
} | ||
@@ -555,3 +381,2 @@ /** | ||
function CanvasRendererPlugin(canvasRendererPluginOptions) { | ||
_classCallCheck(this, CanvasRendererPlugin); | ||
this.canvasRendererPluginOptions = void 0; | ||
@@ -574,409 +399,387 @@ this.context = void 0; | ||
} | ||
_createClass(CanvasRendererPlugin, [{ | ||
key: "apply", | ||
value: function apply(context) { | ||
var _this = this; | ||
this.context = context; | ||
var config = context.config, | ||
camera = context.camera, | ||
renderingService = context.renderingService, | ||
renderingContext = context.renderingContext, | ||
rBushRoot = context.rBushRoot, | ||
pathGeneratorFactory = context.pathGeneratorFactory; | ||
this.rBush = rBushRoot; | ||
this.pathGeneratorFactory = pathGeneratorFactory; | ||
var contextService = context.contextService; | ||
var canvas = renderingContext.root.ownerDocument.defaultView; | ||
var handleUnmounted = function handleUnmounted(e) { | ||
var object = e.target; | ||
// remove r-bush node | ||
// @ts-ignore | ||
var rBushNode = object.rBushNode; | ||
if (rBushNode.aabb) { | ||
// save removed aabbs for dirty-rectangle rendering later | ||
_this.removedRBushNodeAABBs.push(rBushNode.aabb); | ||
} | ||
}; | ||
var handleCulled = function handleCulled(e) { | ||
var object = e.target; | ||
// @ts-ignore | ||
var rBushNode = object.rBushNode; | ||
if (rBushNode.aabb) { | ||
// save removed aabbs for dirty-rectangle rendering later | ||
_this.removedRBushNodeAABBs.push(rBushNode.aabb); | ||
} | ||
}; | ||
renderingService.hooks.init.tapPromise(CanvasRendererPlugin.tag, /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() { | ||
var dpr, width, height, context; | ||
return _regeneratorRuntime().wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
canvas.addEventListener(gLite.ElementEvent.UNMOUNTED, handleUnmounted); | ||
canvas.addEventListener(gLite.ElementEvent.CULLED, handleCulled); | ||
// clear fullscreen | ||
dpr = contextService.getDPR(); | ||
width = config.width, height = config.height; | ||
context = contextService.getContext(); | ||
_this.clearRect(context, 0, 0, width * dpr, height * dpr, config.background); | ||
case 6: | ||
case "end": | ||
return _context.stop(); | ||
} | ||
var _proto = CanvasRendererPlugin.prototype; | ||
_proto.apply = function apply(context) { | ||
var _this = this; | ||
this.context = context; | ||
var config = context.config, | ||
camera = context.camera, | ||
renderingService = context.renderingService, | ||
renderingContext = context.renderingContext, | ||
rBushRoot = context.rBushRoot, | ||
pathGeneratorFactory = context.pathGeneratorFactory; | ||
this.rBush = rBushRoot; | ||
this.pathGeneratorFactory = pathGeneratorFactory; | ||
var contextService = context.contextService; | ||
var canvas = renderingContext.root.ownerDocument.defaultView; | ||
var handleUnmounted = function handleUnmounted(e) { | ||
var object = e.target; | ||
// remove r-bush node | ||
// @ts-ignore | ||
var rBushNode = object.rBushNode; | ||
if (rBushNode.aabb) { | ||
// save removed aabbs for dirty-rectangle rendering later | ||
_this.removedRBushNodeAABBs.push(rBushNode.aabb); | ||
} | ||
}; | ||
var handleCulled = function handleCulled(e) { | ||
var object = e.target; | ||
// @ts-ignore | ||
var rBushNode = object.rBushNode; | ||
if (rBushNode.aabb) { | ||
// save removed aabbs for dirty-rectangle rendering later | ||
_this.removedRBushNodeAABBs.push(rBushNode.aabb); | ||
} | ||
}; | ||
renderingService.hooks.init.tapPromise(CanvasRendererPlugin.tag, /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() { | ||
var dpr, width, height, context; | ||
return _regeneratorRuntime().wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
canvas.addEventListener(gLite.ElementEvent.UNMOUNTED, handleUnmounted); | ||
canvas.addEventListener(gLite.ElementEvent.CULLED, handleCulled); | ||
// clear fullscreen | ||
dpr = contextService.getDPR(); | ||
width = config.width, height = config.height; | ||
context = contextService.getContext(); | ||
_this.clearRect(context, 0, 0, width * dpr, height * dpr, config.background); | ||
case 6: | ||
case "end": | ||
return _context.stop(); | ||
} | ||
}, _callee); | ||
}))); | ||
renderingService.hooks.destroy.tap(CanvasRendererPlugin.tag, function () { | ||
canvas.removeEventListener(gLite.ElementEvent.UNMOUNTED, handleUnmounted); | ||
canvas.removeEventListener(gLite.ElementEvent.CULLED, handleCulled); | ||
}); | ||
renderingService.hooks.beginFrame.tap(CanvasRendererPlugin.tag, function () { | ||
var context = contextService.getContext(); | ||
var dpr = contextService.getDPR(); | ||
var width = config.width, | ||
height = config.height; | ||
var _this$canvasRendererP = _this.canvasRendererPluginOptions, | ||
dirtyObjectNumThreshold = _this$canvasRendererP.dirtyObjectNumThreshold, | ||
dirtyObjectRatioThreshold = _this$canvasRendererP.dirtyObjectRatioThreshold; | ||
// some heuristic conditions such as 80% object changed | ||
var _renderingService$get = renderingService.getStats(), | ||
total = _renderingService$get.total, | ||
rendered = _renderingService$get.rendered; | ||
var ratio = rendered / total; | ||
_this.clearFullScreen = renderingService.disableDirtyRectangleRendering() || rendered > dirtyObjectNumThreshold && ratio > dirtyObjectRatioThreshold; | ||
if (context) { | ||
context.resetTransform(); | ||
if (_this.clearFullScreen) { | ||
_this.clearRect(context, 0, 0, width * dpr, height * dpr, config.background); | ||
} | ||
} | ||
}); | ||
var renderByZIndex = function renderByZIndex(object, context) { | ||
if (object.isVisible() && !object.isCulled()) { | ||
_this.renderDisplayObject(object, context, _this.context, _this.restoreStack); | ||
// if we did a full screen rendering last frame | ||
_this.saveDirtyAABB(object); | ||
} | ||
var sorted = object.sortable.sorted || object.childNodes; | ||
// should account for z-index | ||
sorted.forEach(function (child) { | ||
renderByZIndex(child, context); | ||
}); | ||
}; | ||
// render at the end of frame | ||
renderingService.hooks.endFrame.tap(CanvasRendererPlugin.tag, function () { | ||
var context = contextService.getContext(); | ||
// clear & clip dirty rectangle | ||
var dpr = contextService.getDPR(); | ||
glMatrix.mat4.fromScaling(_this.dprMatrix, glMatrix.vec3.fromValues(dpr, dpr, 1)); | ||
glMatrix.mat4.multiply(_this.vpMatrix, _this.dprMatrix, camera.getOrthoMatrix()); | ||
}, _callee); | ||
}))); | ||
renderingService.hooks.destroy.tap(CanvasRendererPlugin.tag, function () { | ||
canvas.removeEventListener(gLite.ElementEvent.UNMOUNTED, handleUnmounted); | ||
canvas.removeEventListener(gLite.ElementEvent.CULLED, handleCulled); | ||
}); | ||
renderingService.hooks.beginFrame.tap(CanvasRendererPlugin.tag, function () { | ||
var context = contextService.getContext(); | ||
var dpr = contextService.getDPR(); | ||
var width = config.width, | ||
height = config.height; | ||
var _this$canvasRendererP = _this.canvasRendererPluginOptions, | ||
dirtyObjectNumThreshold = _this$canvasRendererP.dirtyObjectNumThreshold, | ||
dirtyObjectRatioThreshold = _this$canvasRendererP.dirtyObjectRatioThreshold; | ||
// some heuristic conditions such as 80% object changed | ||
var _renderingService$get = renderingService.getStats(), | ||
total = _renderingService$get.total, | ||
rendered = _renderingService$get.rendered; | ||
var ratio = rendered / total; | ||
_this.clearFullScreen = renderingService.disableDirtyRectangleRendering() || rendered > dirtyObjectNumThreshold && ratio > dirtyObjectRatioThreshold; | ||
if (context) { | ||
context.resetTransform(); | ||
if (_this.clearFullScreen) { | ||
renderByZIndex(renderingContext.root, context); | ||
} else { | ||
// merge removed AABB | ||
var dirtyRenderBounds = _this.safeMergeAABB.apply(_this, [_this.mergeDirtyAABBs(_this.renderQueue)].concat(_toConsumableArray(_this.removedRBushNodeAABBs.map(function (_ref2) { | ||
var minX = _ref2.minX, | ||
minY = _ref2.minY, | ||
maxX = _ref2.maxX, | ||
maxY = _ref2.maxY; | ||
var aabb = new gLite.AABB(); | ||
aabb.setMinMax(glMatrix.vec3.fromValues(minX, minY, 0), glMatrix.vec3.fromValues(maxX, maxY, 0)); | ||
return aabb; | ||
})))); | ||
_this.removedRBushNodeAABBs = []; | ||
if (gLite.AABB.isEmpty(dirtyRenderBounds)) { | ||
_this.renderQueue = []; | ||
return; | ||
} | ||
var dirtyRect = _this.convertAABB2Rect(dirtyRenderBounds); | ||
var x = dirtyRect.x, | ||
y = dirtyRect.y, | ||
width = dirtyRect.width, | ||
height = dirtyRect.height; | ||
var tl = glMatrix.vec3.transformMat4(_this.vec3a, glMatrix.vec3.fromValues(x, y, 0), _this.vpMatrix); | ||
var tr = glMatrix.vec3.transformMat4(_this.vec3b, glMatrix.vec3.fromValues(x + width, y, 0), _this.vpMatrix); | ||
var bl = glMatrix.vec3.transformMat4(_this.vec3c, glMatrix.vec3.fromValues(x, y + height, 0), _this.vpMatrix); | ||
var br = glMatrix.vec3.transformMat4(_this.vec3d, glMatrix.vec3.fromValues(x + width, y + height, 0), _this.vpMatrix); | ||
var minx = Math.min(tl[0], tr[0], br[0], bl[0]); | ||
var miny = Math.min(tl[1], tr[1], br[1], bl[1]); | ||
var maxx = Math.max(tl[0], tr[0], br[0], bl[0]); | ||
var maxy = Math.max(tl[1], tr[1], br[1], bl[1]); | ||
var ix = Math.floor(minx); | ||
var iy = Math.floor(miny); | ||
var iwidth = Math.ceil(maxx - minx); | ||
var iheight = Math.ceil(maxy - miny); | ||
context.save(); | ||
_this.clearRect(context, ix, iy, iwidth, iheight, config.background); | ||
context.beginPath(); | ||
context.rect(ix, iy, iwidth, iheight); | ||
context.clip(); | ||
// @see https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Transformations | ||
context.setTransform(_this.vpMatrix[0], _this.vpMatrix[1], _this.vpMatrix[4], _this.vpMatrix[5], _this.vpMatrix[12], _this.vpMatrix[13]); | ||
// draw dirty rectangle | ||
var _config$renderer$getC = config.renderer.getConfig(), | ||
enableDirtyRectangleRenderingDebug = _config$renderer$getC.enableDirtyRectangleRenderingDebug; | ||
if (enableDirtyRectangleRenderingDebug) { | ||
canvas.dispatchEvent(new gLite.CustomEvent(gLite.CanvasEvent.DIRTY_RECTANGLE, { | ||
dirtyRect: { | ||
x: ix, | ||
y: iy, | ||
width: iwidth, | ||
height: iheight | ||
} | ||
})); | ||
} | ||
// search objects intersect with dirty rectangle | ||
var dirtyObjects = _this.searchDirtyObjects(dirtyRenderBounds); | ||
// do rendering | ||
dirtyObjects | ||
// sort by z-index | ||
.sort(function (a, b) { | ||
return a.sortable.renderOrder - b.sortable.renderOrder; | ||
}).forEach(function (object) { | ||
// culled object should not be rendered | ||
if (object && object.isVisible() && !object.isCulled()) { | ||
_this.renderDisplayObject(object, context, _this.context, _this.restoreStack); | ||
} | ||
}); | ||
context.restore(); | ||
// save dirty AABBs in last frame | ||
_this.renderQueue.forEach(function (object) { | ||
_this.saveDirtyAABB(object); | ||
}); | ||
// clear queue | ||
_this.renderQueue = []; | ||
_this.clearRect(context, 0, 0, width * dpr, height * dpr, config.background); | ||
} | ||
// pop restore stack, eg. root -> parent -> child | ||
_this.restoreStack.forEach(function () { | ||
context.restore(); | ||
}); | ||
// clear restore stack | ||
_this.restoreStack = []; | ||
}); | ||
renderingService.hooks.render.tap(CanvasRendererPlugin.tag, function (object) { | ||
if (!_this.clearFullScreen) { | ||
// render at the end of frame | ||
_this.renderQueue.push(object); | ||
} | ||
}); | ||
} | ||
}, { | ||
key: "clearRect", | ||
value: function clearRect(context, x, y, width, height, background) { | ||
// clearRect is faster than fillRect @see https://stackoverflow.com/a/30830253 | ||
context.clearRect(x, y, width, height); | ||
if (background) { | ||
context.fillStyle = background; | ||
context.fillRect(x, y, width, height); | ||
} | ||
} | ||
}, { | ||
key: "renderDisplayObject", | ||
value: function renderDisplayObject(object, context, canvasContext, restoreStack) { | ||
var nodeName = object.nodeName; | ||
// restore to its ancestor | ||
var parent = restoreStack[restoreStack.length - 1]; | ||
if (parent && !(object.compareDocumentPosition(parent) & Node.DOCUMENT_POSITION_CONTAINS)) { | ||
context.restore(); | ||
restoreStack.pop(); | ||
}); | ||
var renderByZIndex = function renderByZIndex(object, context) { | ||
if (object.isVisible() && !object.isCulled()) { | ||
_this.renderDisplayObject(object, context, _this.context, _this.restoreStack); | ||
// if we did a full screen rendering last frame | ||
_this.saveDirtyAABB(object); | ||
} | ||
// @ts-ignore | ||
var styleRenderer = this.context.styleRendererFactory[nodeName]; | ||
var generatePath = this.pathGeneratorFactory[nodeName]; | ||
// clip path | ||
var clipPath = object.parsedStyle.clipPath; | ||
if (clipPath) { | ||
this.applyWorldTransform(context, clipPath); | ||
// generate path in local space | ||
var _generatePath = this.pathGeneratorFactory[clipPath.nodeName]; | ||
if (_generatePath) { | ||
context.save(); | ||
// save clip | ||
restoreStack.push(object); | ||
context.beginPath(); | ||
_generatePath(context, clipPath.parsedStyle); | ||
context.closePath(); | ||
context.clip(); | ||
var sorted = object.sortable.sorted || object.childNodes; | ||
// should account for z-index | ||
sorted.forEach(function (child) { | ||
renderByZIndex(child, context); | ||
}); | ||
}; | ||
// render at the end of frame | ||
renderingService.hooks.endFrame.tap(CanvasRendererPlugin.tag, function () { | ||
var context = contextService.getContext(); | ||
// clear & clip dirty rectangle | ||
var dpr = contextService.getDPR(); | ||
glMatrix.mat4.fromScaling(_this.dprMatrix, glMatrix.vec3.fromValues(dpr, dpr, 1)); | ||
glMatrix.mat4.multiply(_this.vpMatrix, _this.dprMatrix, camera.getOrthoMatrix()); | ||
if (_this.clearFullScreen) { | ||
renderByZIndex(renderingContext.root, context); | ||
} else { | ||
// merge removed AABB | ||
var dirtyRenderBounds = _this.safeMergeAABB.apply(_this, [_this.mergeDirtyAABBs(_this.renderQueue)].concat(_this.removedRBushNodeAABBs.map(function (_ref2) { | ||
var minX = _ref2.minX, | ||
minY = _ref2.minY, | ||
maxX = _ref2.maxX, | ||
maxY = _ref2.maxY; | ||
var aabb = new gLite.AABB(); | ||
aabb.setMinMax(glMatrix.vec3.fromValues(minX, minY, 0), glMatrix.vec3.fromValues(maxX, maxY, 0)); | ||
return aabb; | ||
}))); | ||
_this.removedRBushNodeAABBs = []; | ||
if (gLite.AABB.isEmpty(dirtyRenderBounds)) { | ||
_this.renderQueue = []; | ||
return; | ||
} | ||
} | ||
// fill & stroke | ||
if (styleRenderer) { | ||
this.applyWorldTransform(context, object); | ||
var dirtyRect = _this.convertAABB2Rect(dirtyRenderBounds); | ||
var x = dirtyRect.x, | ||
y = dirtyRect.y, | ||
width = dirtyRect.width, | ||
height = dirtyRect.height; | ||
var tl = glMatrix.vec3.transformMat4(_this.vec3a, glMatrix.vec3.fromValues(x, y, 0), _this.vpMatrix); | ||
var tr = glMatrix.vec3.transformMat4(_this.vec3b, glMatrix.vec3.fromValues(x + width, y, 0), _this.vpMatrix); | ||
var bl = glMatrix.vec3.transformMat4(_this.vec3c, glMatrix.vec3.fromValues(x, y + height, 0), _this.vpMatrix); | ||
var br = glMatrix.vec3.transformMat4(_this.vec3d, glMatrix.vec3.fromValues(x + width, y + height, 0), _this.vpMatrix); | ||
var minx = Math.min(tl[0], tr[0], br[0], bl[0]); | ||
var miny = Math.min(tl[1], tr[1], br[1], bl[1]); | ||
var maxx = Math.max(tl[0], tr[0], br[0], bl[0]); | ||
var maxy = Math.max(tl[1], tr[1], br[1], bl[1]); | ||
var ix = Math.floor(minx); | ||
var iy = Math.floor(miny); | ||
var iwidth = Math.ceil(maxx - minx); | ||
var iheight = Math.ceil(maxy - miny); | ||
context.save(); | ||
// apply attributes to context | ||
this.applyAttributesToContext(context, object); | ||
} | ||
if (generatePath) { | ||
_this.clearRect(context, ix, iy, iwidth, iheight, config.background); | ||
context.beginPath(); | ||
generatePath(context, object.parsedStyle); | ||
if (object.nodeName !== gLite.Shape.LINE && object.nodeName !== gLite.Shape.PATH && object.nodeName !== gLite.Shape.POLYLINE) { | ||
context.closePath(); | ||
context.rect(ix, iy, iwidth, iheight); | ||
context.clip(); | ||
// @see https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Transformations | ||
context.setTransform(_this.vpMatrix[0], _this.vpMatrix[1], _this.vpMatrix[4], _this.vpMatrix[5], _this.vpMatrix[12], _this.vpMatrix[13]); | ||
// draw dirty rectangle | ||
var _config$renderer$getC = config.renderer.getConfig(), | ||
enableDirtyRectangleRenderingDebug = _config$renderer$getC.enableDirtyRectangleRenderingDebug; | ||
if (enableDirtyRectangleRenderingDebug) { | ||
canvas.dispatchEvent(new gLite.CustomEvent(gLite.CanvasEvent.DIRTY_RECTANGLE, { | ||
dirtyRect: { | ||
x: ix, | ||
y: iy, | ||
width: iwidth, | ||
height: iheight | ||
} | ||
})); | ||
} | ||
// search objects intersect with dirty rectangle | ||
var dirtyObjects = _this.searchDirtyObjects(dirtyRenderBounds); | ||
// do rendering | ||
dirtyObjects | ||
// sort by z-index | ||
.sort(function (a, b) { | ||
return a.sortable.renderOrder - b.sortable.renderOrder; | ||
}).forEach(function (object) { | ||
// culled object should not be rendered | ||
if (object && object.isVisible() && !object.isCulled()) { | ||
_this.renderDisplayObject(object, context, _this.context, _this.restoreStack); | ||
} | ||
}); | ||
context.restore(); | ||
// save dirty AABBs in last frame | ||
_this.renderQueue.forEach(function (object) { | ||
_this.saveDirtyAABB(object); | ||
}); | ||
// clear queue | ||
_this.renderQueue = []; | ||
} | ||
// fill & stroke | ||
if (styleRenderer) { | ||
styleRenderer.render(context, object.parsedStyle, object, canvasContext, this); | ||
// restore applied attributes, eg. shadowBlur shadowColor... | ||
// pop restore stack, eg. root -> parent -> child | ||
_this.restoreStack.forEach(function () { | ||
context.restore(); | ||
}); | ||
// clear restore stack | ||
_this.restoreStack = []; | ||
}); | ||
renderingService.hooks.render.tap(CanvasRendererPlugin.tag, function (object) { | ||
if (!_this.clearFullScreen) { | ||
// render at the end of frame | ||
_this.renderQueue.push(object); | ||
} | ||
// finish rendering, clear dirty flag | ||
object.renderable.dirty = false; | ||
}); | ||
}; | ||
_proto.clearRect = function clearRect(context, x, y, width, height, background) { | ||
// clearRect is faster than fillRect @see https://stackoverflow.com/a/30830253 | ||
context.clearRect(x, y, width, height); | ||
if (background) { | ||
context.fillStyle = background; | ||
context.fillRect(x, y, width, height); | ||
} | ||
}, { | ||
key: "convertAABB2Rect", | ||
value: function convertAABB2Rect(aabb) { | ||
var min = aabb.getMin(); | ||
var max = aabb.getMax(); | ||
// expand the rectangle a bit to avoid artifacts | ||
// @see https://www.yuque.com/antv/ou292n/bi8nix#ExvCu | ||
var minX = Math.floor(min[0]); | ||
var minY = Math.floor(min[1]); | ||
var maxX = Math.ceil(max[0]); | ||
var maxY = Math.ceil(max[1]); | ||
var width = maxX - minX; | ||
var height = maxY - minY; | ||
return { | ||
x: minX, | ||
y: minY, | ||
width: width, | ||
height: height | ||
}; | ||
}; | ||
_proto.renderDisplayObject = function renderDisplayObject(object, context, canvasContext, restoreStack) { | ||
var nodeName = object.nodeName; | ||
// restore to its ancestor | ||
var parent = restoreStack[restoreStack.length - 1]; | ||
if (parent && !(object.compareDocumentPosition(parent) & Node.DOCUMENT_POSITION_CONTAINS)) { | ||
context.restore(); | ||
restoreStack.pop(); | ||
} | ||
/** | ||
* TODO: merge dirty rectangles with some strategies. | ||
* For now, we just simply merge all the rectangles into one. | ||
* @see https://idom.me/articles/841.html | ||
*/ | ||
}, { | ||
key: "mergeDirtyAABBs", | ||
value: function mergeDirtyAABBs(dirtyObjects) { | ||
// merge into a big AABB | ||
// TODO: skip descendant if ancestor is caculated, but compareNodePosition is really slow | ||
var aabb = new gLite.AABB(); | ||
dirtyObjects.forEach(function (object) { | ||
var renderBounds = object.getRenderBounds(); | ||
aabb.add(renderBounds); | ||
var dirtyRenderBounds = object.renderable.dirtyRenderBounds; | ||
if (dirtyRenderBounds) { | ||
aabb.add(dirtyRenderBounds); | ||
} | ||
}); | ||
return aabb; | ||
// @ts-ignore | ||
var styleRenderer = this.context.styleRendererFactory[nodeName]; | ||
var generatePath = this.pathGeneratorFactory[nodeName]; | ||
// clip path | ||
var clipPath = object.parsedStyle.clipPath; | ||
if (clipPath) { | ||
this.applyWorldTransform(context, clipPath); | ||
// generate path in local space | ||
var _generatePath = this.pathGeneratorFactory[clipPath.nodeName]; | ||
if (_generatePath) { | ||
context.save(); | ||
// save clip | ||
restoreStack.push(object); | ||
context.beginPath(); | ||
_generatePath(context, clipPath.parsedStyle); | ||
context.closePath(); | ||
context.clip(); | ||
} | ||
} | ||
}, { | ||
key: "searchDirtyObjects", | ||
value: function searchDirtyObjects(dirtyRectangle) { | ||
// search in r-tree, get all affected nodes | ||
var _dirtyRectangle$getMi = dirtyRectangle.getMin(), | ||
_dirtyRectangle$getMi2 = _slicedToArray(_dirtyRectangle$getMi, 2), | ||
minX = _dirtyRectangle$getMi2[0], | ||
minY = _dirtyRectangle$getMi2[1]; | ||
var _dirtyRectangle$getMa = dirtyRectangle.getMax(), | ||
_dirtyRectangle$getMa2 = _slicedToArray(_dirtyRectangle$getMa, 2), | ||
maxX = _dirtyRectangle$getMa2[0], | ||
maxY = _dirtyRectangle$getMa2[1]; | ||
var rBushNodes = this.rBush.search({ | ||
minX: minX, | ||
minY: minY, | ||
maxX: maxX, | ||
maxY: maxY | ||
}); | ||
return rBushNodes.map(function (_ref3) { | ||
var id = _ref3.id; | ||
return gLite.runtime.displayObjectPool.getByEntity(id); | ||
}); | ||
// fill & stroke | ||
if (styleRenderer) { | ||
this.applyWorldTransform(context, object); | ||
context.save(); | ||
// apply attributes to context | ||
this.applyAttributesToContext(context, object); | ||
} | ||
}, { | ||
key: "saveDirtyAABB", | ||
value: function saveDirtyAABB(object) { | ||
var renderable = object.renderable; | ||
if (!renderable.dirtyRenderBounds) { | ||
renderable.dirtyRenderBounds = new gLite.AABB(); | ||
if (generatePath) { | ||
context.beginPath(); | ||
generatePath(context, object.parsedStyle); | ||
if (object.nodeName !== gLite.Shape.LINE && object.nodeName !== gLite.Shape.PATH && object.nodeName !== gLite.Shape.POLYLINE) { | ||
context.closePath(); | ||
} | ||
} | ||
// fill & stroke | ||
if (styleRenderer) { | ||
styleRenderer.render(context, object.parsedStyle, object, canvasContext, this); | ||
// restore applied attributes, eg. shadowBlur shadowColor... | ||
context.restore(); | ||
} | ||
// finish rendering, clear dirty flag | ||
object.renderable.dirty = false; | ||
}; | ||
_proto.convertAABB2Rect = function convertAABB2Rect(aabb) { | ||
var min = aabb.getMin(); | ||
var max = aabb.getMax(); | ||
// expand the rectangle a bit to avoid artifacts | ||
// @see https://www.yuque.com/antv/ou292n/bi8nix#ExvCu | ||
var minX = Math.floor(min[0]); | ||
var minY = Math.floor(min[1]); | ||
var maxX = Math.ceil(max[0]); | ||
var maxY = Math.ceil(max[1]); | ||
var width = maxX - minX; | ||
var height = maxY - minY; | ||
return { | ||
x: minX, | ||
y: minY, | ||
width: width, | ||
height: height | ||
}; | ||
} | ||
/** | ||
* TODO: merge dirty rectangles with some strategies. | ||
* For now, we just simply merge all the rectangles into one. | ||
* @see https://idom.me/articles/841.html | ||
*/; | ||
_proto.mergeDirtyAABBs = function mergeDirtyAABBs(dirtyObjects) { | ||
// merge into a big AABB | ||
// TODO: skip descendant if ancestor is caculated, but compareNodePosition is really slow | ||
var aabb = new gLite.AABB(); | ||
dirtyObjects.forEach(function (object) { | ||
var renderBounds = object.getRenderBounds(); | ||
if (renderBounds) { | ||
// save last dirty aabb | ||
renderable.dirtyRenderBounds.update(renderBounds.center, renderBounds.halfExtents); | ||
aabb.add(renderBounds); | ||
var dirtyRenderBounds = object.renderable.dirtyRenderBounds; | ||
if (dirtyRenderBounds) { | ||
aabb.add(dirtyRenderBounds); | ||
} | ||
}); | ||
return aabb; | ||
}; | ||
_proto.searchDirtyObjects = function searchDirtyObjects(dirtyRectangle) { | ||
// search in r-tree, get all affected nodes | ||
var _dirtyRectangle$getMi = dirtyRectangle.getMin(), | ||
minX = _dirtyRectangle$getMi[0], | ||
minY = _dirtyRectangle$getMi[1]; | ||
var _dirtyRectangle$getMa = dirtyRectangle.getMax(), | ||
maxX = _dirtyRectangle$getMa[0], | ||
maxY = _dirtyRectangle$getMa[1]; | ||
var rBushNodes = this.rBush.search({ | ||
minX: minX, | ||
minY: minY, | ||
maxX: maxX, | ||
maxY: maxY | ||
}); | ||
return rBushNodes.map(function (_ref3) { | ||
var id = _ref3.id; | ||
return gLite.runtime.displayObjectPool.getByEntity(id); | ||
}); | ||
}; | ||
_proto.saveDirtyAABB = function saveDirtyAABB(object) { | ||
var renderable = object.renderable; | ||
if (!renderable.dirtyRenderBounds) { | ||
renderable.dirtyRenderBounds = new gLite.AABB(); | ||
} | ||
/** | ||
* TODO: batch the same global attributes | ||
*/ | ||
}, { | ||
key: "applyAttributesToContext", | ||
value: function applyAttributesToContext(context, object) { | ||
var _object$parsedStyle = object.parsedStyle, | ||
stroke = _object$parsedStyle.stroke, | ||
fill = _object$parsedStyle.fill, | ||
opacity = _object$parsedStyle.opacity, | ||
lineDash = _object$parsedStyle.lineDash, | ||
lineDashOffset = _object$parsedStyle.lineDashOffset; | ||
// @see https://developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D/setLineDash | ||
if (lineDash) { | ||
context.setLineDash(lineDash); | ||
} | ||
// @see https://developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D/lineDashOffset | ||
if (!util.isNil(lineDashOffset)) { | ||
context.lineDashOffset = lineDashOffset; | ||
} | ||
if (!util.isNil(opacity)) { | ||
context.globalAlpha *= opacity; | ||
} | ||
if (!util.isNil(stroke) && !Array.isArray(stroke) && !stroke.isNone) { | ||
context.strokeStyle = object.attributes.stroke; | ||
} | ||
if (!util.isNil(fill) && !Array.isArray(fill) && !fill.isNone) { | ||
context.fillStyle = object.attributes.fill; | ||
} | ||
var renderBounds = object.getRenderBounds(); | ||
if (renderBounds) { | ||
// save last dirty aabb | ||
renderable.dirtyRenderBounds.update(renderBounds.center, renderBounds.halfExtents); | ||
} | ||
}, { | ||
key: "applyWorldTransform", | ||
value: function applyWorldTransform(context, object, matrix) { | ||
var tx = 0; | ||
var ty = 0; | ||
var _ref4 = object.parsedStyle || {}, | ||
anchor = _ref4.anchor; | ||
var anchorX = anchor && anchor[0] || 0; | ||
var anchorY = anchor && anchor[1] || 0; | ||
if (anchorX !== 0 || anchorY !== 0) { | ||
var bounds = object.getGeometryBounds(); | ||
var width = bounds && bounds.halfExtents[0] * 2 || 0; | ||
var height = bounds && bounds.halfExtents[1] * 2 || 0; | ||
tx = -(anchorX * width); | ||
ty = -(anchorY * height); | ||
} | ||
// apply clip shape's RTS | ||
if (matrix) { | ||
glMatrix.mat4.copy(this.tmpMat4, object.getLocalTransform()); | ||
this.vec3a[0] = tx; | ||
this.vec3a[1] = ty; | ||
this.vec3a[2] = 0; | ||
glMatrix.mat4.translate(this.tmpMat4, this.tmpMat4, this.vec3a); | ||
glMatrix.mat4.multiply(this.tmpMat4, matrix, this.tmpMat4); | ||
glMatrix.mat4.multiply(this.tmpMat4, this.vpMatrix, this.tmpMat4); | ||
} else { | ||
// apply RTS transformation in world space | ||
glMatrix.mat4.copy(this.tmpMat4, object.getWorldTransform()); | ||
this.vec3a[0] = tx; | ||
this.vec3a[1] = ty; | ||
this.vec3a[2] = 0; | ||
glMatrix.mat4.translate(this.tmpMat4, this.tmpMat4, this.vec3a); | ||
glMatrix.mat4.multiply(this.tmpMat4, this.vpMatrix, this.tmpMat4); | ||
} | ||
// @see https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Transformations | ||
context.setTransform(this.tmpMat4[0], this.tmpMat4[1], this.tmpMat4[4], this.tmpMat4[5], this.tmpMat4[12], this.tmpMat4[13]); | ||
} | ||
/** | ||
* TODO: batch the same global attributes | ||
*/; | ||
_proto.applyAttributesToContext = function applyAttributesToContext(context, object) { | ||
var _object$parsedStyle = object.parsedStyle, | ||
stroke = _object$parsedStyle.stroke, | ||
fill = _object$parsedStyle.fill, | ||
opacity = _object$parsedStyle.opacity, | ||
lineDash = _object$parsedStyle.lineDash, | ||
lineDashOffset = _object$parsedStyle.lineDashOffset; | ||
// @see https://developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D/setLineDash | ||
if (lineDash) { | ||
context.setLineDash(lineDash); | ||
} | ||
}, { | ||
key: "safeMergeAABB", | ||
value: function safeMergeAABB() { | ||
var merged = new gLite.AABB(); | ||
for (var _len = arguments.length, aabbs = new Array(_len), _key = 0; _key < _len; _key++) { | ||
aabbs[_key] = arguments[_key]; | ||
} | ||
aabbs.forEach(function (aabb) { | ||
merged.add(aabb); | ||
}); | ||
return merged; | ||
// @see https://developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D/lineDashOffset | ||
if (!util.isNil(lineDashOffset)) { | ||
context.lineDashOffset = lineDashOffset; | ||
} | ||
}]); | ||
if (!util.isNil(opacity)) { | ||
context.globalAlpha *= opacity; | ||
} | ||
if (!util.isNil(stroke) && !Array.isArray(stroke) && !stroke.isNone) { | ||
context.strokeStyle = object.attributes.stroke; | ||
} | ||
if (!util.isNil(fill) && !Array.isArray(fill) && !fill.isNone) { | ||
context.fillStyle = object.attributes.fill; | ||
} | ||
}; | ||
_proto.applyWorldTransform = function applyWorldTransform(context, object, matrix) { | ||
var tx = 0; | ||
var ty = 0; | ||
var _ref4 = object.parsedStyle || {}, | ||
anchor = _ref4.anchor; | ||
var anchorX = anchor && anchor[0] || 0; | ||
var anchorY = anchor && anchor[1] || 0; | ||
if (anchorX !== 0 || anchorY !== 0) { | ||
var bounds = object.getGeometryBounds(); | ||
var width = bounds && bounds.halfExtents[0] * 2 || 0; | ||
var height = bounds && bounds.halfExtents[1] * 2 || 0; | ||
tx = -(anchorX * width); | ||
ty = -(anchorY * height); | ||
} | ||
// apply clip shape's RTS | ||
if (matrix) { | ||
glMatrix.mat4.copy(this.tmpMat4, object.getLocalTransform()); | ||
this.vec3a[0] = tx; | ||
this.vec3a[1] = ty; | ||
this.vec3a[2] = 0; | ||
glMatrix.mat4.translate(this.tmpMat4, this.tmpMat4, this.vec3a); | ||
glMatrix.mat4.multiply(this.tmpMat4, matrix, this.tmpMat4); | ||
glMatrix.mat4.multiply(this.tmpMat4, this.vpMatrix, this.tmpMat4); | ||
} else { | ||
// apply RTS transformation in world space | ||
glMatrix.mat4.copy(this.tmpMat4, object.getWorldTransform()); | ||
this.vec3a[0] = tx; | ||
this.vec3a[1] = ty; | ||
this.vec3a[2] = 0; | ||
glMatrix.mat4.translate(this.tmpMat4, this.tmpMat4, this.vec3a); | ||
glMatrix.mat4.multiply(this.tmpMat4, this.vpMatrix, this.tmpMat4); | ||
} | ||
// @see https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Transformations | ||
context.setTransform(this.tmpMat4[0], this.tmpMat4[1], this.tmpMat4[4], this.tmpMat4[5], this.tmpMat4[12], this.tmpMat4[13]); | ||
}; | ||
_proto.safeMergeAABB = function safeMergeAABB() { | ||
var merged = new gLite.AABB(); | ||
for (var _len = arguments.length, aabbs = new Array(_len), _key = 0; _key < _len; _key++) { | ||
aabbs[_key] = arguments[_key]; | ||
} | ||
aabbs.forEach(function (aabb) { | ||
merged.add(aabb); | ||
}); | ||
return merged; | ||
}; | ||
return CanvasRendererPlugin; | ||
@@ -988,163 +791,150 @@ }(); | ||
function DefaultRenderer(imagePool) { | ||
_classCallCheck(this, DefaultRenderer); | ||
this.imagePool = void 0; | ||
this.imagePool = imagePool; | ||
} | ||
_createClass(DefaultRenderer, [{ | ||
key: "render", | ||
value: function render(context, parsedStyle, object, canvasContext, plugin) { | ||
var fill = parsedStyle.fill, | ||
fillRule = parsedStyle.fillRule, | ||
opacity = parsedStyle.opacity, | ||
fillOpacity = parsedStyle.fillOpacity, | ||
stroke = parsedStyle.stroke, | ||
strokeOpacity = parsedStyle.strokeOpacity, | ||
lineWidth = parsedStyle.lineWidth, | ||
lineCap = parsedStyle.lineCap, | ||
lineJoin = parsedStyle.lineJoin, | ||
shadowType = parsedStyle.shadowType, | ||
shadowColor = parsedStyle.shadowColor, | ||
shadowBlur = parsedStyle.shadowBlur, | ||
filter = parsedStyle.filter, | ||
miterLimit = parsedStyle.miterLimit; | ||
var hasFill = !util.isNil(fill) && !fill.isNone; | ||
var hasStroke = !util.isNil(stroke) && !stroke.isNone && lineWidth > 0; | ||
var isFillTransparent = fill.alpha === 0; | ||
var hasFilter = !!(filter && filter.length); | ||
var hasShadow = !util.isNil(shadowColor) && shadowBlur > 0; | ||
var nodeName = object.nodeName; | ||
var isInnerShadow = shadowType === 'inner'; | ||
var shouldDrawShadowWithStroke = hasStroke && hasShadow && (nodeName === gLite.Shape.PATH || nodeName === gLite.Shape.LINE || nodeName === gLite.Shape.POLYLINE || isFillTransparent || isInnerShadow); | ||
if (hasFill) { | ||
context.globalAlpha = opacity * fillOpacity; | ||
if (!shouldDrawShadowWithStroke) { | ||
setShadowAndFilter(object, context, hasShadow); | ||
} | ||
this.fill(context, object, fill, fillRule, canvasContext, plugin); | ||
if (!shouldDrawShadowWithStroke) { | ||
this.clearShadowAndFilter(context, hasFilter, hasShadow); | ||
} | ||
var _proto = DefaultRenderer.prototype; | ||
_proto.render = function render(context, parsedStyle, object, canvasContext, plugin) { | ||
var fill = parsedStyle.fill, | ||
fillRule = parsedStyle.fillRule, | ||
opacity = parsedStyle.opacity, | ||
fillOpacity = parsedStyle.fillOpacity, | ||
stroke = parsedStyle.stroke, | ||
strokeOpacity = parsedStyle.strokeOpacity, | ||
lineWidth = parsedStyle.lineWidth, | ||
lineCap = parsedStyle.lineCap, | ||
lineJoin = parsedStyle.lineJoin, | ||
shadowType = parsedStyle.shadowType, | ||
shadowColor = parsedStyle.shadowColor, | ||
shadowBlur = parsedStyle.shadowBlur, | ||
filter = parsedStyle.filter, | ||
miterLimit = parsedStyle.miterLimit; | ||
var hasFill = !util.isNil(fill) && !fill.isNone; | ||
var hasStroke = !util.isNil(stroke) && !stroke.isNone && lineWidth > 0; | ||
var isFillTransparent = fill.alpha === 0; | ||
var hasFilter = !!(filter && filter.length); | ||
var hasShadow = !util.isNil(shadowColor) && shadowBlur > 0; | ||
var nodeName = object.nodeName; | ||
var isInnerShadow = shadowType === 'inner'; | ||
var shouldDrawShadowWithStroke = hasStroke && hasShadow && (nodeName === gLite.Shape.PATH || nodeName === gLite.Shape.LINE || nodeName === gLite.Shape.POLYLINE || isFillTransparent || isInnerShadow); | ||
if (hasFill) { | ||
context.globalAlpha = opacity * fillOpacity; | ||
if (!shouldDrawShadowWithStroke) { | ||
setShadowAndFilter(object, context, hasShadow); | ||
} | ||
if (hasStroke) { | ||
context.globalAlpha = opacity * strokeOpacity; | ||
context.lineWidth = lineWidth; | ||
if (!util.isNil(miterLimit)) { | ||
context.miterLimit = miterLimit; | ||
} | ||
if (!util.isNil(lineCap)) { | ||
context.lineCap = lineCap; | ||
} | ||
if (!util.isNil(lineJoin)) { | ||
context.lineJoin = lineJoin; | ||
} | ||
if (shouldDrawShadowWithStroke) { | ||
if (isInnerShadow) { | ||
context.globalCompositeOperation = 'source-atop'; | ||
} | ||
setShadowAndFilter(object, context, true); | ||
if (isInnerShadow) { | ||
this.stroke(context, object, stroke, canvasContext, plugin); | ||
context.globalCompositeOperation = 'source-over'; | ||
this.clearShadowAndFilter(context, hasFilter, true); | ||
} | ||
} | ||
this.stroke(context, object, stroke, canvasContext, plugin); | ||
this.fill(context, object, fill, fillRule, canvasContext, plugin); | ||
if (!shouldDrawShadowWithStroke) { | ||
this.clearShadowAndFilter(context, hasFilter, hasShadow); | ||
} | ||
} | ||
}, { | ||
key: "clearShadowAndFilter", | ||
value: function clearShadowAndFilter(context, hasFilter, hasShadow) { | ||
if (hasShadow) { | ||
context.shadowColor = 'transparent'; | ||
context.shadowBlur = 0; | ||
if (hasStroke) { | ||
context.globalAlpha = opacity * strokeOpacity; | ||
context.lineWidth = lineWidth; | ||
if (!util.isNil(miterLimit)) { | ||
context.miterLimit = miterLimit; | ||
} | ||
if (hasFilter) { | ||
// save drop-shadow filter | ||
var oldFilter = context.filter; | ||
if (!util.isNil(oldFilter) && oldFilter.indexOf('drop-shadow') > -1) { | ||
context.filter = oldFilter.replace(/drop-shadow\([^)]*\)/, '').trim() || 'none'; | ||
if (!util.isNil(lineCap)) { | ||
context.lineCap = lineCap; | ||
} | ||
if (!util.isNil(lineJoin)) { | ||
context.lineJoin = lineJoin; | ||
} | ||
if (shouldDrawShadowWithStroke) { | ||
if (isInnerShadow) { | ||
context.globalCompositeOperation = 'source-atop'; | ||
} | ||
setShadowAndFilter(object, context, true); | ||
if (isInnerShadow) { | ||
this.stroke(context, object, stroke, canvasContext, plugin); | ||
context.globalCompositeOperation = 'source-over'; | ||
this.clearShadowAndFilter(context, hasFilter, true); | ||
} | ||
} | ||
this.stroke(context, object, stroke, canvasContext, plugin); | ||
} | ||
}, { | ||
key: "fill", | ||
value: function fill(context, object, _fill, fillRule, canvasContext, plugin) { | ||
var _this = this; | ||
if (Array.isArray(_fill)) { | ||
_fill.forEach(function (gradient) { | ||
context.fillStyle = _this.getColor(gradient, object, context); | ||
context.fill(fillRule); | ||
}); | ||
} else { | ||
if (gLite.isPattern(_fill)) { | ||
context.fillStyle = this.getPattern(_fill, object, context, canvasContext, plugin); | ||
} | ||
}; | ||
_proto.clearShadowAndFilter = function clearShadowAndFilter(context, hasFilter, hasShadow) { | ||
if (hasShadow) { | ||
context.shadowColor = 'transparent'; | ||
context.shadowBlur = 0; | ||
} | ||
if (hasFilter) { | ||
// save drop-shadow filter | ||
var oldFilter = context.filter; | ||
if (!util.isNil(oldFilter) && oldFilter.indexOf('drop-shadow') > -1) { | ||
context.filter = oldFilter.replace(/drop-shadow\([^)]*\)/, '').trim() || 'none'; | ||
} | ||
} | ||
}; | ||
_proto.fill = function fill(context, object, _fill, fillRule, canvasContext, plugin) { | ||
var _this = this; | ||
if (Array.isArray(_fill)) { | ||
_fill.forEach(function (gradient) { | ||
context.fillStyle = _this.getColor(gradient, object, context); | ||
context.fill(fillRule); | ||
}); | ||
} else { | ||
if (gLite.isPattern(_fill)) { | ||
context.fillStyle = this.getPattern(_fill, object, context, canvasContext, plugin); | ||
} | ||
context.fill(fillRule); | ||
} | ||
}, { | ||
key: "stroke", | ||
value: function stroke(context, object, _stroke, canvasContext, plugin) { | ||
var _this2 = this; | ||
if (Array.isArray(_stroke)) { | ||
_stroke.forEach(function (gradient) { | ||
context.strokeStyle = _this2.getColor(gradient, object, context); | ||
context.stroke(); | ||
}); | ||
} else { | ||
if (gLite.isPattern(_stroke)) { | ||
context.strokeStyle = this.getPattern(_stroke, object, context, canvasContext, plugin); | ||
} | ||
}; | ||
_proto.stroke = function stroke(context, object, _stroke, canvasContext, plugin) { | ||
var _this2 = this; | ||
if (Array.isArray(_stroke)) { | ||
_stroke.forEach(function (gradient) { | ||
context.strokeStyle = _this2.getColor(gradient, object, context); | ||
context.stroke(); | ||
}); | ||
} else { | ||
if (gLite.isPattern(_stroke)) { | ||
context.strokeStyle = this.getPattern(_stroke, object, context, canvasContext, plugin); | ||
} | ||
context.stroke(); | ||
} | ||
}, { | ||
key: "getPattern", | ||
value: function getPattern(pattern, object, context, canvasContext, plugin) { | ||
var $offscreenCanvas; | ||
var dpr; | ||
if (pattern.image instanceof gLite.Rect) { | ||
var _pattern$image$parsed = pattern.image.parsedStyle, | ||
width = _pattern$image$parsed.width, | ||
height = _pattern$image$parsed.height; | ||
dpr = canvasContext.contextService.getDPR(); | ||
var offscreenCanvas = canvasContext.config.offscreenCanvas; | ||
$offscreenCanvas = gLite.runtime.offscreenCanvas.getOrCreateCanvas(offscreenCanvas); | ||
$offscreenCanvas.width = width * dpr; | ||
$offscreenCanvas.height = height * dpr; | ||
var offscreenCanvasContext = gLite.runtime.offscreenCanvas.getOrCreateContext(offscreenCanvas); | ||
var restoreStack = []; | ||
// offscreenCanvasContext.scale(1 / dpr, 1 / dpr); | ||
pattern.image.forEach(function (object) { | ||
plugin.renderDisplayObject(object, offscreenCanvasContext, canvasContext, restoreStack); | ||
}); | ||
restoreStack.forEach(function () { | ||
offscreenCanvasContext.restore(); | ||
}); | ||
} | ||
var canvasPattern = this.imagePool.getOrCreatePatternSync(pattern, context, $offscreenCanvas, dpr, function () { | ||
// set dirty rectangle flag | ||
object.renderable.dirty = true; | ||
canvasContext.renderingService.dirtify(); | ||
}; | ||
_proto.getPattern = function getPattern(pattern, object, context, canvasContext, plugin) { | ||
var $offscreenCanvas; | ||
var dpr; | ||
if (pattern.image instanceof gLite.Rect) { | ||
var _pattern$image$parsed = pattern.image.parsedStyle, | ||
width = _pattern$image$parsed.width, | ||
height = _pattern$image$parsed.height; | ||
dpr = canvasContext.contextService.getDPR(); | ||
var offscreenCanvas = canvasContext.config.offscreenCanvas; | ||
$offscreenCanvas = gLite.runtime.offscreenCanvas.getOrCreateCanvas(offscreenCanvas); | ||
$offscreenCanvas.width = width * dpr; | ||
$offscreenCanvas.height = height * dpr; | ||
var offscreenCanvasContext = gLite.runtime.offscreenCanvas.getOrCreateContext(offscreenCanvas); | ||
var restoreStack = []; | ||
// offscreenCanvasContext.scale(1 / dpr, 1 / dpr); | ||
pattern.image.forEach(function (object) { | ||
plugin.renderDisplayObject(object, offscreenCanvasContext, canvasContext, restoreStack); | ||
}); | ||
return canvasPattern; | ||
restoreStack.forEach(function () { | ||
offscreenCanvasContext.restore(); | ||
}); | ||
} | ||
}, { | ||
key: "getColor", | ||
value: function getColor(parsedColor, object, context) { | ||
var color; | ||
if (parsedColor.type === gLite.GradientType.LinearGradient || parsedColor.type === gLite.GradientType.RadialGradient) { | ||
var bounds = object.getGeometryBounds(); | ||
var width = bounds && bounds.halfExtents[0] * 2 || 1; | ||
var height = bounds && bounds.halfExtents[1] * 2 || 1; | ||
color = this.imagePool.getOrCreateGradient(_objectSpread2(_objectSpread2({ | ||
type: parsedColor.type | ||
}, parsedColor.value), {}, { | ||
width: width, | ||
height: height | ||
}), context); | ||
} | ||
return color; | ||
var canvasPattern = this.imagePool.getOrCreatePatternSync(pattern, context, $offscreenCanvas, dpr, function () { | ||
// set dirty rectangle flag | ||
object.renderable.dirty = true; | ||
canvasContext.renderingService.dirtify(); | ||
}); | ||
return canvasPattern; | ||
}; | ||
_proto.getColor = function getColor(parsedColor, object, context) { | ||
var color; | ||
if (parsedColor.type === gLite.GradientType.LinearGradient || parsedColor.type === gLite.GradientType.RadialGradient) { | ||
var bounds = object.getGeometryBounds(); | ||
var width = bounds && bounds.halfExtents[0] * 2 || 1; | ||
var height = bounds && bounds.halfExtents[1] * 2 || 1; | ||
color = this.imagePool.getOrCreateGradient(_extends({ | ||
type: parsedColor.type | ||
}, parsedColor.value, { | ||
width: width, | ||
height: height | ||
}), context); | ||
} | ||
}]); | ||
return color; | ||
}; | ||
return DefaultRenderer; | ||
@@ -1176,36 +966,33 @@ }(); | ||
function ImageRenderer(imagePool) { | ||
_classCallCheck(this, ImageRenderer); | ||
this.imagePool = void 0; | ||
this.imagePool = imagePool; | ||
} | ||
_createClass(ImageRenderer, [{ | ||
key: "render", | ||
value: function render(context, parsedStyle, object) { | ||
var width = parsedStyle.width, | ||
height = parsedStyle.height, | ||
img = parsedStyle.img, | ||
shadowColor = parsedStyle.shadowColor, | ||
shadowBlur = parsedStyle.shadowBlur; | ||
var image; | ||
var iw = width; | ||
var ih = height; | ||
if (util.isString(img)) { | ||
// image has been loaded in `mounted` hook | ||
image = this.imagePool.getImageSync(img); | ||
} else { | ||
iw || (iw = img.width); | ||
ih || (ih = img.height); | ||
image = img; | ||
} | ||
if (image) { | ||
var hasShadow = !util.isNil(shadowColor) && shadowBlur > 0; | ||
setShadowAndFilter(object, context, hasShadow); | ||
// node-canvas will throw the following err: | ||
// Error: Image given has not completed loading | ||
try { | ||
context.drawImage(image, 0, 0, iw, ih); | ||
} catch (e) {} | ||
} | ||
var _proto = ImageRenderer.prototype; | ||
_proto.render = function render(context, parsedStyle, object) { | ||
var width = parsedStyle.width, | ||
height = parsedStyle.height, | ||
img = parsedStyle.img, | ||
shadowColor = parsedStyle.shadowColor, | ||
shadowBlur = parsedStyle.shadowBlur; | ||
var image; | ||
var iw = width; | ||
var ih = height; | ||
if (util.isString(img)) { | ||
// image has been loaded in `mounted` hook | ||
image = this.imagePool.getImageSync(img); | ||
} else { | ||
iw || (iw = img.width); | ||
ih || (ih = img.height); | ||
image = img; | ||
} | ||
}]); | ||
if (image) { | ||
var hasShadow = !util.isNil(shadowColor) && shadowBlur > 0; | ||
setShadowAndFilter(object, context, hasShadow); | ||
// node-canvas will throw the following err: | ||
// Error: Image given has not completed loading | ||
try { | ||
context.drawImage(image, 0, 0, iw, ih); | ||
} catch (e) {} | ||
} | ||
}; | ||
return ImageRenderer; | ||
@@ -1215,132 +1002,124 @@ }(); | ||
var TextRenderer = /*#__PURE__*/function () { | ||
function TextRenderer() { | ||
_classCallCheck(this, TextRenderer); | ||
} | ||
_createClass(TextRenderer, [{ | ||
key: "render", | ||
value: function render(context, parsedStyle, object) { | ||
var lineWidth = parsedStyle.lineWidth, | ||
textAlign = parsedStyle.textAlign, | ||
textBaseline = parsedStyle.textBaseline, | ||
lineJoin = parsedStyle.lineJoin, | ||
miterLimit = parsedStyle.miterLimit, | ||
letterSpacing = parsedStyle.letterSpacing, | ||
stroke = parsedStyle.stroke, | ||
fill = parsedStyle.fill, | ||
fillOpacity = parsedStyle.fillOpacity, | ||
strokeOpacity = parsedStyle.strokeOpacity, | ||
opacity = parsedStyle.opacity, | ||
metrics = parsedStyle.metrics, | ||
dx = parsedStyle.dx, | ||
dy = parsedStyle.dy, | ||
shadowColor = parsedStyle.shadowColor, | ||
shadowBlur = parsedStyle.shadowBlur; | ||
var font = metrics.font, | ||
lines = metrics.lines, | ||
height = metrics.height, | ||
lineHeight = metrics.lineHeight, | ||
lineMetrics = metrics.lineMetrics; | ||
context.font = font; | ||
context.lineWidth = lineWidth; | ||
context.textAlign = textAlign === 'middle' ? 'center' : textAlign; | ||
context.textBaseline = textBaseline; | ||
context.lineJoin = lineJoin; | ||
if (!util.isNil(miterLimit)) { | ||
context.miterLimit = miterLimit; | ||
} | ||
var linePositionY = 0; | ||
// handle vertical text baseline | ||
if (textBaseline === 'middle') { | ||
linePositionY = -height / 2 - lineHeight / 2; | ||
} else if (textBaseline === 'bottom' || textBaseline === 'alphabetic' || textBaseline === 'ideographic') { | ||
linePositionY = -height; | ||
} else if (textBaseline === 'top' || textBaseline === 'hanging') { | ||
linePositionY = -lineHeight; | ||
} | ||
// account for dx & dy | ||
var offsetX = dx || 0; | ||
linePositionY += dy || 0; | ||
var hasShadow = !util.isNil(shadowColor) && shadowBlur > 0; | ||
setShadowAndFilter(object, context, hasShadow); | ||
// draw lines line by line | ||
for (var i = 0; i < lines.length; i++) { | ||
var linePositionX = lineWidth / 2 + offsetX; | ||
linePositionY += lineHeight; | ||
// no need to re-position X, cause we already set text align | ||
// @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textAlign | ||
if (!util.isNil(stroke) && !stroke.isNone && lineWidth) { | ||
this.drawLetterSpacing(context, lines[i], lineMetrics[i], textAlign, linePositionX, linePositionY, letterSpacing, fillOpacity, strokeOpacity, opacity, true); | ||
} | ||
if (!util.isNil(fill)) { | ||
this.drawLetterSpacing(context, lines[i], lineMetrics[i], textAlign, linePositionX, linePositionY, letterSpacing, fillOpacity, strokeOpacity, opacity); | ||
} | ||
} | ||
function TextRenderer() {} | ||
var _proto = TextRenderer.prototype; | ||
_proto.render = function render(context, parsedStyle, object) { | ||
var lineWidth = parsedStyle.lineWidth, | ||
textAlign = parsedStyle.textAlign, | ||
textBaseline = parsedStyle.textBaseline, | ||
lineJoin = parsedStyle.lineJoin, | ||
miterLimit = parsedStyle.miterLimit, | ||
letterSpacing = parsedStyle.letterSpacing, | ||
stroke = parsedStyle.stroke, | ||
fill = parsedStyle.fill, | ||
fillOpacity = parsedStyle.fillOpacity, | ||
strokeOpacity = parsedStyle.strokeOpacity, | ||
opacity = parsedStyle.opacity, | ||
metrics = parsedStyle.metrics, | ||
dx = parsedStyle.dx, | ||
dy = parsedStyle.dy, | ||
shadowColor = parsedStyle.shadowColor, | ||
shadowBlur = parsedStyle.shadowBlur; | ||
var font = metrics.font, | ||
lines = metrics.lines, | ||
height = metrics.height, | ||
lineHeight = metrics.lineHeight, | ||
lineMetrics = metrics.lineMetrics; | ||
context.font = font; | ||
context.lineWidth = lineWidth; | ||
context.textAlign = textAlign === 'middle' ? 'center' : textAlign; | ||
context.textBaseline = textBaseline; | ||
context.lineJoin = lineJoin; | ||
if (!util.isNil(miterLimit)) { | ||
context.miterLimit = miterLimit; | ||
} | ||
}, { | ||
key: "drawLetterSpacing", | ||
value: function drawLetterSpacing(context, text, lineMetrics, textAlign, x, y, letterSpacing, fillOpacity, strokeOpacity, opacity) { | ||
var isStroke = arguments.length > 10 && arguments[10] !== undefined ? arguments[10] : false; | ||
// letterSpacing of 0 means normal, render all texts directly | ||
if (letterSpacing === 0) { | ||
if (isStroke) { | ||
this.strokeText(context, text, x, y, strokeOpacity); | ||
} else { | ||
this.fillText(context, text, x, y, fillOpacity, opacity); | ||
} | ||
return; | ||
var linePositionY = 0; | ||
// handle vertical text baseline | ||
if (textBaseline === 'middle') { | ||
linePositionY = -height / 2 - lineHeight / 2; | ||
} else if (textBaseline === 'bottom' || textBaseline === 'alphabetic' || textBaseline === 'ideographic') { | ||
linePositionY = -height; | ||
} else if (textBaseline === 'top' || textBaseline === 'hanging') { | ||
linePositionY = -lineHeight; | ||
} | ||
// account for dx & dy | ||
var offsetX = dx || 0; | ||
linePositionY += dy || 0; | ||
var hasShadow = !util.isNil(shadowColor) && shadowBlur > 0; | ||
setShadowAndFilter(object, context, hasShadow); | ||
// draw lines line by line | ||
for (var i = 0; i < lines.length; i++) { | ||
var linePositionX = lineWidth / 2 + offsetX; | ||
linePositionY += lineHeight; | ||
// no need to re-position X, cause we already set text align | ||
// @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textAlign | ||
if (!util.isNil(stroke) && !stroke.isNone && lineWidth) { | ||
this.drawLetterSpacing(context, lines[i], lineMetrics[i], textAlign, linePositionX, linePositionY, letterSpacing, fillOpacity, strokeOpacity, opacity, true); | ||
} | ||
// draw text using left align | ||
var currentTextAlign = context.textAlign; | ||
context.textAlign = 'left'; | ||
var currentPosition = x; | ||
if (textAlign === 'center' || textAlign === 'middle') { | ||
currentPosition = x - lineMetrics.width / 2; | ||
} else if (textAlign === 'right' || textAlign === 'end') { | ||
currentPosition = x - lineMetrics.width; | ||
if (!util.isNil(fill)) { | ||
this.drawLetterSpacing(context, lines[i], lineMetrics[i], textAlign, linePositionX, linePositionY, letterSpacing, fillOpacity, strokeOpacity, opacity); | ||
} | ||
var stringArray = Array.from(text); | ||
var previousWidth = context.measureText(text).width; | ||
var currentWidth = 0; | ||
for (var i = 0; i < stringArray.length; ++i) { | ||
var currentChar = stringArray[i]; | ||
if (isStroke) { | ||
this.strokeText(context, currentChar, currentPosition, y, strokeOpacity); | ||
} else { | ||
this.fillText(context, currentChar, currentPosition, y, fillOpacity, opacity); | ||
} | ||
currentWidth = context.measureText(text.substring(i + 1)).width; | ||
currentPosition += previousWidth - currentWidth + letterSpacing; | ||
previousWidth = currentWidth; | ||
} | ||
context.textAlign = currentTextAlign; | ||
} | ||
}, { | ||
key: "fillText", | ||
value: function fillText(context, text, x, y, fillOpacity, opacity) { | ||
var currentGlobalAlpha; | ||
var applyOpacity = !util.isNil(fillOpacity) && fillOpacity !== 1; | ||
if (applyOpacity) { | ||
currentGlobalAlpha = context.globalAlpha; | ||
context.globalAlpha = fillOpacity * opacity; | ||
}; | ||
_proto.drawLetterSpacing = function drawLetterSpacing(context, text, lineMetrics, textAlign, x, y, letterSpacing, fillOpacity, strokeOpacity, opacity, isStroke) { | ||
if (isStroke === void 0) { | ||
isStroke = false; | ||
} | ||
// letterSpacing of 0 means normal, render all texts directly | ||
if (letterSpacing === 0) { | ||
if (isStroke) { | ||
this.strokeText(context, text, x, y, strokeOpacity); | ||
} else { | ||
this.fillText(context, text, x, y, fillOpacity, opacity); | ||
} | ||
context.fillText(text, x, y); | ||
if (applyOpacity) { | ||
context.globalAlpha = currentGlobalAlpha; | ||
} | ||
return; | ||
} | ||
}, { | ||
key: "strokeText", | ||
value: function strokeText(context, text, x, y, strokeOpacity) { | ||
var currentGlobalAlpha; | ||
var applyOpacity = !util.isNil(strokeOpacity) && strokeOpacity !== 1; | ||
if (applyOpacity) { | ||
currentGlobalAlpha = context.globalAlpha; | ||
context.globalAlpha = strokeOpacity; | ||
// draw text using left align | ||
var currentTextAlign = context.textAlign; | ||
context.textAlign = 'left'; | ||
var currentPosition = x; | ||
if (textAlign === 'center' || textAlign === 'middle') { | ||
currentPosition = x - lineMetrics.width / 2; | ||
} else if (textAlign === 'right' || textAlign === 'end') { | ||
currentPosition = x - lineMetrics.width; | ||
} | ||
var stringArray = Array.from(text); | ||
var previousWidth = context.measureText(text).width; | ||
var currentWidth = 0; | ||
for (var i = 0; i < stringArray.length; ++i) { | ||
var currentChar = stringArray[i]; | ||
if (isStroke) { | ||
this.strokeText(context, currentChar, currentPosition, y, strokeOpacity); | ||
} else { | ||
this.fillText(context, currentChar, currentPosition, y, fillOpacity, opacity); | ||
} | ||
context.strokeText(text, x, y); | ||
if (applyOpacity) { | ||
context.globalAlpha = currentGlobalAlpha; | ||
} | ||
currentWidth = context.measureText(text.substring(i + 1)).width; | ||
currentPosition += previousWidth - currentWidth + letterSpacing; | ||
previousWidth = currentWidth; | ||
} | ||
}]); | ||
context.textAlign = currentTextAlign; | ||
}; | ||
_proto.fillText = function fillText(context, text, x, y, fillOpacity, opacity) { | ||
var currentGlobalAlpha; | ||
var applyOpacity = !util.isNil(fillOpacity) && fillOpacity !== 1; | ||
if (applyOpacity) { | ||
currentGlobalAlpha = context.globalAlpha; | ||
context.globalAlpha = fillOpacity * opacity; | ||
} | ||
context.fillText(text, x, y); | ||
if (applyOpacity) { | ||
context.globalAlpha = currentGlobalAlpha; | ||
} | ||
}; | ||
_proto.strokeText = function strokeText(context, text, x, y, strokeOpacity) { | ||
var currentGlobalAlpha; | ||
var applyOpacity = !util.isNil(strokeOpacity) && strokeOpacity !== 1; | ||
if (applyOpacity) { | ||
currentGlobalAlpha = context.globalAlpha; | ||
context.globalAlpha = strokeOpacity; | ||
} | ||
context.strokeText(text, x, y); | ||
if (applyOpacity) { | ||
context.globalAlpha = currentGlobalAlpha; | ||
} | ||
}; | ||
return TextRenderer; | ||
@@ -1350,79 +1129,65 @@ }(); | ||
var RectRenderer = /*#__PURE__*/function (_DefaultRenderer) { | ||
_inherits(RectRenderer, _DefaultRenderer); | ||
var _super = _createSuper(RectRenderer); | ||
_inheritsLoose(RectRenderer, _DefaultRenderer); | ||
function RectRenderer() { | ||
_classCallCheck(this, RectRenderer); | ||
return _super.apply(this, arguments); | ||
return _DefaultRenderer.apply(this, arguments) || this; | ||
} | ||
return _createClass(RectRenderer); | ||
return RectRenderer; | ||
}(DefaultRenderer); | ||
var CircleRenderer = /*#__PURE__*/function (_DefaultRenderer) { | ||
_inherits(CircleRenderer, _DefaultRenderer); | ||
var _super = _createSuper(CircleRenderer); | ||
_inheritsLoose(CircleRenderer, _DefaultRenderer); | ||
function CircleRenderer() { | ||
_classCallCheck(this, CircleRenderer); | ||
return _super.apply(this, arguments); | ||
return _DefaultRenderer.apply(this, arguments) || this; | ||
} | ||
return _createClass(CircleRenderer); | ||
return CircleRenderer; | ||
}(DefaultRenderer); | ||
var EllipseRenderer = /*#__PURE__*/function (_DefaultRenderer) { | ||
_inherits(EllipseRenderer, _DefaultRenderer); | ||
var _super = _createSuper(EllipseRenderer); | ||
_inheritsLoose(EllipseRenderer, _DefaultRenderer); | ||
function EllipseRenderer() { | ||
_classCallCheck(this, EllipseRenderer); | ||
return _super.apply(this, arguments); | ||
return _DefaultRenderer.apply(this, arguments) || this; | ||
} | ||
return _createClass(EllipseRenderer); | ||
return EllipseRenderer; | ||
}(DefaultRenderer); | ||
var LineRenderer = /*#__PURE__*/function (_DefaultRenderer) { | ||
_inherits(LineRenderer, _DefaultRenderer); | ||
var _super = _createSuper(LineRenderer); | ||
_inheritsLoose(LineRenderer, _DefaultRenderer); | ||
function LineRenderer() { | ||
_classCallCheck(this, LineRenderer); | ||
return _super.apply(this, arguments); | ||
return _DefaultRenderer.apply(this, arguments) || this; | ||
} | ||
return _createClass(LineRenderer); | ||
return LineRenderer; | ||
}(DefaultRenderer); | ||
var PolylineRenderer = /*#__PURE__*/function (_DefaultRenderer) { | ||
_inherits(PolylineRenderer, _DefaultRenderer); | ||
var _super = _createSuper(PolylineRenderer); | ||
_inheritsLoose(PolylineRenderer, _DefaultRenderer); | ||
function PolylineRenderer() { | ||
_classCallCheck(this, PolylineRenderer); | ||
return _super.apply(this, arguments); | ||
return _DefaultRenderer.apply(this, arguments) || this; | ||
} | ||
return _createClass(PolylineRenderer); | ||
return PolylineRenderer; | ||
}(DefaultRenderer); | ||
var PolygonRenderer = /*#__PURE__*/function (_DefaultRenderer) { | ||
_inherits(PolygonRenderer, _DefaultRenderer); | ||
var _super = _createSuper(PolygonRenderer); | ||
_inheritsLoose(PolygonRenderer, _DefaultRenderer); | ||
function PolygonRenderer() { | ||
_classCallCheck(this, PolygonRenderer); | ||
return _super.apply(this, arguments); | ||
return _DefaultRenderer.apply(this, arguments) || this; | ||
} | ||
return _createClass(PolygonRenderer); | ||
return PolygonRenderer; | ||
}(DefaultRenderer); | ||
var PathRenderer = /*#__PURE__*/function (_DefaultRenderer) { | ||
_inherits(PathRenderer, _DefaultRenderer); | ||
var _super = _createSuper(PathRenderer); | ||
_inheritsLoose(PathRenderer, _DefaultRenderer); | ||
function PathRenderer() { | ||
_classCallCheck(this, PathRenderer); | ||
return _super.apply(this, arguments); | ||
return _DefaultRenderer.apply(this, arguments) || this; | ||
} | ||
return _createClass(PathRenderer); | ||
return PathRenderer; | ||
}(DefaultRenderer); | ||
var Plugin = /*#__PURE__*/function (_AbstractRendererPlug) { | ||
_inherits(Plugin, _AbstractRendererPlug); | ||
var _super = _createSuper(Plugin); | ||
function Plugin() { | ||
_inheritsLoose(Plugin, _AbstractRendererPlug); | ||
function Plugin(options) { | ||
var _this; | ||
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; | ||
_classCallCheck(this, Plugin); | ||
_this = _super.call(this); | ||
if (options === void 0) { | ||
options = {}; | ||
} | ||
_this = _AbstractRendererPlug.call(this) || this; | ||
_this.options = void 0; | ||
@@ -1433,26 +1198,22 @@ _this.name = 'canvas-renderer'; | ||
} | ||
_createClass(Plugin, [{ | ||
key: "init", | ||
value: function init() { | ||
var _defaultStyleRenderer; | ||
var canvasRendererPluginOptions = _objectSpread2({ | ||
dirtyObjectNumThreshold: 500, | ||
dirtyObjectRatioThreshold: 0.8 | ||
}, this.options); | ||
// @ts-ignore | ||
var imagePool = this.context.imagePool; | ||
var defaultRenderer = new DefaultRenderer(imagePool); | ||
var defaultStyleRendererFactory = (_defaultStyleRenderer = {}, _defineProperty(_defaultStyleRenderer, gLite.Shape.CIRCLE, defaultRenderer), _defineProperty(_defaultStyleRenderer, gLite.Shape.ELLIPSE, defaultRenderer), _defineProperty(_defaultStyleRenderer, gLite.Shape.RECT, defaultRenderer), _defineProperty(_defaultStyleRenderer, gLite.Shape.IMAGE, new ImageRenderer(imagePool)), _defineProperty(_defaultStyleRenderer, gLite.Shape.TEXT, new TextRenderer()), _defineProperty(_defaultStyleRenderer, gLite.Shape.LINE, defaultRenderer), _defineProperty(_defaultStyleRenderer, gLite.Shape.POLYLINE, defaultRenderer), _defineProperty(_defaultStyleRenderer, gLite.Shape.POLYGON, defaultRenderer), _defineProperty(_defaultStyleRenderer, gLite.Shape.PATH, defaultRenderer), _defineProperty(_defaultStyleRenderer, gLite.Shape.GROUP, undefined), _defineProperty(_defaultStyleRenderer, gLite.Shape.HTML, undefined), _defineProperty(_defaultStyleRenderer, gLite.Shape.MESH, undefined), _defaultStyleRenderer); | ||
this.context.defaultStyleRendererFactory = defaultStyleRendererFactory; | ||
this.context.styleRendererFactory = defaultStyleRendererFactory; | ||
this.addRenderingPlugin(new CanvasRendererPlugin(canvasRendererPluginOptions)); | ||
} | ||
}, { | ||
key: "destroy", | ||
value: function destroy() { | ||
this.removeAllRenderingPlugins(); | ||
delete this.context.defaultStyleRendererFactory; | ||
delete this.context.styleRendererFactory; | ||
} | ||
}]); | ||
var _proto = Plugin.prototype; | ||
_proto.init = function init() { | ||
var _defaultStyleRenderer; | ||
var canvasRendererPluginOptions = _extends({ | ||
dirtyObjectNumThreshold: 500, | ||
dirtyObjectRatioThreshold: 0.8 | ||
}, this.options); | ||
// @ts-ignore | ||
var imagePool = this.context.imagePool; | ||
var defaultRenderer = new DefaultRenderer(imagePool); | ||
var defaultStyleRendererFactory = (_defaultStyleRenderer = {}, _defaultStyleRenderer[gLite.Shape.CIRCLE] = defaultRenderer, _defaultStyleRenderer[gLite.Shape.ELLIPSE] = defaultRenderer, _defaultStyleRenderer[gLite.Shape.RECT] = defaultRenderer, _defaultStyleRenderer[gLite.Shape.IMAGE] = new ImageRenderer(imagePool), _defaultStyleRenderer[gLite.Shape.TEXT] = new TextRenderer(), _defaultStyleRenderer[gLite.Shape.LINE] = defaultRenderer, _defaultStyleRenderer[gLite.Shape.POLYLINE] = defaultRenderer, _defaultStyleRenderer[gLite.Shape.POLYGON] = defaultRenderer, _defaultStyleRenderer[gLite.Shape.PATH] = defaultRenderer, _defaultStyleRenderer[gLite.Shape.GROUP] = undefined, _defaultStyleRenderer[gLite.Shape.HTML] = undefined, _defaultStyleRenderer[gLite.Shape.MESH] = undefined, _defaultStyleRenderer); | ||
this.context.defaultStyleRendererFactory = defaultStyleRendererFactory; | ||
this.context.styleRendererFactory = defaultStyleRendererFactory; | ||
this.addRenderingPlugin(new CanvasRendererPlugin(canvasRendererPluginOptions)); | ||
}; | ||
_proto.destroy = function destroy() { | ||
this.removeAllRenderingPlugins(); | ||
delete this.context.defaultStyleRendererFactory; | ||
delete this.context.styleRendererFactory; | ||
}; | ||
return Plugin; | ||
@@ -1459,0 +1220,0 @@ }(gLite.AbstractRendererPlugin); |
@@ -1,1 +0,1 @@ | ||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("@antv/g-lite")):"function"==typeof define&&define.amd?define(["exports","@antv/g-lite"],e):e(((t="undefined"!=typeof globalThis?globalThis:t||self).G=t.G||{},t.G.CanvasRenderer={}),t.window.G)}(this,(function(t,e){"use strict";function r(t,e){var r=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),r.push.apply(r,n)}return r}function n(t){for(var e=1;arguments.length>e;e++){var n=null!=arguments[e]?arguments[e]:{};e%2?r(Object(n),!0).forEach((function(e){s(t,e,n[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(n)):r(Object(n)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(n,e))}))}return t}function i(){i=function(){return t};var t={},e=Object.prototype,r=e.hasOwnProperty,n=Object.defineProperty||function(t,e,r){t[e]=r.value},o="function"==typeof Symbol?Symbol:{},a=o.iterator||"@@iterator",c=o.asyncIterator||"@@asyncIterator",l=o.toStringTag||"@@toStringTag";function u(t,e,r){return Object.defineProperty(t,e,{value:r,enumerable:!0,configurable:!0,writable:!0}),t[e]}try{u({},"")}catch(t){u=function(t,e,r){return t[e]=r}}function s(t,e,r,i){var o=Object.create((e&&e.prototype instanceof d?e:d).prototype),a=new P(i||[]);return n(o,"_invoke",{value:O(t,r,a)}),o}function h(t,e,r){try{return{type:"normal",arg:t.call(e,r)}}catch(t){return{type:"throw",arg:t}}}t.wrap=s;var f={};function d(){}function p(){}function v(){}var y={};u(y,a,(function(){return this}));var g=Object.getPrototypeOf,m=g&&g(g(M([])));m&&m!==e&&r.call(m,a)&&(y=m);var b=v.prototype=d.prototype=Object.create(y);function w(t){["next","throw","return"].forEach((function(e){u(t,e,(function(t){return this._invoke(e,t)}))}))}function x(t,e){function i(n,o,a,c){var l=h(t[n],t,o);if("throw"!==l.type){var u=l.arg,s=u.value;return s&&"object"==typeof s&&r.call(s,"__await")?e.resolve(s.__await).then((function(t){i("next",t,a,c)}),(function(t){i("throw",t,a,c)})):e.resolve(s).then((function(t){u.value=t,a(u)}),(function(t){return i("throw",t,a,c)}))}c(l.arg)}var o;n(this,"_invoke",{value:function(t,r){function n(){return new e((function(e,n){i(t,r,e,n)}))}return o=o?o.then(n,n):n()}})}function O(t,e,r){var n="suspendedStart";return function(i,o){if("executing"===n)throw Error("Generator is already running");if("completed"===n){if("throw"===i)throw o;return B()}for(r.method=i,r.arg=o;;){var a=r.delegate;if(a){var c=A(a,r);if(c){if(c===f)continue;return c}}if("next"===r.method)r.sent=r._sent=r.arg;else if("throw"===r.method){if("suspendedStart"===n)throw n="completed",r.arg;r.dispatchException(r.arg)}else"return"===r.method&&r.abrupt("return",r.arg);n="executing";var l=h(t,e,r);if("normal"===l.type){if(n=r.done?"completed":"suspendedYield",l.arg===f)continue;return{value:l.arg,done:r.done}}"throw"===l.type&&(n="completed",r.method="throw",r.arg=l.arg)}}}function A(t,e){var r=e.method,n=t.iterator[r];if(void 0===n)return e.delegate=null,"throw"===r&&t.iterator.return&&(e.method="return",e.arg=void 0,A(t,e),"throw"===e.method)||"return"!==r&&(e.method="throw",e.arg=new TypeError("The iterator does not provide a '"+r+"' method")),f;var i=h(n,t.iterator,e.arg);if("throw"===i.type)return e.method="throw",e.arg=i.arg,e.delegate=null,f;var o=i.arg;return o?o.done?(e[t.resultName]=o.value,e.next=t.nextLoc,"return"!==e.method&&(e.method="next",e.arg=void 0),e.delegate=null,f):o:(e.method="throw",e.arg=new TypeError("iterator result is not an object"),e.delegate=null,f)}function S(t){var e={tryLoc:t[0]};1 in t&&(e.catchLoc=t[1]),2 in t&&(e.finallyLoc=t[2],e.afterLoc=t[3]),this.tryEntries.push(e)}function E(t){var e=t.completion||{};e.type="normal",delete e.arg,t.completion=e}function P(t){this.tryEntries=[{tryLoc:"root"}],t.forEach(S,this),this.reset(!0)}function M(t){if(t){var e=t[a];if(e)return e.call(t);if("function"==typeof t.next)return t;if(!isNaN(t.length)){var n=-1,i=function e(){for(;++n<t.length;)if(r.call(t,n))return e.value=t[n],e.done=!1,e;return e.value=void 0,e.done=!0,e};return i.next=i}}return{next:B}}function B(){return{value:void 0,done:!0}}return p.prototype=v,n(b,"constructor",{value:v,configurable:!0}),n(v,"constructor",{value:p,configurable:!0}),p.displayName=u(v,l,"GeneratorFunction"),t.isGeneratorFunction=function(t){var e="function"==typeof t&&t.constructor;return!!e&&(e===p||"GeneratorFunction"===(e.displayName||e.name))},t.mark=function(t){return Object.setPrototypeOf?Object.setPrototypeOf(t,v):(t.__proto__=v,u(t,l,"GeneratorFunction")),t.prototype=Object.create(b),t},t.awrap=function(t){return{__await:t}},w(x.prototype),u(x.prototype,c,(function(){return this})),t.AsyncIterator=x,t.async=function(e,r,n,i,o){void 0===o&&(o=Promise);var a=new x(s(e,r,n,i),o);return t.isGeneratorFunction(r)?a:a.next().then((function(t){return t.done?t.value:a.next()}))},w(b),u(b,l,"Generator"),u(b,a,(function(){return this})),u(b,"toString",(function(){return"[object Generator]"})),t.keys=function(t){var e=Object(t),r=[];for(var n in e)r.push(n);return r.reverse(),function t(){for(;r.length;){var n=r.pop();if(n in e)return t.value=n,t.done=!1,t}return t.done=!0,t}},t.values=M,P.prototype={constructor:P,reset:function(t){if(this.prev=0,this.next=0,this.sent=this._sent=void 0,this.done=!1,this.delegate=null,this.method="next",this.arg=void 0,this.tryEntries.forEach(E),!t)for(var e in this)"t"===e.charAt(0)&&r.call(this,e)&&!isNaN(+e.slice(1))&&(this[e]=void 0)},stop:function(){this.done=!0;var t=this.tryEntries[0].completion;if("throw"===t.type)throw t.arg;return this.rval},dispatchException:function(t){if(this.done)throw t;var e=this;function n(r,n){return a.type="throw",a.arg=t,e.next=r,n&&(e.method="next",e.arg=void 0),!!n}for(var i=this.tryEntries.length-1;i>=0;--i){var o=this.tryEntries[i],a=o.completion;if("root"===o.tryLoc)return n("end");if(this.prev>=o.tryLoc){var c=r.call(o,"catchLoc"),l=r.call(o,"finallyLoc");if(c&&l){if(o.catchLoc>this.prev)return n(o.catchLoc,!0);if(o.finallyLoc>this.prev)return n(o.finallyLoc)}else if(c){if(o.catchLoc>this.prev)return n(o.catchLoc,!0)}else{if(!l)throw Error("try statement without catch or finally");if(o.finallyLoc>this.prev)return n(o.finallyLoc)}}}},abrupt:function(t,e){for(var n=this.tryEntries.length-1;n>=0;--n){var i=this.tryEntries[n];if(this.prev>=i.tryLoc&&r.call(i,"finallyLoc")&&i.finallyLoc>this.prev){var o=i;break}}o&&("break"===t||"continue"===t)&&e>=o.tryLoc&&o.finallyLoc>=e&&(o=null);var a=o?o.completion:{};return a.type=t,a.arg=e,o?(this.method="next",this.next=o.finallyLoc,f):this.complete(a)},complete:function(t,e){if("throw"===t.type)throw t.arg;return"break"===t.type||"continue"===t.type?this.next=t.arg:"return"===t.type?(this.rval=this.arg=t.arg,this.method="return",this.next="end"):"normal"===t.type&&e&&(this.next=e),f},finish:function(t){for(var e=this.tryEntries.length-1;e>=0;--e){var r=this.tryEntries[e];if(r.finallyLoc===t)return this.complete(r.completion,r.afterLoc),E(r),f}},catch:function(t){for(var e=this.tryEntries.length-1;e>=0;--e){var r=this.tryEntries[e];if(r.tryLoc===t){var n=r.completion;if("throw"===n.type){var i=n.arg;E(r)}return i}}throw Error("illegal catch attempt")},delegateYield:function(t,e,r){return this.delegate={iterator:M(t),resultName:e,nextLoc:r},"next"===this.method&&(this.arg=void 0),f}},t}function o(t,e,r,n,i,o,a){try{var c=t[o](a),l=c.value}catch(t){return void r(t)}c.done?e(l):Promise.resolve(l).then(n,i)}function a(t){return function(){var e=this,r=arguments;return new Promise((function(n,i){var a=t.apply(e,r);function c(t){o(a,n,i,c,l,"next",t)}function l(t){o(a,n,i,c,l,"throw",t)}c(void 0)}))}}function c(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function l(t,e){for(var r=0;e.length>r;r++){var n=e[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,w(n.key),n)}}function u(t,e,r){return e&&l(t.prototype,e),r&&l(t,r),Object.defineProperty(t,"prototype",{writable:!1}),t}function s(t,e,r){return(e=w(e))in t?Object.defineProperty(t,e,{value:r,enumerable:!0,configurable:!0,writable:!0}):t[e]=r,t}function h(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),Object.defineProperty(t,"prototype",{writable:!1}),e&&d(t,e)}function f(t){return f=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(t){return t.__proto__||Object.getPrototypeOf(t)},f(t)}function d(t,e){return d=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(t,e){return t.__proto__=e,t},d(t,e)}function p(t,e){if(e&&("object"==typeof e||"function"==typeof e))return e;if(void 0!==e)throw new TypeError("Derived constructors may only return object or undefined");return function(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}(t)}function v(t){var e=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(t){return!1}}();return function(){var r,n=f(t);if(e){var i=f(this).constructor;r=Reflect.construct(n,arguments,i)}else r=n.apply(this,arguments);return p(this,r)}}function y(t,e){return function(t){if(Array.isArray(t))return t}(t)||function(t,e){var r=null==t?null:"undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(null!=r){var n,i,o,a,c=[],l=!0,u=!1;try{if(o=(r=r.call(t)).next,0===e){if(Object(r)!==r)return;l=!1}else for(;!(l=(n=o.call(r)).done)&&(c.push(n.value),c.length!==e);l=!0);}catch(t){u=!0,i=t}finally{try{if(!l&&null!=r.return&&(a=r.return(),Object(a)!==a))return}finally{if(u)throw i}}return c}}(t,e)||m(t,e)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function g(t){return function(t){if(Array.isArray(t))return b(t)}(t)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(t)||m(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function m(t,e){if(t){if("string"==typeof t)return b(t,e);var r=Object.prototype.toString.call(t).slice(8,-1);return"Object"===r&&t.constructor&&(r=t.constructor.name),"Map"===r||"Set"===r?Array.from(t):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?b(t,e):void 0}}function b(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,n=Array(e);e>r;r++)n[r]=t[r];return n}function w(t){var e=function(t,e){if("object"!=typeof t||null===t)return t;var r=t[Symbol.toPrimitive];if(void 0!==r){var n=r.call(t,e||"default");if("object"!=typeof n)return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===e?String:Number)(t)}(t,"string");return"symbol"==typeof e?e:e+""}var x="undefined"!=typeof Float32Array?Float32Array:Array;function O(){var t=new x(16);return x!=Float32Array&&(t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[11]=0,t[12]=0,t[13]=0,t[14]=0),t[0]=1,t[5]=1,t[10]=1,t[15]=1,t}function A(t,e){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t}function S(t,e,r){var n=e[0],i=e[1],o=e[2],a=e[3],c=e[4],l=e[5],u=e[6],s=e[7],h=e[8],f=e[9],d=e[10],p=e[11],v=e[12],y=e[13],g=e[14],m=e[15],b=r[0],w=r[1],x=r[2],O=r[3];return t[0]=b*n+w*c+x*h+O*v,t[1]=b*i+w*l+x*f+O*y,t[2]=b*o+w*u+x*d+O*g,t[3]=b*a+w*s+x*p+O*m,t[4]=(b=r[4])*n+(w=r[5])*c+(x=r[6])*h+(O=r[7])*v,t[5]=b*i+w*l+x*f+O*y,t[6]=b*o+w*u+x*d+O*g,t[7]=b*a+w*s+x*p+O*m,t[8]=(b=r[8])*n+(w=r[9])*c+(x=r[10])*h+(O=r[11])*v,t[9]=b*i+w*l+x*f+O*y,t[10]=b*o+w*u+x*d+O*g,t[11]=b*a+w*s+x*p+O*m,t[12]=(b=r[12])*n+(w=r[13])*c+(x=r[14])*h+(O=r[15])*v,t[13]=b*i+w*l+x*f+O*y,t[14]=b*o+w*u+x*d+O*g,t[15]=b*a+w*s+x*p+O*m,t}function E(t,e,r){var n,i,o,a,c,l,u,s,h,f,d,p,v=r[0],y=r[1],g=r[2];return e===t?(t[12]=e[0]*v+e[4]*y+e[8]*g+e[12],t[13]=e[1]*v+e[5]*y+e[9]*g+e[13],t[14]=e[2]*v+e[6]*y+e[10]*g+e[14],t[15]=e[3]*v+e[7]*y+e[11]*g+e[15]):(i=e[1],o=e[2],a=e[3],c=e[4],l=e[5],u=e[6],s=e[7],h=e[8],f=e[9],d=e[10],p=e[11],t[0]=n=e[0],t[1]=i,t[2]=o,t[3]=a,t[4]=c,t[5]=l,t[6]=u,t[7]=s,t[8]=h,t[9]=f,t[10]=d,t[11]=p,t[12]=n*v+c*y+h*g+e[12],t[13]=i*v+l*y+f*g+e[13],t[14]=o*v+u*y+d*g+e[14],t[15]=a*v+s*y+p*g+e[15]),t}function P(){var t=new x(3);return x!=Float32Array&&(t[0]=0,t[1]=0,t[2]=0),t}function M(t,e,r){var n=new x(3);return n[0]=t,n[1]=e,n[2]=r,n}function B(t,e,r){var n=e[0],i=e[1],o=e[2],a=r[3]*n+r[7]*i+r[11]*o+r[15];return t[0]=(r[0]*n+r[4]*i+r[8]*o+r[12])/(a=a||1),t[1]=(r[1]*n+r[5]*i+r[9]*o+r[13])/a,t[2]=(r[2]*n+r[6]*i+r[10]*o+r[14])/a,t}Math.hypot||(Math.hypot=function(){for(var t=0,e=arguments.length;e--;)t+=arguments[e]*arguments[e];return Math.sqrt(t)});R=P();var R,k=function(t){return null==t},L={}.toString,j=function(t){return e="String",L.call(t)==="[object "+e+"]";var e},T=function(){function t(e){c(this,t),this.canvasRendererPluginOptions=void 0,this.context=void 0,this.pathGeneratorFactory=void 0,this.rBush=void 0,this.removedRBushNodeAABBs=[],this.renderQueue=[],this.restoreStack=[],this.clearFullScreen=!1,this.vpMatrix=O(),this.dprMatrix=O(),this.tmpMat4=O(),this.vec3a=P(),this.vec3b=P(),this.vec3c=P(),this.vec3d=P(),this.canvasRendererPluginOptions=e}return u(t,[{key:"apply",value:function(r){var n=this;this.context=r;var o=r.config,c=r.camera,l=r.renderingService,u=r.renderingContext,s=r.pathGeneratorFactory;this.rBush=r.rBushRoot,this.pathGeneratorFactory=s;var h=r.contextService,f=u.root.ownerDocument.defaultView,d=function(t){var e=t.target.rBushNode;e.aabb&&n.removedRBushNodeAABBs.push(e.aabb)},p=function(t){var e=t.target.rBushNode;e.aabb&&n.removedRBushNodeAABBs.push(e.aabb)};l.hooks.init.tapPromise(t.tag,a(i().mark((function t(){var r,a,c,l;return i().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:f.addEventListener(e.ElementEvent.UNMOUNTED,d),f.addEventListener(e.ElementEvent.CULLED,p),r=h.getDPR(),a=o.width,c=o.height,l=h.getContext(),n.clearRect(l,0,0,a*r,c*r,o.background);case 6:case"end":return t.stop()}}),t)})))),l.hooks.destroy.tap(t.tag,(function(){f.removeEventListener(e.ElementEvent.UNMOUNTED,d),f.removeEventListener(e.ElementEvent.CULLED,p)})),l.hooks.beginFrame.tap(t.tag,(function(){var t=h.getContext(),e=h.getDPR(),r=o.width,i=o.height,a=n.canvasRendererPluginOptions,c=a.dirtyObjectNumThreshold,u=a.dirtyObjectRatioThreshold,s=l.getStats(),f=s.rendered,d=f/s.total;n.clearFullScreen=l.disableDirtyRectangleRendering()||f>c&&d>u,t&&(t.resetTransform(),n.clearFullScreen&&n.clearRect(t,0,0,r*e,i*e,o.background))}));var v=function t(e,r){e.isVisible()&&!e.isCulled()&&(n.renderDisplayObject(e,r,n.context,n.restoreStack),n.saveDirtyAABB(e)),(e.sortable.sorted||e.childNodes).forEach((function(e){t(e,r)}))};l.hooks.endFrame.tap(t.tag,(function(){var t,r,i=h.getContext(),a=h.getDPR();if(t=n.dprMatrix,r=M(a,a,1),t[0]=r[0],t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=r[1],t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=r[2],t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,S(n.vpMatrix,n.dprMatrix,c.getOrthoMatrix()),n.clearFullScreen)v(u.root,i);else{var l=n.safeMergeAABB.apply(n,[n.mergeDirtyAABBs(n.renderQueue)].concat(g(n.removedRBushNodeAABBs.map((function(t){var r=t.minX,n=t.minY,i=t.maxX,o=t.maxY,a=new e.AABB;return a.setMinMax(M(r,n,0),M(i,o,0)),a})))));if(n.removedRBushNodeAABBs=[],e.AABB.isEmpty(l))return void(n.renderQueue=[]);var s=n.convertAABB2Rect(l),d=s.x,p=s.y,y=s.width,m=s.height,b=B(n.vec3a,M(d,p,0),n.vpMatrix),w=B(n.vec3b,M(d+y,p,0),n.vpMatrix),x=B(n.vec3c,M(d,p+m,0),n.vpMatrix),O=B(n.vec3d,M(d+y,p+m,0),n.vpMatrix),A=Math.min(b[0],w[0],O[0],x[0]),E=Math.min(b[1],w[1],O[1],x[1]),P=Math.max(b[0],w[0],O[0],x[0]),R=Math.max(b[1],w[1],O[1],x[1]),k=Math.floor(A),L=Math.floor(E),j=Math.ceil(P-A),T=Math.ceil(R-E);i.save(),n.clearRect(i,k,L,j,T,o.background),i.beginPath(),i.rect(k,L,j,T),i.clip(),i.setTransform(n.vpMatrix[0],n.vpMatrix[1],n.vpMatrix[4],n.vpMatrix[5],n.vpMatrix[12],n.vpMatrix[13]),o.renderer.getConfig().enableDirtyRectangleRenderingDebug&&f.dispatchEvent(new e.CustomEvent(e.CanvasEvent.DIRTY_RECTANGLE,{dirtyRect:{x:k,y:L,width:j,height:T}})),n.searchDirtyObjects(l).sort((function(t,e){return t.sortable.renderOrder-e.sortable.renderOrder})).forEach((function(t){t&&t.isVisible()&&!t.isCulled()&&n.renderDisplayObject(t,i,n.context,n.restoreStack)})),i.restore(),n.renderQueue.forEach((function(t){n.saveDirtyAABB(t)})),n.renderQueue=[]}n.restoreStack.forEach((function(){i.restore()})),n.restoreStack=[]})),l.hooks.render.tap(t.tag,(function(t){n.clearFullScreen||n.renderQueue.push(t)}))}},{key:"clearRect",value:function(t,e,r,n,i,o){t.clearRect(e,r,n,i),o&&(t.fillStyle=o,t.fillRect(e,r,n,i))}},{key:"renderDisplayObject",value:function(t,r,n,i){var o=t.nodeName,a=i[i.length-1];!a||t.compareDocumentPosition(a)&Node.DOCUMENT_POSITION_CONTAINS||(r.restore(),i.pop());var c=this.context.styleRendererFactory[o],l=this.pathGeneratorFactory[o],u=t.parsedStyle.clipPath;if(u){this.applyWorldTransform(r,u);var s=this.pathGeneratorFactory[u.nodeName];s&&(r.save(),i.push(t),r.beginPath(),s(r,u.parsedStyle),r.closePath(),r.clip())}c&&(this.applyWorldTransform(r,t),r.save(),this.applyAttributesToContext(r,t)),l&&(r.beginPath(),l(r,t.parsedStyle),t.nodeName!==e.Shape.LINE&&t.nodeName!==e.Shape.PATH&&t.nodeName!==e.Shape.POLYLINE&&r.closePath()),c&&(c.render(r,t.parsedStyle,t,n,this),r.restore()),t.renderable.dirty=!1}},{key:"convertAABB2Rect",value:function(t){var e=t.getMin(),r=t.getMax(),n=Math.floor(e[0]),i=Math.floor(e[1]);return{x:n,y:i,width:Math.ceil(r[0])-n,height:Math.ceil(r[1])-i}}},{key:"mergeDirtyAABBs",value:function(t){var r=new e.AABB;return t.forEach((function(t){var e=t.getRenderBounds();r.add(e);var n=t.renderable.dirtyRenderBounds;n&&r.add(n)})),r}},{key:"searchDirtyObjects",value:function(t){var r=y(t.getMin(),2),n=r[0],i=r[1],o=y(t.getMax(),2);return this.rBush.search({minX:n,minY:i,maxX:o[0],maxY:o[1]}).map((function(t){return e.runtime.displayObjectPool.getByEntity(t.id)}))}},{key:"saveDirtyAABB",value:function(t){var r=t.renderable;r.dirtyRenderBounds||(r.dirtyRenderBounds=new e.AABB);var n=t.getRenderBounds();n&&r.dirtyRenderBounds.update(n.center,n.halfExtents)}},{key:"applyAttributesToContext",value:function(t,e){var r=e.parsedStyle,n=r.stroke,i=r.fill,o=r.opacity,a=r.lineDash,c=r.lineDashOffset;a&&t.setLineDash(a),k(c)||(t.lineDashOffset=c),k(o)||(t.globalAlpha*=o),k(n)||Array.isArray(n)||n.isNone||(t.strokeStyle=e.attributes.stroke),k(i)||Array.isArray(i)||i.isNone||(t.fillStyle=e.attributes.fill)}},{key:"applyWorldTransform",value:function(t,e,r){var n=0,i=0,o=(e.parsedStyle||{}).anchor,a=o&&o[0]||0,c=o&&o[1]||0;if(0!==a||0!==c){var l=e.getGeometryBounds();n=-a*(l&&2*l.halfExtents[0]||0),i=-c*(l&&2*l.halfExtents[1]||0)}r?(A(this.tmpMat4,e.getLocalTransform()),this.vec3a[0]=n,this.vec3a[1]=i,this.vec3a[2]=0,E(this.tmpMat4,this.tmpMat4,this.vec3a),S(this.tmpMat4,r,this.tmpMat4),S(this.tmpMat4,this.vpMatrix,this.tmpMat4)):(A(this.tmpMat4,e.getWorldTransform()),this.vec3a[0]=n,this.vec3a[1]=i,this.vec3a[2]=0,E(this.tmpMat4,this.tmpMat4,this.vec3a),S(this.tmpMat4,this.vpMatrix,this.tmpMat4)),t.setTransform(this.tmpMat4[0],this.tmpMat4[1],this.tmpMat4[4],this.tmpMat4[5],this.tmpMat4[12],this.tmpMat4[13])}},{key:"safeMergeAABB",value:function(){for(var t=new e.AABB,r=arguments.length,n=Array(r),i=0;r>i;i++)n[i]=arguments[i];return n.forEach((function(e){t.add(e)})),t}}]),t}();T.tag="CanvasRenderer";var N=function(){function t(e){c(this,t),this.imagePool=void 0,this.imagePool=e}return u(t,[{key:"render",value:function(t,r,n,i,o){var a=r.fill,c=r.fillRule,l=r.opacity,u=r.fillOpacity,s=r.stroke,h=r.strokeOpacity,f=r.lineWidth,d=r.lineCap,p=r.lineJoin,v=r.shadowType,y=r.shadowColor,g=r.shadowBlur,m=r.filter,b=r.miterLimit,w=!k(a)&&!a.isNone,x=!k(s)&&!s.isNone&&f>0,O=0===a.alpha,A=!(!m||!m.length),S=!k(y)&&g>0,E=n.nodeName,P="inner"===v,M=x&&S&&(E===e.Shape.PATH||E===e.Shape.LINE||E===e.Shape.POLYLINE||O||P);w&&(t.globalAlpha=l*u,M||C(n,t,S),this.fill(t,n,a,c,i,o),M||this.clearShadowAndFilter(t,A,S)),x&&(t.globalAlpha=l*h,t.lineWidth=f,k(b)||(t.miterLimit=b),k(d)||(t.lineCap=d),k(p)||(t.lineJoin=p),M&&(P&&(t.globalCompositeOperation="source-atop"),C(n,t,!0),P&&(this.stroke(t,n,s,i,o),t.globalCompositeOperation="source-over",this.clearShadowAndFilter(t,A,!0))),this.stroke(t,n,s,i,o))}},{key:"clearShadowAndFilter",value:function(t,e,r){if(r&&(t.shadowColor="transparent",t.shadowBlur=0),e){var n=t.filter;!k(n)&&n.indexOf("drop-shadow")>-1&&(t.filter=n.replace(/drop-shadow\([^)]*\)/,"").trim()||"none")}}},{key:"fill",value:function(t,r,n,i,o,a){var c=this;Array.isArray(n)?n.forEach((function(e){t.fillStyle=c.getColor(e,r,t),t.fill(i)})):(e.isPattern(n)&&(t.fillStyle=this.getPattern(n,r,t,o,a)),t.fill(i))}},{key:"stroke",value:function(t,r,n,i,o){var a=this;Array.isArray(n)?n.forEach((function(e){t.strokeStyle=a.getColor(e,r,t),t.stroke()})):(e.isPattern(n)&&(t.strokeStyle=this.getPattern(n,r,t,i,o)),t.stroke())}},{key:"getPattern",value:function(t,r,n,i,o){var a,c;if(t.image instanceof e.Rect){var l=t.image.parsedStyle,u=l.width,s=l.height;c=i.contextService.getDPR();var h=i.config.offscreenCanvas;(a=e.runtime.offscreenCanvas.getOrCreateCanvas(h)).width=u*c,a.height=s*c;var f=e.runtime.offscreenCanvas.getOrCreateContext(h),d=[];t.image.forEach((function(t){o.renderDisplayObject(t,f,i,d)})),d.forEach((function(){f.restore()}))}return this.imagePool.getOrCreatePatternSync(t,n,a,c,(function(){r.renderable.dirty=!0,i.renderingService.dirtify()}))}},{key:"getColor",value:function(t,r,i){var o;if(t.type===e.GradientType.LinearGradient||t.type===e.GradientType.RadialGradient){var a=r.getGeometryBounds(),c=a&&2*a.halfExtents[0]||1,l=a&&2*a.halfExtents[1]||1;o=this.imagePool.getOrCreateGradient(n(n({type:t.type},t.value),{},{width:c,height:l}),i)}return o}}]),t}();function C(t,e,r){var n=t.parsedStyle,i=n.filter,o=n.shadowColor,a=n.shadowBlur,c=n.shadowOffsetX,l=n.shadowOffsetY;i&&i.length&&(e.filter=t.style.filter),r&&(e.shadowColor=""+o,e.shadowBlur=a||0,e.shadowOffsetX=c||0,e.shadowOffsetY=l||0)}var D=function(){function t(e){c(this,t),this.imagePool=void 0,this.imagePool=e}return u(t,[{key:"render",value:function(t,e,r){var n,i=e.img,o=e.shadowColor,a=e.shadowBlur,c=e.width,l=e.height;if(j(i)?n=this.imagePool.getImageSync(i):(c||(c=i.width),l||(l=i.height),n=i),n){C(r,t,!k(o)&&a>0);try{t.drawImage(n,0,0,c,l)}catch(t){}}}}]),t}(),F=function(){function t(){c(this,t)}return u(t,[{key:"render",value:function(t,e,r){var n=e.lineWidth,i=e.textAlign,o=e.textBaseline,a=e.lineJoin,c=e.miterLimit,l=e.letterSpacing,u=e.stroke,s=e.fill,h=e.fillOpacity,f=e.strokeOpacity,d=e.opacity,p=e.metrics,v=e.dx,y=e.dy,g=e.shadowColor,m=e.shadowBlur,b=p.lines,w=p.height,x=p.lineHeight,O=p.lineMetrics;t.font=p.font,t.lineWidth=n,t.textAlign="middle"===i?"center":i,t.textBaseline=o,t.lineJoin=a,k(c)||(t.miterLimit=c);var A=0;"middle"===o?A=-w/2-x/2:"bottom"===o||"alphabetic"===o||"ideographic"===o?A=-w:"top"!==o&&"hanging"!==o||(A=-x);var S=v||0;A+=y||0,C(r,t,!k(g)&&m>0);for(var E=0;b.length>E;E++){var P=n/2+S;A+=x,k(u)||u.isNone||!n||this.drawLetterSpacing(t,b[E],O[E],i,P,A,l,h,f,d,!0),k(s)||this.drawLetterSpacing(t,b[E],O[E],i,P,A,l,h,f,d)}}},{key:"drawLetterSpacing",value:function(t,e,r,n,i,o,a,c,l,u){var s=arguments.length>10&&void 0!==arguments[10]&&arguments[10];if(0!==a){var h=t.textAlign;t.textAlign="left";var f=i;"center"===n||"middle"===n?f=i-r.width/2:"right"!==n&&"end"!==n||(f=i-r.width);for(var d=Array.from(e),p=t.measureText(e).width,v=0,y=0;d.length>y;++y){var g=d[y];s?this.strokeText(t,g,f,o,l):this.fillText(t,g,f,o,c,u),f+=p-(v=t.measureText(e.substring(y+1)).width)+a,p=v}t.textAlign=h}else s?this.strokeText(t,e,i,o,l):this.fillText(t,e,i,o,c,u)}},{key:"fillText",value:function(t,e,r,n,i,o){var a,c=!k(i)&&1!==i;c&&(a=t.globalAlpha,t.globalAlpha=i*o),t.fillText(e,r,n),c&&(t.globalAlpha=a)}},{key:"strokeText",value:function(t,e,r,n,i){var o,a=!k(i)&&1!==i;a&&(o=t.globalAlpha,t.globalAlpha=i),t.strokeText(e,r,n),a&&(t.globalAlpha=o)}}]),t}(),G=function(t){h(r,t);var e=v(r);function r(){return c(this,r),e.apply(this,arguments)}return u(r)}(N),_=function(t){h(r,t);var e=v(r);function r(){return c(this,r),e.apply(this,arguments)}return u(r)}(N),I=function(t){h(r,t);var e=v(r);function r(){return c(this,r),e.apply(this,arguments)}return u(r)}(N),Y=function(t){h(r,t);var e=v(r);function r(){return c(this,r),e.apply(this,arguments)}return u(r)}(N),U=function(t){h(r,t);var e=v(r);function r(){return c(this,r),e.apply(this,arguments)}return u(r)}(N),W=function(t){h(r,t);var e=v(r);function r(){return c(this,r),e.apply(this,arguments)}return u(r)}(N),X=function(t){h(r,t);var e=v(r);function r(){return c(this,r),e.apply(this,arguments)}return u(r)}(N),H=function(t){h(i,t);var r=v(i);function i(){var t,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return c(this,i),(t=r.call(this)).options=void 0,t.name="canvas-renderer",t.options=e,t}return u(i,[{key:"init",value:function(){var t,r=n({dirtyObjectNumThreshold:500,dirtyObjectRatioThreshold:.8},this.options),i=this.context.imagePool,o=new N(i),a=(s(t={},e.Shape.CIRCLE,o),s(t,e.Shape.ELLIPSE,o),s(t,e.Shape.RECT,o),s(t,e.Shape.IMAGE,new D(i)),s(t,e.Shape.TEXT,new F),s(t,e.Shape.LINE,o),s(t,e.Shape.POLYLINE,o),s(t,e.Shape.POLYGON,o),s(t,e.Shape.PATH,o),s(t,e.Shape.GROUP,void 0),s(t,e.Shape.HTML,void 0),s(t,e.Shape.MESH,void 0),t);this.context.defaultStyleRendererFactory=a,this.context.styleRendererFactory=a,this.addRenderingPlugin(new T(r))}},{key:"destroy",value:function(){this.removeAllRenderingPlugins(),delete this.context.defaultStyleRendererFactory,delete this.context.styleRendererFactory}}]),i}(e.AbstractRendererPlugin);t.CircleRenderer=_,t.EllipseRenderer=I,t.ImageRenderer=D,t.LineRenderer=Y,t.PathRenderer=X,t.Plugin=H,t.PolygonRenderer=W,t.PolylineRenderer=U,t.RectRenderer=G,t.TextRenderer=F,Object.defineProperty(t,"__esModule",{value:!0})})); | ||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("@antv/g-lite")):"function"==typeof define&&define.amd?define(["exports","@antv/g-lite"],e):e(((t="undefined"!=typeof globalThis?globalThis:t||self).G=t.G||{},t.G.CanvasRenderer={}),t.window.G)}(this,(function(t,e){"use strict";function r(){r=function(){return t};var t={},e=Object.prototype,n=e.hasOwnProperty,i=Object.defineProperty||function(t,e,r){t[e]=r.value},o="function"==typeof Symbol?Symbol:{},a=o.iterator||"@@iterator",s=o.asyncIterator||"@@asyncIterator",c=o.toStringTag||"@@toStringTag";function l(t,e,r){return Object.defineProperty(t,e,{value:r,enumerable:!0,configurable:!0,writable:!0}),t[e]}try{l({},"")}catch(t){l=function(t,e,r){return t[e]=r}}function h(t,e,r,n){var o=Object.create((e&&e.prototype instanceof d?e:d).prototype),a=new M(n||[]);return i(o,"_invoke",{value:A(t,r,a)}),o}function u(t,e,r){try{return{type:"normal",arg:t.call(e,r)}}catch(t){return{type:"throw",arg:t}}}t.wrap=h;var f={};function d(){}function p(){}function v(){}var y={};l(y,a,(function(){return this}));var g=Object.getPrototypeOf,m=g&&g(g(B([])));m&&m!==e&&n.call(m,a)&&(y=m);var x=v.prototype=d.prototype=Object.create(y);function w(t){["next","throw","return"].forEach((function(e){l(t,e,(function(t){return this._invoke(e,t)}))}))}function b(t,e){function r(i,o,a,s){var c=u(t[i],t,o);if("throw"!==c.type){var l=c.arg,h=l.value;return h&&"object"==typeof h&&n.call(h,"__await")?e.resolve(h.__await).then((function(t){r("next",t,a,s)}),(function(t){r("throw",t,a,s)})):e.resolve(h).then((function(t){l.value=t,a(l)}),(function(t){return r("throw",t,a,s)}))}s(c.arg)}var o;i(this,"_invoke",{value:function(t,n){function i(){return new e((function(e,i){r(t,n,e,i)}))}return o=o?o.then(i,i):i()}})}function A(t,e,r){var n="suspendedStart";return function(i,o){if("executing"===n)throw Error("Generator is already running");if("completed"===n){if("throw"===i)throw o;return L()}for(r.method=i,r.arg=o;;){var a=r.delegate;if(a){var s=E(a,r);if(s){if(s===f)continue;return s}}if("next"===r.method)r.sent=r._sent=r.arg;else if("throw"===r.method){if("suspendedStart"===n)throw n="completed",r.arg;r.dispatchException(r.arg)}else"return"===r.method&&r.abrupt("return",r.arg);n="executing";var c=u(t,e,r);if("normal"===c.type){if(n=r.done?"completed":"suspendedYield",c.arg===f)continue;return{value:c.arg,done:r.done}}"throw"===c.type&&(n="completed",r.method="throw",r.arg=c.arg)}}}function E(t,e){var r=e.method,n=t.iterator[r];if(void 0===n)return e.delegate=null,"throw"===r&&t.iterator.return&&(e.method="return",e.arg=void 0,E(t,e),"throw"===e.method)||"return"!==r&&(e.method="throw",e.arg=new TypeError("The iterator does not provide a '"+r+"' method")),f;var i=u(n,t.iterator,e.arg);if("throw"===i.type)return e.method="throw",e.arg=i.arg,e.delegate=null,f;var o=i.arg;return o?o.done?(e[t.resultName]=o.value,e.next=t.nextLoc,"return"!==e.method&&(e.method="next",e.arg=void 0),e.delegate=null,f):o:(e.method="throw",e.arg=new TypeError("iterator result is not an object"),e.delegate=null,f)}function S(t){var e={tryLoc:t[0]};1 in t&&(e.catchLoc=t[1]),2 in t&&(e.finallyLoc=t[2],e.afterLoc=t[3]),this.tryEntries.push(e)}function O(t){var e=t.completion||{};e.type="normal",delete e.arg,t.completion=e}function M(t){this.tryEntries=[{tryLoc:"root"}],t.forEach(S,this),this.reset(!0)}function B(t){if(t){var e=t[a];if(e)return e.call(t);if("function"==typeof t.next)return t;if(!isNaN(t.length)){var r=-1,i=function e(){for(;++r<t.length;)if(n.call(t,r))return e.value=t[r],e.done=!1,e;return e.value=void 0,e.done=!0,e};return i.next=i}}return{next:L}}function L(){return{value:void 0,done:!0}}return p.prototype=v,i(x,"constructor",{value:v,configurable:!0}),i(v,"constructor",{value:p,configurable:!0}),p.displayName=l(v,c,"GeneratorFunction"),t.isGeneratorFunction=function(t){var e="function"==typeof t&&t.constructor;return!!e&&(e===p||"GeneratorFunction"===(e.displayName||e.name))},t.mark=function(t){return Object.setPrototypeOf?Object.setPrototypeOf(t,v):(t.__proto__=v,l(t,c,"GeneratorFunction")),t.prototype=Object.create(x),t},t.awrap=function(t){return{__await:t}},w(b.prototype),l(b.prototype,s,(function(){return this})),t.AsyncIterator=b,t.async=function(e,r,n,i,o){void 0===o&&(o=Promise);var a=new b(h(e,r,n,i),o);return t.isGeneratorFunction(r)?a:a.next().then((function(t){return t.done?t.value:a.next()}))},w(x),l(x,c,"Generator"),l(x,a,(function(){return this})),l(x,"toString",(function(){return"[object Generator]"})),t.keys=function(t){var e=Object(t),r=[];for(var n in e)r.push(n);return r.reverse(),function t(){for(;r.length;){var n=r.pop();if(n in e)return t.value=n,t.done=!1,t}return t.done=!0,t}},t.values=B,M.prototype={constructor:M,reset:function(t){if(this.prev=0,this.next=0,this.sent=this._sent=void 0,this.done=!1,this.delegate=null,this.method="next",this.arg=void 0,this.tryEntries.forEach(O),!t)for(var e in this)"t"===e.charAt(0)&&n.call(this,e)&&!isNaN(+e.slice(1))&&(this[e]=void 0)},stop:function(){this.done=!0;var t=this.tryEntries[0].completion;if("throw"===t.type)throw t.arg;return this.rval},dispatchException:function(t){if(this.done)throw t;var e=this;function r(r,n){return a.type="throw",a.arg=t,e.next=r,n&&(e.method="next",e.arg=void 0),!!n}for(var i=this.tryEntries.length-1;i>=0;--i){var o=this.tryEntries[i],a=o.completion;if("root"===o.tryLoc)return r("end");if(this.prev>=o.tryLoc){var s=n.call(o,"catchLoc"),c=n.call(o,"finallyLoc");if(s&&c){if(o.catchLoc>this.prev)return r(o.catchLoc,!0);if(o.finallyLoc>this.prev)return r(o.finallyLoc)}else if(s){if(o.catchLoc>this.prev)return r(o.catchLoc,!0)}else{if(!c)throw Error("try statement without catch or finally");if(o.finallyLoc>this.prev)return r(o.finallyLoc)}}}},abrupt:function(t,e){for(var r=this.tryEntries.length-1;r>=0;--r){var i=this.tryEntries[r];if(this.prev>=i.tryLoc&&n.call(i,"finallyLoc")&&i.finallyLoc>this.prev){var o=i;break}}o&&("break"===t||"continue"===t)&&e>=o.tryLoc&&o.finallyLoc>=e&&(o=null);var a=o?o.completion:{};return a.type=t,a.arg=e,o?(this.method="next",this.next=o.finallyLoc,f):this.complete(a)},complete:function(t,e){if("throw"===t.type)throw t.arg;return"break"===t.type||"continue"===t.type?this.next=t.arg:"return"===t.type?(this.rval=this.arg=t.arg,this.method="return",this.next="end"):"normal"===t.type&&e&&(this.next=e),f},finish:function(t){for(var e=this.tryEntries.length-1;e>=0;--e){var r=this.tryEntries[e];if(r.finallyLoc===t)return this.complete(r.completion,r.afterLoc),O(r),f}},catch:function(t){for(var e=this.tryEntries.length-1;e>=0;--e){var r=this.tryEntries[e];if(r.tryLoc===t){var n=r.completion;if("throw"===n.type){var i=n.arg;O(r)}return i}}throw Error("illegal catch attempt")},delegateYield:function(t,e,r){return this.delegate={iterator:B(t),resultName:e,nextLoc:r},"next"===this.method&&(this.arg=void 0),f}},t}function n(t,e,r,n,i,o,a){try{var s=t[o](a),c=s.value}catch(t){return void r(t)}s.done?e(c):Promise.resolve(c).then(n,i)}function i(t){return function(){var e=this,r=arguments;return new Promise((function(i,o){var a=t.apply(e,r);function s(t){n(a,i,o,s,c,"next",t)}function c(t){n(a,i,o,s,c,"throw",t)}s(void 0)}))}}function o(){return o=Object.assign?Object.assign.bind():function(t){for(var e=1;arguments.length>e;e++){var r=arguments[e];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(t[n]=r[n])}return t},o.apply(this,arguments)}function a(t,e){t.prototype=Object.create(e.prototype),t.prototype.constructor=t,s(t,e)}function s(t,e){return s=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(t,e){return t.__proto__=e,t},s(t,e)}var c="undefined"!=typeof Float32Array?Float32Array:Array;function l(){var t=new c(16);return c!=Float32Array&&(t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[11]=0,t[12]=0,t[13]=0,t[14]=0),t[0]=1,t[5]=1,t[10]=1,t[15]=1,t}function h(t,e){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t}function u(t,e,r){var n=e[0],i=e[1],o=e[2],a=e[3],s=e[4],c=e[5],l=e[6],h=e[7],u=e[8],f=e[9],d=e[10],p=e[11],v=e[12],y=e[13],g=e[14],m=e[15],x=r[0],w=r[1],b=r[2],A=r[3];return t[0]=x*n+w*s+b*u+A*v,t[1]=x*i+w*c+b*f+A*y,t[2]=x*o+w*l+b*d+A*g,t[3]=x*a+w*h+b*p+A*m,t[4]=(x=r[4])*n+(w=r[5])*s+(b=r[6])*u+(A=r[7])*v,t[5]=x*i+w*c+b*f+A*y,t[6]=x*o+w*l+b*d+A*g,t[7]=x*a+w*h+b*p+A*m,t[8]=(x=r[8])*n+(w=r[9])*s+(b=r[10])*u+(A=r[11])*v,t[9]=x*i+w*c+b*f+A*y,t[10]=x*o+w*l+b*d+A*g,t[11]=x*a+w*h+b*p+A*m,t[12]=(x=r[12])*n+(w=r[13])*s+(b=r[14])*u+(A=r[15])*v,t[13]=x*i+w*c+b*f+A*y,t[14]=x*o+w*l+b*d+A*g,t[15]=x*a+w*h+b*p+A*m,t}function f(t,e,r){var n,i,o,a,s,c,l,h,u,f,d,p,v=r[0],y=r[1],g=r[2];return e===t?(t[12]=e[0]*v+e[4]*y+e[8]*g+e[12],t[13]=e[1]*v+e[5]*y+e[9]*g+e[13],t[14]=e[2]*v+e[6]*y+e[10]*g+e[14],t[15]=e[3]*v+e[7]*y+e[11]*g+e[15]):(i=e[1],o=e[2],a=e[3],s=e[4],c=e[5],l=e[6],h=e[7],u=e[8],f=e[9],d=e[10],p=e[11],t[0]=n=e[0],t[1]=i,t[2]=o,t[3]=a,t[4]=s,t[5]=c,t[6]=l,t[7]=h,t[8]=u,t[9]=f,t[10]=d,t[11]=p,t[12]=n*v+s*y+u*g+e[12],t[13]=i*v+c*y+f*g+e[13],t[14]=o*v+l*y+d*g+e[14],t[15]=a*v+h*y+p*g+e[15]),t}function d(){var t=new c(3);return c!=Float32Array&&(t[0]=0,t[1]=0,t[2]=0),t}function p(t,e,r){var n=new c(3);return n[0]=t,n[1]=e,n[2]=r,n}function v(t,e,r){var n=e[0],i=e[1],o=e[2],a=r[3]*n+r[7]*i+r[11]*o+r[15];return t[0]=(r[0]*n+r[4]*i+r[8]*o+r[12])/(a=a||1),t[1]=(r[1]*n+r[5]*i+r[9]*o+r[13])/a,t[2]=(r[2]*n+r[6]*i+r[10]*o+r[14])/a,t}Math.hypot||(Math.hypot=function(){for(var t=0,e=arguments.length;e--;)t+=arguments[e]*arguments[e];return Math.sqrt(t)});y=d();var y,g=function(t){return null==t},m={}.toString,x=function(t){return e="String",m.call(t)==="[object "+e+"]";var e},w=function(){function t(t){this.canvasRendererPluginOptions=void 0,this.context=void 0,this.pathGeneratorFactory=void 0,this.rBush=void 0,this.removedRBushNodeAABBs=[],this.renderQueue=[],this.restoreStack=[],this.clearFullScreen=!1,this.vpMatrix=l(),this.dprMatrix=l(),this.tmpMat4=l(),this.vec3a=d(),this.vec3b=d(),this.vec3c=d(),this.vec3d=d(),this.canvasRendererPluginOptions=t}var n=t.prototype;return n.apply=function(n){var o=this;this.context=n;var a=n.config,s=n.camera,c=n.renderingService,l=n.renderingContext,h=n.pathGeneratorFactory;this.rBush=n.rBushRoot,this.pathGeneratorFactory=h;var f=n.contextService,d=l.root.ownerDocument.defaultView,y=function(t){var e=t.target.rBushNode;e.aabb&&o.removedRBushNodeAABBs.push(e.aabb)},g=function(t){var e=t.target.rBushNode;e.aabb&&o.removedRBushNodeAABBs.push(e.aabb)};c.hooks.init.tapPromise(t.tag,i(r().mark((function t(){var n,i,s,c;return r().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:d.addEventListener(e.ElementEvent.UNMOUNTED,y),d.addEventListener(e.ElementEvent.CULLED,g),n=f.getDPR(),i=a.width,s=a.height,c=f.getContext(),o.clearRect(c,0,0,i*n,s*n,a.background);case 6:case"end":return t.stop()}}),t)})))),c.hooks.destroy.tap(t.tag,(function(){d.removeEventListener(e.ElementEvent.UNMOUNTED,y),d.removeEventListener(e.ElementEvent.CULLED,g)})),c.hooks.beginFrame.tap(t.tag,(function(){var t=f.getContext(),e=f.getDPR(),r=a.width,n=a.height,i=o.canvasRendererPluginOptions,s=i.dirtyObjectNumThreshold,l=i.dirtyObjectRatioThreshold,h=c.getStats(),u=h.rendered,d=u/h.total;o.clearFullScreen=c.disableDirtyRectangleRendering()||u>s&&d>l,t&&(t.resetTransform(),o.clearFullScreen&&o.clearRect(t,0,0,r*e,n*e,a.background))}));var m=function t(e,r){e.isVisible()&&!e.isCulled()&&(o.renderDisplayObject(e,r,o.context,o.restoreStack),o.saveDirtyAABB(e)),(e.sortable.sorted||e.childNodes).forEach((function(e){t(e,r)}))};c.hooks.endFrame.tap(t.tag,(function(){var t,r,n=f.getContext(),i=f.getDPR();if(t=o.dprMatrix,r=p(i,i,1),t[0]=r[0],t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=r[1],t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=r[2],t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,u(o.vpMatrix,o.dprMatrix,s.getOrthoMatrix()),o.clearFullScreen)m(l.root,n);else{var c=o.safeMergeAABB.apply(o,[o.mergeDirtyAABBs(o.renderQueue)].concat(o.removedRBushNodeAABBs.map((function(t){var r=t.minX,n=t.minY,i=t.maxX,o=t.maxY,a=new e.AABB;return a.setMinMax(p(r,n,0),p(i,o,0)),a}))));if(o.removedRBushNodeAABBs=[],e.AABB.isEmpty(c))return void(o.renderQueue=[]);var h=o.convertAABB2Rect(c),y=h.x,g=h.y,x=h.width,w=h.height,b=v(o.vec3a,p(y,g,0),o.vpMatrix),A=v(o.vec3b,p(y+x,g,0),o.vpMatrix),E=v(o.vec3c,p(y,g+w,0),o.vpMatrix),S=v(o.vec3d,p(y+x,g+w,0),o.vpMatrix),O=Math.min(b[0],A[0],S[0],E[0]),M=Math.min(b[1],A[1],S[1],E[1]),B=Math.max(b[0],A[0],S[0],E[0]),L=Math.max(b[1],A[1],S[1],E[1]),R=Math.floor(O),P=Math.floor(M),T=Math.ceil(B-O),N=Math.ceil(L-M);n.save(),o.clearRect(n,R,P,T,N,a.background),n.beginPath(),n.rect(R,P,T,N),n.clip(),n.setTransform(o.vpMatrix[0],o.vpMatrix[1],o.vpMatrix[4],o.vpMatrix[5],o.vpMatrix[12],o.vpMatrix[13]),a.renderer.getConfig().enableDirtyRectangleRenderingDebug&&d.dispatchEvent(new e.CustomEvent(e.CanvasEvent.DIRTY_RECTANGLE,{dirtyRect:{x:R,y:P,width:T,height:N}})),o.searchDirtyObjects(c).sort((function(t,e){return t.sortable.renderOrder-e.sortable.renderOrder})).forEach((function(t){t&&t.isVisible()&&!t.isCulled()&&o.renderDisplayObject(t,n,o.context,o.restoreStack)})),n.restore(),o.renderQueue.forEach((function(t){o.saveDirtyAABB(t)})),o.renderQueue=[]}o.restoreStack.forEach((function(){n.restore()})),o.restoreStack=[]})),c.hooks.render.tap(t.tag,(function(t){o.clearFullScreen||o.renderQueue.push(t)}))},n.clearRect=function(t,e,r,n,i,o){t.clearRect(e,r,n,i),o&&(t.fillStyle=o,t.fillRect(e,r,n,i))},n.renderDisplayObject=function(t,r,n,i){var o=t.nodeName,a=i[i.length-1];!a||t.compareDocumentPosition(a)&Node.DOCUMENT_POSITION_CONTAINS||(r.restore(),i.pop());var s=this.context.styleRendererFactory[o],c=this.pathGeneratorFactory[o],l=t.parsedStyle.clipPath;if(l){this.applyWorldTransform(r,l);var h=this.pathGeneratorFactory[l.nodeName];h&&(r.save(),i.push(t),r.beginPath(),h(r,l.parsedStyle),r.closePath(),r.clip())}s&&(this.applyWorldTransform(r,t),r.save(),this.applyAttributesToContext(r,t)),c&&(r.beginPath(),c(r,t.parsedStyle),t.nodeName!==e.Shape.LINE&&t.nodeName!==e.Shape.PATH&&t.nodeName!==e.Shape.POLYLINE&&r.closePath()),s&&(s.render(r,t.parsedStyle,t,n,this),r.restore()),t.renderable.dirty=!1},n.convertAABB2Rect=function(t){var e=t.getMin(),r=t.getMax(),n=Math.floor(e[0]),i=Math.floor(e[1]);return{x:n,y:i,width:Math.ceil(r[0])-n,height:Math.ceil(r[1])-i}},n.mergeDirtyAABBs=function(t){var r=new e.AABB;return t.forEach((function(t){var e=t.getRenderBounds();r.add(e);var n=t.renderable.dirtyRenderBounds;n&&r.add(n)})),r},n.searchDirtyObjects=function(t){var r=t.getMin(),n=r[0],i=r[1],o=t.getMax();return this.rBush.search({minX:n,minY:i,maxX:o[0],maxY:o[1]}).map((function(t){return e.runtime.displayObjectPool.getByEntity(t.id)}))},n.saveDirtyAABB=function(t){var r=t.renderable;r.dirtyRenderBounds||(r.dirtyRenderBounds=new e.AABB);var n=t.getRenderBounds();n&&r.dirtyRenderBounds.update(n.center,n.halfExtents)},n.applyAttributesToContext=function(t,e){var r=e.parsedStyle,n=r.stroke,i=r.fill,o=r.opacity,a=r.lineDash,s=r.lineDashOffset;a&&t.setLineDash(a),g(s)||(t.lineDashOffset=s),g(o)||(t.globalAlpha*=o),g(n)||Array.isArray(n)||n.isNone||(t.strokeStyle=e.attributes.stroke),g(i)||Array.isArray(i)||i.isNone||(t.fillStyle=e.attributes.fill)},n.applyWorldTransform=function(t,e,r){var n=0,i=0,o=(e.parsedStyle||{}).anchor,a=o&&o[0]||0,s=o&&o[1]||0;if(0!==a||0!==s){var c=e.getGeometryBounds();n=-a*(c&&2*c.halfExtents[0]||0),i=-s*(c&&2*c.halfExtents[1]||0)}r?(h(this.tmpMat4,e.getLocalTransform()),this.vec3a[0]=n,this.vec3a[1]=i,this.vec3a[2]=0,f(this.tmpMat4,this.tmpMat4,this.vec3a),u(this.tmpMat4,r,this.tmpMat4),u(this.tmpMat4,this.vpMatrix,this.tmpMat4)):(h(this.tmpMat4,e.getWorldTransform()),this.vec3a[0]=n,this.vec3a[1]=i,this.vec3a[2]=0,f(this.tmpMat4,this.tmpMat4,this.vec3a),u(this.tmpMat4,this.vpMatrix,this.tmpMat4)),t.setTransform(this.tmpMat4[0],this.tmpMat4[1],this.tmpMat4[4],this.tmpMat4[5],this.tmpMat4[12],this.tmpMat4[13])},n.safeMergeAABB=function(){for(var t=new e.AABB,r=arguments.length,n=Array(r),i=0;r>i;i++)n[i]=arguments[i];return n.forEach((function(e){t.add(e)})),t},t}();w.tag="CanvasRenderer";var b=function(){function t(t){this.imagePool=void 0,this.imagePool=t}var r=t.prototype;return r.render=function(t,r,n,i,o){var a=r.fill,s=r.fillRule,c=r.opacity,l=r.fillOpacity,h=r.stroke,u=r.strokeOpacity,f=r.lineWidth,d=r.lineCap,p=r.lineJoin,v=r.shadowType,y=r.shadowColor,m=r.shadowBlur,x=r.filter,w=r.miterLimit,b=!g(a)&&!a.isNone,E=!g(h)&&!h.isNone&&f>0,S=0===a.alpha,O=!(!x||!x.length),M=!g(y)&&m>0,B=n.nodeName,L="inner"===v,R=E&&M&&(B===e.Shape.PATH||B===e.Shape.LINE||B===e.Shape.POLYLINE||S||L);b&&(t.globalAlpha=c*l,R||A(n,t,M),this.fill(t,n,a,s,i,o),R||this.clearShadowAndFilter(t,O,M)),E&&(t.globalAlpha=c*u,t.lineWidth=f,g(w)||(t.miterLimit=w),g(d)||(t.lineCap=d),g(p)||(t.lineJoin=p),R&&(L&&(t.globalCompositeOperation="source-atop"),A(n,t,!0),L&&(this.stroke(t,n,h,i,o),t.globalCompositeOperation="source-over",this.clearShadowAndFilter(t,O,!0))),this.stroke(t,n,h,i,o))},r.clearShadowAndFilter=function(t,e,r){if(r&&(t.shadowColor="transparent",t.shadowBlur=0),e){var n=t.filter;!g(n)&&n.indexOf("drop-shadow")>-1&&(t.filter=n.replace(/drop-shadow\([^)]*\)/,"").trim()||"none")}},r.fill=function(t,r,n,i,o,a){var s=this;Array.isArray(n)?n.forEach((function(e){t.fillStyle=s.getColor(e,r,t),t.fill(i)})):(e.isPattern(n)&&(t.fillStyle=this.getPattern(n,r,t,o,a)),t.fill(i))},r.stroke=function(t,r,n,i,o){var a=this;Array.isArray(n)?n.forEach((function(e){t.strokeStyle=a.getColor(e,r,t),t.stroke()})):(e.isPattern(n)&&(t.strokeStyle=this.getPattern(n,r,t,i,o)),t.stroke())},r.getPattern=function(t,r,n,i,o){var a,s;if(t.image instanceof e.Rect){var c=t.image.parsedStyle,l=c.width,h=c.height;s=i.contextService.getDPR();var u=i.config.offscreenCanvas;(a=e.runtime.offscreenCanvas.getOrCreateCanvas(u)).width=l*s,a.height=h*s;var f=e.runtime.offscreenCanvas.getOrCreateContext(u),d=[];t.image.forEach((function(t){o.renderDisplayObject(t,f,i,d)})),d.forEach((function(){f.restore()}))}return this.imagePool.getOrCreatePatternSync(t,n,a,s,(function(){r.renderable.dirty=!0,i.renderingService.dirtify()}))},r.getColor=function(t,r,n){var i;if(t.type===e.GradientType.LinearGradient||t.type===e.GradientType.RadialGradient){var a=r.getGeometryBounds();i=this.imagePool.getOrCreateGradient(o({type:t.type},t.value,{width:a&&2*a.halfExtents[0]||1,height:a&&2*a.halfExtents[1]||1}),n)}return i},t}();function A(t,e,r){var n=t.parsedStyle,i=n.filter,o=n.shadowColor,a=n.shadowBlur,s=n.shadowOffsetX,c=n.shadowOffsetY;i&&i.length&&(e.filter=t.style.filter),r&&(e.shadowColor=""+o,e.shadowBlur=a||0,e.shadowOffsetX=s||0,e.shadowOffsetY=c||0)}var E=function(){function t(t){this.imagePool=void 0,this.imagePool=t}return t.prototype.render=function(t,e,r){var n,i=e.img,o=e.shadowColor,a=e.shadowBlur,s=e.width,c=e.height;if(x(i)?n=this.imagePool.getImageSync(i):(s||(s=i.width),c||(c=i.height),n=i),n){A(r,t,!g(o)&&a>0);try{t.drawImage(n,0,0,s,c)}catch(t){}}},t}(),S=function(){function t(){}var e=t.prototype;return e.render=function(t,e,r){var n=e.lineWidth,i=e.textAlign,o=e.textBaseline,a=e.lineJoin,s=e.miterLimit,c=e.letterSpacing,l=e.stroke,h=e.fill,u=e.fillOpacity,f=e.strokeOpacity,d=e.opacity,p=e.metrics,v=e.dx,y=e.dy,m=e.shadowColor,x=e.shadowBlur,w=p.lines,b=p.height,E=p.lineHeight,S=p.lineMetrics;t.font=p.font,t.lineWidth=n,t.textAlign="middle"===i?"center":i,t.textBaseline=o,t.lineJoin=a,g(s)||(t.miterLimit=s);var O=0;"middle"===o?O=-b/2-E/2:"bottom"===o||"alphabetic"===o||"ideographic"===o?O=-b:"top"!==o&&"hanging"!==o||(O=-E);var M=v||0;O+=y||0,A(r,t,!g(m)&&x>0);for(var B=0;w.length>B;B++){var L=n/2+M;O+=E,g(l)||l.isNone||!n||this.drawLetterSpacing(t,w[B],S[B],i,L,O,c,u,f,d,!0),g(h)||this.drawLetterSpacing(t,w[B],S[B],i,L,O,c,u,f,d)}},e.drawLetterSpacing=function(t,e,r,n,i,o,a,s,c,l,h){if(void 0===h&&(h=!1),0!==a){var u=t.textAlign;t.textAlign="left";var f=i;"center"===n||"middle"===n?f=i-r.width/2:"right"!==n&&"end"!==n||(f=i-r.width);for(var d=Array.from(e),p=t.measureText(e).width,v=0,y=0;d.length>y;++y){var g=d[y];h?this.strokeText(t,g,f,o,c):this.fillText(t,g,f,o,s,l),f+=p-(v=t.measureText(e.substring(y+1)).width)+a,p=v}t.textAlign=u}else h?this.strokeText(t,e,i,o,c):this.fillText(t,e,i,o,s,l)},e.fillText=function(t,e,r,n,i,o){var a,s=!g(i)&&1!==i;s&&(a=t.globalAlpha,t.globalAlpha=i*o),t.fillText(e,r,n),s&&(t.globalAlpha=a)},e.strokeText=function(t,e,r,n,i){var o,a=!g(i)&&1!==i;a&&(o=t.globalAlpha,t.globalAlpha=i),t.strokeText(e,r,n),a&&(t.globalAlpha=o)},t}(),O=function(t){function e(){return t.apply(this,arguments)||this}return a(e,t),e}(b),M=function(t){function e(){return t.apply(this,arguments)||this}return a(e,t),e}(b),B=function(t){function e(){return t.apply(this,arguments)||this}return a(e,t),e}(b),L=function(t){function e(){return t.apply(this,arguments)||this}return a(e,t),e}(b),R=function(t){function e(){return t.apply(this,arguments)||this}return a(e,t),e}(b),P=function(t){function e(){return t.apply(this,arguments)||this}return a(e,t),e}(b),T=function(t){function e(){return t.apply(this,arguments)||this}return a(e,t),e}(b),N=function(t){function r(e){var r;return void 0===e&&(e={}),(r=t.call(this)||this).options=void 0,r.name="canvas-renderer",r.options=e,r}a(r,t);var n=r.prototype;return n.init=function(){var t,r=o({dirtyObjectNumThreshold:500,dirtyObjectRatioThreshold:.8},this.options),n=this.context.imagePool,i=new b(n),a=((t={})[e.Shape.CIRCLE]=i,t[e.Shape.ELLIPSE]=i,t[e.Shape.RECT]=i,t[e.Shape.IMAGE]=new E(n),t[e.Shape.TEXT]=new S,t[e.Shape.LINE]=i,t[e.Shape.POLYLINE]=i,t[e.Shape.POLYGON]=i,t[e.Shape.PATH]=i,t[e.Shape.GROUP]=void 0,t[e.Shape.HTML]=void 0,t[e.Shape.MESH]=void 0,t);this.context.defaultStyleRendererFactory=a,this.context.styleRendererFactory=a,this.addRenderingPlugin(new w(r))},n.destroy=function(){this.removeAllRenderingPlugins(),delete this.context.defaultStyleRendererFactory,delete this.context.styleRendererFactory},r}(e.AbstractRendererPlugin);t.CircleRenderer=M,t.EllipseRenderer=B,t.ImageRenderer=E,t.LineRenderer=L,t.PathRenderer=T,t.Plugin=N,t.PolygonRenderer=P,t.PolylineRenderer=R,t.RectRenderer=O,t.TextRenderer=S,Object.defineProperty(t,"__esModule",{value:!0})})); |
{ | ||
"name": "@antv/g-plugin-canvas-renderer", | ||
"version": "1.7.35", | ||
"version": "1.7.36", | ||
"description": "A G plugin of renderer implementation with Canvas2D API", | ||
@@ -33,5 +33,5 @@ "keywords": [ | ||
"dependencies": { | ||
"@antv/g-math": "^1.7.32", | ||
"@antv/g-plugin-canvas-path-generator": "^1.1.32", | ||
"@antv/g-plugin-image-loader": "^1.1.33", | ||
"@antv/g-math": "^1.7.33", | ||
"@antv/g-plugin-canvas-path-generator": "^1.1.33", | ||
"@antv/g-plugin-image-loader": "^1.1.34", | ||
"@antv/util": "^3.3.1", | ||
@@ -50,3 +50,3 @@ "gl-matrix": "^3.1.0", | ||
}, | ||
"gitHead": "a4ea86f17b561d0483129ca2022586fcd9e42b7b" | ||
"gitHead": "c3c09705bf97040bbec01d94f55c27cc6f14d230" | ||
} |
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
195321
4166