@leafer/display-module
Advanced tools
| import { ILeafEventerModule, ILeafDataProxyModule, ILeafMatrixModule, ILeafBoundsModule, ILeafHitModule, ILeafRenderModule, ILeafMaskModule, IBranchRenderModule } from '@leafer/interface'; | ||
| declare const LeafEventer: ILeafEventerModule; | ||
| declare const LeafDataProxy: ILeafDataProxyModule; | ||
| declare const LeafMatrix: ILeafMatrixModule; | ||
| declare const LeafBounds: ILeafBoundsModule; | ||
| declare const LeafHit: ILeafHitModule; | ||
| declare const LeafRender: ILeafRenderModule; | ||
| declare const LeafMask: ILeafMaskModule; | ||
| declare const BranchRender: IBranchRenderModule; | ||
| export { BranchRender, LeafBounds, LeafDataProxy, LeafEventer, LeafHit, LeafMask, LeafMatrix, LeafRender }; |
+7
-5
| { | ||
| "name": "@leafer/display-module", | ||
| "version": "1.0.0-beta.12", | ||
| "version": "1.0.0-beta.15", | ||
| "description": "@leafer/display-module", | ||
@@ -8,4 +8,6 @@ "author": "Chao (Leafer) Wan", | ||
| "main": "src/index.ts", | ||
| "types": "types/index.d.ts", | ||
| "files": [ | ||
| "src" | ||
| "types", | ||
| "dist" | ||
| ], | ||
@@ -23,8 +25,8 @@ "repository": { | ||
| "dependencies": { | ||
| "@leafer/event": "1.0.0-beta.12", | ||
| "@leafer/math": "1.0.0-beta.12" | ||
| "@leafer/event": "1.0.0-beta.15", | ||
| "@leafer/math": "1.0.0-beta.15" | ||
| }, | ||
| "devDependencies": { | ||
| "@leafer/interface": "1.0.0-beta.12" | ||
| "@leafer/interface": "1.0.0-beta.15" | ||
| } | ||
| } |
| import { ILeaf, ILeaferCanvas, IRenderOptions, IBranchRenderModule } from '@leafer/interface' | ||
| export const BranchRender: IBranchRenderModule = { | ||
| __updateChange(): void { | ||
| const { __layout: layout } = this | ||
| if (layout.childrenSortChanged) { | ||
| this.__updateSortChildren() | ||
| layout.childrenSortChanged = false | ||
| } | ||
| this.__.__checkSingle() | ||
| }, | ||
| __render(canvas: ILeaferCanvas, options: IRenderOptions): void { | ||
| if (this.__worldOpacity) { | ||
| if (this.__.__single) { | ||
| canvas.resetTransform() | ||
| const tempCanvas = canvas.getSameCanvas() | ||
| this.__renderBranch(tempCanvas, options) | ||
| canvas.opacity = this.__worldOpacity | ||
| const blendMode = this.__.isEraser ? 'destination-out' : this.__.blendMode | ||
| options.matrix ? canvas.copyWorld(tempCanvas, null, null, blendMode) : canvas.copyWorld(tempCanvas, this.__world, this.__world, blendMode) | ||
| tempCanvas.recycle() | ||
| } else { | ||
| this.__renderBranch(canvas, options) | ||
| } | ||
| } | ||
| }, | ||
| __renderBranch(canvas: ILeaferCanvas, options: IRenderOptions): void { | ||
| let child: ILeaf | ||
| const { children } = this | ||
| if (this.__hasMask && children.length > 1) { | ||
| let mask: boolean | ||
| let maskCanvas = canvas.getSameCanvas() | ||
| let contentCanvas = canvas.getSameCanvas() | ||
| for (let i = 0, len = children.length; i < len; i++) { | ||
| child = children[i] | ||
| if (child.isMask) { | ||
| if (mask) { | ||
| this.__renderMask(canvas, contentCanvas, maskCanvas) | ||
| maskCanvas.clear() | ||
| contentCanvas.clear() | ||
| } else { | ||
| mask = true | ||
| } | ||
| child.__render(maskCanvas, options) | ||
| continue | ||
| } | ||
| child.__render(contentCanvas, options) | ||
| } | ||
| this.__renderMask(canvas, contentCanvas, maskCanvas) | ||
| maskCanvas.recycle() | ||
| contentCanvas.recycle() | ||
| } else { | ||
| const { bounds, hideBounds } = options | ||
| for (let i = 0, len = children.length; i < len; i++) { | ||
| child = children[i] | ||
| if (bounds && !bounds.hit(child.__world, options.matrix)) continue | ||
| if (hideBounds && hideBounds.includes(child.__world, options.matrix)) continue | ||
| child.__render(canvas, options) | ||
| } | ||
| } | ||
| } | ||
| } |
| import { ILeafBoundsModule } from '@leafer/interface' | ||
| import { BoundsHelper } from '@leafer/math' | ||
| const { toOuterOf, copyAndSpread } = BoundsHelper | ||
| export const LeafBounds: ILeafBoundsModule = { | ||
| __updateWorldBounds(): void { | ||
| if (this.__layout.boundsChanged) { | ||
| let resize: boolean | ||
| const layout = this.__layout | ||
| if (layout.boxChanged) { | ||
| this.__updatePath() | ||
| this.__updateRenderPath() | ||
| this.__updateBoxBounds() | ||
| layout.boxChanged = false | ||
| resize = true | ||
| } | ||
| if (layout.localBoxChanged) { // position change | ||
| this.__updateLocalBoxBounds() | ||
| layout.localBoxChanged = false | ||
| if (layout.strokeSpread) layout.strokeChanged = true | ||
| if (layout.renderSpread) layout.renderChanged = true | ||
| this.parent?.__layout.boxChange() | ||
| } | ||
| if (layout.strokeChanged) { | ||
| layout.strokeSpread = this.__updateStrokeSpread() | ||
| if (layout.strokeSpread) { | ||
| if (layout.strokeBounds === layout.boxBounds) { | ||
| layout.spreadStroke() | ||
| } | ||
| this.__updateStrokeBounds() | ||
| this.__updateLocalStrokeBounds() | ||
| } else { | ||
| layout.spreadStrokeCancel() | ||
| } | ||
| layout.strokeChanged = false | ||
| if (layout.renderSpread) layout.renderChanged = true | ||
| if (this.parent) this.parent.__layout.strokeChange() | ||
| resize || (resize = true) | ||
| } | ||
| if (layout.renderChanged) { | ||
| layout.renderSpread = this.__updateRenderSpread() | ||
| if (layout.renderSpread) { | ||
| if (layout.renderBounds === layout.boxBounds || layout.renderBounds === layout.strokeBounds) { | ||
| layout.spreadRender() | ||
| } | ||
| this.__updateRenderBounds() | ||
| this.__updateLocalRenderBounds() | ||
| } else { | ||
| layout.spreadRenderCancel() | ||
| } | ||
| layout.renderChanged = false | ||
| if (this.parent) this.parent.__layout.renderChange() | ||
| } | ||
| layout.boundsChanged = false | ||
| toOuterOf(this.__layout.renderBounds, this.__world, this.__world) | ||
| if (resize) this.__onUpdateSize() | ||
| } else { | ||
| toOuterOf(this.__layout.renderBounds, this.__world, this.__world) | ||
| } | ||
| }, | ||
| __updateLocalBoxBounds(): void { | ||
| toOuterOf(this.__layout.boxBounds, this.__local, this.__local) | ||
| }, | ||
| __updateLocalStrokeBounds(): void { | ||
| toOuterOf(this.__layout.strokeBounds, this.__local, this.__layout.localStrokeBounds) | ||
| }, | ||
| __updateLocalRenderBounds(): void { | ||
| toOuterOf(this.__layout.renderBounds, this.__local, this.__layout.localRenderBounds) | ||
| }, | ||
| __updateBoxBounds(): void { | ||
| const b = this.__layout.boxBounds | ||
| b.x = 0 | ||
| b.y = 0 | ||
| b.width = this.__.width | ||
| b.height = this.__.height | ||
| }, | ||
| __updateStrokeBounds(): void { | ||
| copyAndSpread(this.__layout.strokeBounds, this.__layout.boxBounds, this.__layout.strokeSpread) | ||
| }, | ||
| __updateRenderBounds(): void { | ||
| copyAndSpread(this.__layout.renderBounds, this.__layout.strokeBounds, this.__layout.renderSpread) | ||
| }, | ||
| } |
| import { ILeafDataProxyModule } from '@leafer/interface' | ||
| import { PropertyEvent } from '@leafer/event' | ||
| export const LeafDataProxy: ILeafDataProxyModule = { | ||
| __setAttr(name: string, newValue: unknown): void { | ||
| if (this.leafer && this.leafer.ready) { | ||
| this.__[name] = newValue | ||
| const { CHANGE } = PropertyEvent | ||
| const event = new PropertyEvent(CHANGE, this, name, this.__.__get(name), newValue) | ||
| if (this.hasEvent(CHANGE) && !this.isLeafer) this.emitEvent(event) | ||
| this.leafer.emitEvent(event) | ||
| } else { | ||
| this.__[name] = newValue | ||
| } | ||
| }, | ||
| __getAttr(name: string): unknown { | ||
| return this.__.__get(name) | ||
| } | ||
| } |
| import { IEventListener, IEventListenerOptions, IEventListenerMap, IEventListenerItem, IEventListenerId, IEvent, IObject, IEventTarget, ILeafEventerModule } from '@leafer/interface' | ||
| const empty = {} | ||
| export const LeafEventer: ILeafEventerModule = { | ||
| on(type: string | string[], listener: IEventListener, options?: IEventListenerOptions | boolean): void { | ||
| let capture: boolean, once: boolean | ||
| if (options) { | ||
| if (typeof options === 'boolean') { | ||
| capture = options | ||
| } else { | ||
| capture = options.capture | ||
| once = options.once | ||
| } | ||
| } | ||
| let events: IEventListenerItem[] | ||
| const map = __getListenerMap(this, capture, true) | ||
| const typeList = typeof type === 'string' ? type.split(' ') : type | ||
| const item = once ? { listener, once } : { listener } | ||
| typeList.forEach(type => { | ||
| if (type) { | ||
| events = map[type] | ||
| if (events) { | ||
| if (events.findIndex(item => item.listener === listener) === -1) events.push(item) | ||
| } else { | ||
| map[type] = [item] | ||
| } | ||
| } | ||
| }) | ||
| }, | ||
| off(type: string | string[], listener: IEventListener, options?: IEventListenerOptions | boolean): void { | ||
| let capture: boolean | ||
| if (options) capture = typeof options === 'boolean' ? options : options.capture | ||
| let events: IEventListenerItem[], index: number | ||
| const map = __getListenerMap(this, capture) | ||
| const typeList = typeof type === 'string' ? type.split(' ') : type | ||
| typeList.forEach(type => { | ||
| if (type) { | ||
| events = map[type] | ||
| if (events) { | ||
| index = events.findIndex(item => item.listener === listener) | ||
| if (index > -1) events.splice(index, 1) | ||
| if (!events.length) delete map[type] | ||
| } | ||
| } | ||
| }) | ||
| }, | ||
| on_(type: string | string[], listener: IEventListener, bind?: IObject, options?: IEventListenerOptions | boolean): IEventListenerId { | ||
| if (bind) listener = listener.bind(bind) | ||
| this.on(type, listener, options) | ||
| return { type, listener, options } | ||
| }, | ||
| off_(id: IEventListenerId | IEventListenerId[]): void { | ||
| if (!id) return | ||
| const list = id instanceof Array ? id : [id] | ||
| list.forEach(item => { | ||
| this.off(item.type, item.listener, item.options) | ||
| }) | ||
| list.length = 0 | ||
| }, | ||
| once(type: string | string[], listener: IEventListener, capture?: boolean): void { | ||
| this.on(type, listener, { once: true, capture }) | ||
| }, | ||
| emit(type: string, event?: IEvent | IObject, capture?: boolean): void { | ||
| const map = __getListenerMap(this, capture) | ||
| const list = map[type] | ||
| if (list) { | ||
| let item: IEventListenerItem | ||
| for (let i = 0, len = list.length; i < len; i++) { | ||
| item = list[i] | ||
| item.listener(event) | ||
| if (item.once) { | ||
| this.off(type, item.listener, capture) | ||
| i--, len-- | ||
| } | ||
| if (event && (event as IEvent).isStopNow) break | ||
| } | ||
| } | ||
| }, | ||
| emitEvent(event: IEvent, capture?: boolean): void { | ||
| event.current = this | ||
| this.emit(event.type, event, capture) | ||
| }, | ||
| hasEvent(type: string, capture?: boolean): boolean { | ||
| const { __bubbleMap: b, __captureMap: c } = this | ||
| if (capture === undefined) { | ||
| return !!((c && c[type]) || (b && b[type])) | ||
| } else { | ||
| return !!(capture ? (c && c[type]) : (b && b[type])) | ||
| } | ||
| }, | ||
| } | ||
| function __getListenerMap(eventer: IEventTarget, capture?: boolean, create?: boolean): IEventListenerMap { | ||
| if (capture) { | ||
| const { __captureMap: c } = eventer | ||
| if (c) { | ||
| return c | ||
| } else { | ||
| return create ? eventer.__captureMap = {} : empty | ||
| } | ||
| } else { | ||
| const { __bubbleMap: b } = eventer | ||
| if (b) { | ||
| return b | ||
| } else { | ||
| return create ? eventer.__bubbleMap = {} : empty | ||
| } | ||
| } | ||
| } |
| import { ILeafHitModule, IRadiusPointData, ILeaferCanvas } from '@leafer/interface' | ||
| import { PointHelper } from '@leafer/math' | ||
| const { toInnerRadiusPointOf } = PointHelper | ||
| const inner = {} as IRadiusPointData | ||
| export const LeafHit: ILeafHitModule = { | ||
| __hitWorld(point: IRadiusPointData): boolean { | ||
| if (this.__layout.hitCanvasChanged || !this.__hitCanvas) { | ||
| this.__updateHitCanvas() | ||
| this.__layout.hitCanvasChanged = false | ||
| } | ||
| toInnerRadiusPointOf(point, this.__world, inner) | ||
| return this.__hit(inner) | ||
| }, | ||
| __drawHitPath(canvas: ILeaferCanvas): void { | ||
| this.__drawRenderPath(canvas) | ||
| } | ||
| } |
| import { ILeaf, ILeaferCanvas, ILeafMaskModule } from '@leafer/interface' | ||
| export const LeafMask: ILeafMaskModule = { | ||
| __updateEraser(value?: boolean): void { | ||
| this.__hasEraser = value ? true : this.children.some(item => item.__.isEraser) | ||
| }, | ||
| __updateMask(value?: boolean): void { | ||
| this.__hasMask = value ? true : this.children.some(item => item.__.isMask) | ||
| }, | ||
| __renderMask(canvas: ILeaferCanvas, content: ILeaferCanvas, mask: ILeaferCanvas): void { | ||
| content.resetTransform() | ||
| content.useMask(mask) | ||
| canvas.resetTransform() | ||
| canvas.opacity = this.__worldOpacity | ||
| canvas.copyWorld(content) | ||
| }, | ||
| __removeMask(child?: ILeaf): void { | ||
| if (child) { | ||
| child.isMask = false | ||
| this.remove(child) | ||
| } else { | ||
| const { children } = this | ||
| for (let i = 0, len = children.length; i < len; i++) { | ||
| child = children[i] | ||
| if (child.isMask) { | ||
| this.__removeMask(child) | ||
| len--, i-- | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } |
| import { ILeafMatrixModule } from '@leafer/interface' | ||
| import { OneRadian, MatrixHelper } from '@leafer/math' | ||
| const { sin, cos } = Math | ||
| const defaultWorld = { ...MatrixHelper.defaultMatrix, scaleX: 1, scaleY: 1 } | ||
| export const LeafMatrix: ILeafMatrixModule = { | ||
| __updateWorldMatrix(): void { | ||
| const pw = this.parent ? this.parent.__world : defaultWorld | ||
| const r = this.__local | ||
| const w = this.__world | ||
| if (this.__layout.matrixChanged) this.__updateLocalMatrix() | ||
| if (this.__layout.affectScaleOrRotation) { | ||
| w.a = r.a * pw.a + r.b * pw.c | ||
| w.b = r.a * pw.b + r.b * pw.d | ||
| w.c = r.c * pw.a + r.d * pw.c | ||
| w.d = r.c * pw.b + r.d * pw.d | ||
| w.e = r.e * pw.a + r.f * pw.c + pw.e | ||
| w.f = r.e * pw.b + r.f * pw.d + pw.f | ||
| w.scaleX = pw.scaleX * this.__.scaleX | ||
| w.scaleY = pw.scaleY * this.__.scaleY | ||
| } else { | ||
| w.a = pw.a | ||
| w.b = pw.b | ||
| w.c = pw.c | ||
| w.d = pw.d | ||
| w.e = r.e * pw.a + r.f * pw.c + pw.e | ||
| w.f = r.e * pw.b + r.f * pw.d + pw.f | ||
| w.scaleX = pw.scaleX | ||
| w.scaleY = pw.scaleY | ||
| } | ||
| }, | ||
| __updateLocalMatrix(): void { | ||
| const r = this.__local | ||
| const layout = this.__layout | ||
| if (layout.affectScaleOrRotation) { | ||
| const { scaleX, scaleY } = this.__ | ||
| if (layout.affectRotation) { | ||
| if (layout.scaleChanged || layout.rotationChanged) { | ||
| let { rotation, skewX, skewY } = this.__ | ||
| if (rotation || skewX || skewY) { | ||
| rotation *= OneRadian | ||
| if (skewX) skewX *= OneRadian | ||
| if (skewY) skewY *= OneRadian | ||
| r.a = scaleX * cos(rotation + skewY) | ||
| r.b = scaleX * sin(rotation + skewY) | ||
| r.c = scaleY * -sin(rotation - skewX) | ||
| r.d = scaleY * cos(rotation - skewX) | ||
| } else { | ||
| r.a = scaleX | ||
| r.b = 0 | ||
| r.c = 0 | ||
| r.d = scaleY | ||
| layout.affectRotation = false | ||
| } | ||
| layout.scaleChanged = false | ||
| layout.rotationChanged = false | ||
| } | ||
| } else { | ||
| if (layout.scaleChanged) { | ||
| r.a = scaleX | ||
| r.d = scaleY | ||
| layout.scaleChanged = false | ||
| } | ||
| } | ||
| } | ||
| if (layout.positionChanged) { | ||
| r.e = this.__.x | ||
| r.f = this.__.y | ||
| layout.positionChanged = false | ||
| } | ||
| this.__layout.matrixChanged = false | ||
| } | ||
| } | ||
| import { ILeaferCanvas, IRenderOptions, ILeafRenderModule } from '@leafer/interface' | ||
| export const LeafRender: ILeafRenderModule = { | ||
| __render(canvas: ILeaferCanvas, options: IRenderOptions): void { | ||
| if (this.__worldOpacity) { | ||
| canvas.setWorld(this.__world, options.matrix) | ||
| canvas.opacity = this.__worldOpacity | ||
| if (this.__.__single) { | ||
| const tempCanvas = canvas.getSameCanvas(true) | ||
| this.__draw(tempCanvas, options) | ||
| const blendMode = this.__.isEraser ? 'destination-out' : this.__.blendMode | ||
| if (options.matrix) { | ||
| canvas.resetTransform() | ||
| canvas.copyWorld(tempCanvas, null, null, blendMode) | ||
| } else { | ||
| canvas.copyWorldToInner(tempCanvas, this.__world, this.__layout.renderBounds, blendMode) | ||
| } | ||
| tempCanvas.recycle() | ||
| } else { | ||
| this.__draw(canvas, options) | ||
| } | ||
| } | ||
| }, | ||
| __updateWorldOpacity(): void { | ||
| this.__worldOpacity = this.__.visible ? (this.parent ? this.parent.__worldOpacity * this.__.opacity : this.__.opacity) : 0 | ||
| if (this.__layout.opacityChanged) this.__layout.opacityChanged = false | ||
| } | ||
| } |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
2840
-85.13%5
-58.33%17
-95.91%1
Infinity%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
Updated
Updated