@visactor/vgrammar-core
Version:
VGrammar is a visual grammar library
104 lines (100 loc) • 6.41 kB
JavaScript
import { Brush, IOperateType } from "@visactor/vrender-components";
import { BaseInteraction } from "./base";
import { polygonContainPoint, polygonIntersectPolygon, isRectIntersect } from "@visactor/vutils";
import { HOOK_EVENT } from "../graph/enums";
export class BrushBase extends BaseInteraction {
constructor(view, options) {
super(view, options), this.handleAfterDraw = () => {
var _a, _b, _c, _d;
const stage = this.view.renderer.stage();
if (this._brushComp || !stage) return;
const viewBox = this.view.getViewBox();
this._brushComp = new Brush({
interactiveRange: null !== (_a = this.options.interactiveRange) && void 0 !== _a ? _a : {
minX: viewBox.x1,
maxX: viewBox.x2,
minY: viewBox.y1,
maxY: viewBox.y2
},
xRange: null !== (_b = this.options.xRange) && void 0 !== _b ? _b : [ viewBox.x1, viewBox.x2 ],
yRange: null !== (_c = this.options.yRange) && void 0 !== _c ? _c : [ viewBox.y1, viewBox.y2 ],
brushMode: null !== (_d = this.options.brushMode) && void 0 !== _d ? _d : "single",
brushType: this.options.brushType,
brushStyle: this.options.brushStyle,
brushMoved: this.options.brushMoved,
removeOnClick: this.options.removeOnClick,
sizeThreshold: this.options.sizeThreshold,
delayType: this.options.delayType,
delayTime: this.options.delayTime
}), this._brushComp.addEventListener(IOperateType.brushClear, this.handleBrushUpdate),
this._brushComp.addEventListener(IOperateType.moveEnd, this.handleBrushUpdate),
this._brushComp.addEventListener(IOperateType.drawEnd, this.handleBrushUpdate),
this._brushComp.addEventListener(IOperateType.drawStart, this.handleBrushUpdate),
this._brushComp.addEventListener(IOperateType.moveStart, this.handleBrushUpdate),
this._brushComp.addEventListener(IOperateType.drawing, this.handleBrushUpdate),
this._brushComp.addEventListener(IOperateType.moving, this.handleBrushUpdate), stage.defaultLayer.appendChild(this._brushComp);
}, this.options = options, this._marks = view.getMarksBySelector(this.options.selector);
}
getEvents() {
return [ {
type: HOOK_EVENT.BEFORE_DO_RENDER,
handler: this.handleAfterDraw
} ];
}
isPolygonBrushContainGraphicItem(brushMask, graphicItem, offset) {
const points = brushMask.attribute.points, {a: a, b: b, c: c, d: d, e: e, f: f} = brushMask.globalTransMatrix, {x: dx = 0, y: dy = 0} = null != offset ? offset : {}, pointsCoord = points.map((p => ({
x: a * p.x + c * p.y + e + dx,
y: b * p.x + d * p.y + f + dy
}))), globalAABBBoundsOffset = brushMask.globalAABBBounds.clone().set(brushMask.globalAABBBounds.x1 + dx, brushMask.globalAABBBounds.y1 + dy, brushMask.globalAABBBounds.x2 + dx, brushMask.globalAABBBounds.y2 + dy), x = graphicItem.globalTransMatrix.e, y = graphicItem.globalTransMatrix.f;
if ("symbol" === graphicItem.type || "circle" === graphicItem.type) return globalAABBBoundsOffset.contains(x, y) && polygonContainPoint(pointsCoord, x, y);
if ("rect" === graphicItem.type) {
const {width: width = 0, height: height = 0} = null == graphicItem ? void 0 : graphicItem.attribute;
return polygonIntersectPolygon(pointsCoord, [ {
x: x,
y: y
}, {
x: x + width,
y: y
}, {
x: x + width,
y: y + height
}, {
x: x,
y: y + height
} ]);
}
return brushMask.globalAABBBounds.intersects(graphicItem.globalAABBBounds);
}
isRectBrushContainGraphicItem(brushMask, graphicItem, offset) {
const {x: dx = 0, y: dy = 0} = null != offset ? offset : {}, globalAABBBoundsOffset = brushMask.globalAABBBounds.clone().set(brushMask.globalAABBBounds.x1 + dx, brushMask.globalAABBBounds.y1 + dy, brushMask.globalAABBBounds.x2 + dx, brushMask.globalAABBBounds.y2 + dy), x = graphicItem.globalTransMatrix.e, y = graphicItem.globalTransMatrix.f;
if ("symbol" === graphicItem.type || "circle" === graphicItem.type) return globalAABBBoundsOffset.contains(x, y);
if ("rect" === graphicItem.type) {
const {width: width = 0, height: height = 0} = graphicItem.attribute;
return isRectIntersect(globalAABBBoundsOffset, {
x1: x,
y1: y,
x2: x + width,
y2: y + height
}, !1);
}
return brushMask.globalAABBBounds.intersects(graphicItem.globalAABBBounds);
}
isBrushContainGraphicItem(brushMask, graphicItem, offset) {
var _a;
return !(!((null == brushMask ? void 0 : brushMask.globalTransMatrix) && brushMask.globalAABBBounds && !brushMask.globalAABBBounds.empty() && graphicItem && (null === (_a = null == brushMask ? void 0 : brushMask.attribute) || void 0 === _a ? void 0 : _a.points)) || brushMask.attribute.points.length <= 1) && ("polygon" === this.options.brushType ? this.isPolygonBrushContainGraphicItem(brushMask, graphicItem, offset) : this.isRectBrushContainGraphicItem(brushMask, graphicItem, offset));
}
unbind() {
super.unbind();
const stage = this.view.renderer.stage();
this._brushComp && stage && (stage.defaultLayer.removeChild(this._brushComp), this._brushComp.releaseBrushEvents(),
this._brushComp.release(), this._brushComp = null);
}
_dispatchEvent(event, activeElements) {
const params = {
operateType: event.type,
operateMask: event.detail.operateMask,
activeElements: activeElements
};
event.type === IOperateType.drawStart || event.type === IOperateType.moveStart ? this.dispatchEvent("start", params) : event.type === IOperateType.drawing || event.type === IOperateType.moving ? this.dispatchEvent("update", params) : event.type === IOperateType.drawEnd || event.type === IOperateType.moveEnd ? this.dispatchEvent("end", params) : this.dispatchEvent("reset", params);
}
}