UNPKG

@leafer-in/editor

Version:
106 lines (75 loc) 3.5 kB
import { IUI, ILeaferCanvas, IRenderOptions, IRectInputData, IMatrixWithOptionHalfData } from '@leafer-ui/interface' import { Paint, UI, MatrixHelper, getBoundsData, getMatrixData, BoundsHelper, LeafBoundsHelper } from '@leafer-ui/draw' import { IStroker } from '@leafer-in/interface' import { targetAttr } from '../decorator/data' const { abs } = Math const { copy, scale } = MatrixHelper const { setListWithFn } = BoundsHelper const { worldBounds } = LeafBoundsHelper const matrix = getMatrixData() as IMatrixWithOptionHalfData const bounds = getBoundsData() export class Stroker extends UI implements IStroker { @targetAttr(onTarget) public target: IUI | IUI[] public list: IUI[] = [] constructor() { super() this.visible = 0 this.hittable = false this.strokeAlign = 'center' } public setTarget(target: IUI | IUI[], style: IRectInputData): void { this.set(style) this.target = target this.update() } public update(): void { const { list } = this if (list.length) { setListWithFn(bounds, list, worldBounds) this.set(bounds) this.visible = true } else this.visible = 0 } public __draw(canvas: ILeaferCanvas, options: IRenderOptions): void { const { list } = this if (list.length) { let leaf: IUI const data = this.__, { stroke, strokeWidth, fill } = data, { bounds } = options for (let i = 0; i < list.length; i++) { leaf = list[i] const { worldTransform, worldRenderBounds } = leaf if (worldRenderBounds.width && worldRenderBounds.height && (!bounds || bounds.hit(worldRenderBounds, options.matrix))) { const aScaleX = abs(worldTransform.scaleX), aScaleY = abs(worldTransform.scaleY) copy(matrix, worldTransform) matrix.half = strokeWidth % 2 if (aScaleX !== aScaleY) { // need no scale stroke, use rect path scale(matrix, 1 / aScaleX, 1 / aScaleY) canvas.setWorld(matrix, options.matrix) canvas.beginPath() data.strokeWidth = strokeWidth const { x, y, width, height } = leaf.__layout.boxBounds canvas.rect(x * aScaleX, y * aScaleY, width * aScaleX, height * aScaleY) } else { canvas.setWorld(matrix, options.matrix) canvas.beginPath() if (leaf.__.__useArrow) leaf.__drawPath(canvas) else leaf.__.__pathForRender ? leaf.__drawRenderPath(canvas) : leaf.__drawPathByBox(canvas) data.strokeWidth = strokeWidth / abs(worldTransform.scaleX) } if (stroke) typeof stroke === 'string' ? Paint.stroke(stroke, this, canvas) : Paint.strokes(stroke, this, canvas) if (fill) typeof fill === 'string' ? Paint.fill(fill, this, canvas) : Paint.fills(fill, this, canvas) } } data.strokeWidth = strokeWidth } } public destroy(): void { this.target = null super.destroy() } } function onTarget(stroker: Stroker): void { const value = stroker.target stroker.list = value ? (value instanceof Array ? value : [value]) : [] }