UNPKG

@visactor/vrender-components

Version:

components library for dp visualization

207 lines (202 loc) 12.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: !0 }), exports.Brush = void 0; const vrender_core_1 = require("@visactor/vrender-core"), vutils_1 = require("@visactor/vutils"), base_1 = require("../core/base"), type_1 = require("./type"), config_1 = require("./config"), register_1 = require("./register"), delayMap = { debounce: vutils_1.debounce, throttle: vutils_1.throttle }; (0, register_1.loadBrushComponent)(); class Brush extends base_1.AbstractComponent { constructor(attributes, options) { super((null == options ? void 0 : options.skipDefault) ? attributes : (0, vutils_1.merge)({}, Brush.defaultAttributes, attributes)), this.name = "brush", this._activeDrawState = !1, this._cacheDrawPoints = [], this._isDrawedBeforeEnd = !1, this._isDownBeforeUpOutside = !1, this._activeMoveState = !1, this._operatingMaskMoveDx = 0, this._operatingMaskMoveDy = 0, this._operatingMaskMoveRangeX = [ -1 / 0, 1 / 0 ], this._operatingMaskMoveRangeY = [ -1 / 0, 1 / 0 ], this._brushMaskAABBBoundsDict = {}, this._onBrushStart = e => { var _a; if (this._outOfInteractiveRange(e)) return void (this._isDownBeforeUpOutside = !0); e.stopPropagation(); const brushMoved = null === (_a = this.attribute.brushMoved) || void 0 === _a || _a; this._activeMoveState = brushMoved && this._isPosInBrushMask(e), this._activeDrawState = !this._activeMoveState, this._activeDrawState && this._initDraw(e), this._activeMoveState && this._initMove(e); }, this._onBrushing = e => { this._outOfInteractiveRange(e) || ((this._activeDrawState || this._activeMoveState) && e.stopPropagation(), this._activeDrawState && this._drawing(e), this._activeMoveState && this._moving(e)); }, this._onBrushingWithDelay = 0 === this.attribute.delayTime ? this._onBrushing : delayMap[this.attribute.delayType](this._onBrushing, this.attribute.delayTime), this._onBrushEnd = e => { var _a; if (!this._activeDrawState && !this._activeMoveState) return; e.preventDefault(); const {removeOnClick: removeOnClick = !0} = this.attribute; this._activeDrawState && !this._isDrawedBeforeEnd && removeOnClick ? ((null === (_a = this._operatingMask) || void 0 === _a ? void 0 : _a._AABBBounds.empty()) && this._dispatchEvent(type_1.IOperateType.brushClear, { operateMask: this._operatingMask, operatedMaskAABBBounds: this._brushMaskAABBBoundsDict, event: e }), this._container.incrementalClearChild(), this._brushMaskAABBBoundsDict = {}) : (this._activeDrawState && this._dispatchEvent(type_1.IOperateType.drawEnd, { operateMask: this._operatingMask, operatedMaskAABBBounds: this._brushMaskAABBBoundsDict, event: e }), this._activeMoveState && this._dispatchEvent(type_1.IOperateType.moveEnd, { operateMask: this._operatingMask, operatedMaskAABBBounds: this._brushMaskAABBBoundsDict, event: e })), this._activeDrawState = !1, this._activeMoveState = !1, this._isDrawedBeforeEnd = !1, this._operatingMask && this._operatingMask.setAttribute("pickable", !1); }, this._onBrushClear = e => { e.preventDefault(); const {removeOnClick: removeOnClick = !0} = this.attribute; this._isDownBeforeUpOutside && removeOnClick && (this._dispatchEvent(type_1.IOperateType.brushClear, { operateMask: this._operatingMask, operatedMaskAABBBounds: this._brushMaskAABBBoundsDict, event: e }), this._container.incrementalClearChild(), this._brushMaskAABBBoundsDict = {}), this._activeDrawState = !1, this._activeMoveState = !1, this._isDrawedBeforeEnd = !1, this._isDownBeforeUpOutside = !1, this._operatingMask && this._operatingMask.setAttribute("pickable", !1); }; } _bindBrushEvents() { if (this.attribute.disableTriggerEvent) return; const {trigger: trigger = config_1.DEFAULT_BRUSH_ATTRIBUTES.trigger, updateTrigger: updateTrigger = config_1.DEFAULT_BRUSH_ATTRIBUTES.updateTrigger, endTrigger: endTrigger = config_1.DEFAULT_BRUSH_ATTRIBUTES.endTrigger, resetTrigger: resetTrigger = config_1.DEFAULT_BRUSH_ATTRIBUTES.resetTrigger} = this.attribute; (0, vutils_1.array)(trigger).forEach((t => vrender_core_1.vglobal.addEventListener(t, this._onBrushStart))), (0, vutils_1.array)(updateTrigger).forEach((t => this.stage.addEventListener(t, this._onBrushingWithDelay))), (0, vutils_1.array)(endTrigger).forEach((t => this.stage.addEventListener(t, this._onBrushEnd))), (0, vutils_1.array)(resetTrigger).forEach((t => this.stage.addEventListener(t, this._onBrushClear))); } _isPosInBrushMask(e) { const pos = this.eventPosToStagePos(e), brushMasks = this._container.getChildren(); for (let i = 0; i < brushMasks.length; i++) { const {points: points = [], dx: dx = 0, dy: dy = 0} = brushMasks[i].attribute, pointsConsiderOffset = points.map((point => ({ x: point.x + dx, y: point.y + dy }))); if ((0, vutils_1.polygonContainPoint)(pointsConsiderOffset, pos.x, pos.y)) return this._operatingMask = brushMasks[i], !0; } return !1; } _initDraw(e) { const {brushMode: brushMode} = this.attribute, pos = this.eventPosToStagePos(e); this._cacheDrawPoints = [ pos ], this._isDrawedBeforeEnd = !1, "single" === brushMode && (this._brushMaskAABBBoundsDict = {}, this._container.incrementalClearChild()), this._addBrushMask(), this._dispatchEvent(type_1.IOperateType.drawStart, { operateMask: this._operatingMask, operatedMaskAABBBounds: this._brushMaskAABBBoundsDict, event: e }); } _initMove(e) { var _a, _b; this._cacheMovePoint = this.eventPosToStagePos(e), this._operatingMaskMoveDx = null !== (_a = this._operatingMask.attribute.dx) && void 0 !== _a ? _a : 0, this._operatingMaskMoveDy = null !== (_b = this._operatingMask.attribute.dy) && void 0 !== _b ? _b : 0; const {interactiveRange: interactiveRange} = this.attribute, {minY: minY = -1 / 0, maxY: maxY = 1 / 0, minX: minX = -1 / 0, maxX: maxX = 1 / 0} = interactiveRange, {x1: x1, x2: x2, y1: y1, y2: y2} = this._operatingMask.globalAABBBounds, minMoveStepX = minX - x1, maxMoveStepX = maxX - x2, minMoveStepY = minY - y1, maxMoveStepY = maxY - y2; this._operatingMaskMoveRangeX = [ minMoveStepX, maxMoveStepX ], this._operatingMaskMoveRangeY = [ minMoveStepY, maxMoveStepY ], this._operatingMask.setAttribute("pickable", !0), this._dispatchEvent(type_1.IOperateType.moveStart, { operateMask: this._operatingMask, operatedMaskAABBBounds: this._brushMaskAABBBoundsDict, event: e }); } _drawing(e) { var _a, _b; const pos = this.eventPosToStagePos(e), {sizeThreshold: sizeThreshold = config_1.DEFAULT_SIZE_THRESHOLD, brushType: brushType} = this.attribute, cacheLength = this._cacheDrawPoints.length; if (cacheLength > 0) { const lastPos = null !== (_a = this._cacheDrawPoints[this._cacheDrawPoints.length - 1]) && void 0 !== _a ? _a : {}; if (pos.x === lastPos.x && pos.y === lastPos.y) return; } "polygon" === brushType || cacheLength <= 1 ? this._cacheDrawPoints.push(pos) : this._cacheDrawPoints[cacheLength - 1] = pos; const maskPoints = this._computeMaskPoints(); this._operatingMask.setAttribute("points", maskPoints); const {x1: x1 = 0, x2: x2 = 0, y1: y1 = 0, y2: y2 = 0} = null === (_b = this._operatingMask) || void 0 === _b ? void 0 : _b._AABBBounds; this._isDrawedBeforeEnd = !this._operatingMask._AABBBounds.empty() && !!(Math.abs(x2 - x1) > sizeThreshold || Math.abs(y1 - y2) > sizeThreshold), this._isDrawedBeforeEnd && (this._brushMaskAABBBoundsDict[this._operatingMask.name] = this._operatingMask.AABBBounds, this._dispatchEvent(type_1.IOperateType.drawing, { operateMask: this._operatingMask, operatedMaskAABBBounds: this._brushMaskAABBBoundsDict, event: e })); } _moving(e) { const startPos = this._cacheMovePoint, pos = this.eventPosToStagePos(e); if (pos.x === (null == startPos ? void 0 : startPos.x) && pos.y === (null == startPos ? void 0 : startPos.y)) return; const moveStepX = pos.x - startPos.x, moveStepY = pos.y - startPos.y, moveX = Math.min(this._operatingMaskMoveRangeX[1], Math.max(this._operatingMaskMoveRangeX[0], moveStepX)) + this._operatingMaskMoveDx, moveY = Math.min(this._operatingMaskMoveRangeY[1], Math.max(this._operatingMaskMoveRangeY[0], moveStepY)) + this._operatingMaskMoveDy; this._operatingMask.setAttributes({ dx: moveX, dy: moveY }), this._brushMaskAABBBoundsDict[this._operatingMask.name] = this._operatingMask.AABBBounds, this._dispatchEvent(type_1.IOperateType.moving, { operateMask: this._operatingMask, operatedMaskAABBBounds: this._brushMaskAABBBoundsDict, event: e }); } _computeMaskPoints() { const {brushType: brushType, xRange: xRange = [ 0, 0 ], yRange: yRange = [ 0, 0 ]} = this.attribute; let maskPoints = []; const startPoint = this._cacheDrawPoints[0], endPoint = this._cacheDrawPoints[this._cacheDrawPoints.length - 1]; return maskPoints = "rect" === brushType ? [ startPoint, { x: endPoint.x, y: startPoint.y }, endPoint, { x: startPoint.x, y: endPoint.y } ] : "x" === brushType ? [ { x: startPoint.x, y: yRange[0] }, { x: endPoint.x, y: yRange[0] }, { x: endPoint.x, y: yRange[1] }, { x: startPoint.x, y: yRange[1] } ] : "y" === brushType ? [ { x: xRange[0], y: startPoint.y }, { x: xRange[0], y: endPoint.y }, { x: xRange[1], y: endPoint.y }, { x: xRange[1], y: startPoint.y } ] : (0, vutils_1.cloneDeep)(this._cacheDrawPoints), maskPoints; } _addBrushMask() { var _a; const {brushStyle: brushStyle, hasMask: hasMask} = this.attribute, brushMask = vrender_core_1.graphicCreator.polygon(Object.assign(Object.assign({ points: (0, vutils_1.cloneDeep)(this._cacheDrawPoints), cursor: "move", pickable: !1 }, brushStyle), { opacity: hasMask ? null !== (_a = brushStyle.opacity) && void 0 !== _a ? _a : 1 : 0 })); brushMask.name = `brush-${Date.now()}`, this._operatingMask = brushMask, this._container.add(brushMask), this._brushMaskAABBBoundsDict[brushMask.name] = brushMask.AABBBounds; } _outOfInteractiveRange(e) { const {interactiveRange: interactiveRange} = this.attribute, {minY: minY = -1 / 0, maxY: maxY = 1 / 0, minX: minX = -1 / 0, maxX: maxX = 1 / 0} = interactiveRange, pos = this.eventPosToStagePos(e); return pos.x > maxX || pos.x < minX || pos.y > maxY || pos.y < minY; } eventPosToStagePos(e) { return this.stage.eventPointTransform(e); } render() { this._bindBrushEvents(); const group = this.createOrUpdateChild("brush-container", {}, "group"); this._container = group; } releaseBrushEvents() { const {delayType: delayType = "throttle", delayTime: delayTime = 0, trigger: trigger = config_1.DEFAULT_BRUSH_ATTRIBUTES.trigger, updateTrigger: updateTrigger = config_1.DEFAULT_BRUSH_ATTRIBUTES.updateTrigger, endTrigger: endTrigger = config_1.DEFAULT_BRUSH_ATTRIBUTES.endTrigger, resetTrigger: resetTrigger = config_1.DEFAULT_BRUSH_ATTRIBUTES.resetTrigger} = this.attribute; (0, vutils_1.array)(trigger).forEach((t => vrender_core_1.vglobal.removeEventListener(t, this._onBrushStart))), (0, vutils_1.array)(updateTrigger).forEach((t => this.stage.removeEventListener(t, this._onBrushingWithDelay))), (0, vutils_1.array)(endTrigger).forEach((t => this.stage.removeEventListener(t, this._onBrushEnd))), (0, vutils_1.array)(resetTrigger).forEach((t => this.stage.removeEventListener(t, this._onBrushClear))); } } exports.Brush = Brush, Brush.defaultAttributes = config_1.DEFAULT_BRUSH_ATTRIBUTES; //# sourceMappingURL=brush.js.map