Latest Threat Research:SANDWORM_MODE: Shai-Hulud-Style npm Worm Hijacks CI Workflows and Poisons AI Toolchains.Details
Socket
Book a DemoInstallSign in
Socket

@leafer/math

Package Overview
Dependencies
Maintainers
1
Versions
116
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@leafer/math - npm Package Compare versions

Comparing version
1.0.0-beta.12
to
1.0.0-beta.15
+230
types/index.d.ts
import { INumberMap, IPoint, IPointData, IMatrixData, IBounds, IBoundsData, IMatrix, IObject, IBoundsDataHandle, IRadiusPointData, IMatrixWithLayoutData, IAutoBounds, IAutoBoundsData, ISizeData, ITwoPointBounds, ITwoPointBoundsData, IMatrixDecompositionData, IOffsetBoundsData } from '@leafer/interface';
declare const IncrementId: {
RUNTIME: string;
LEAF: string;
TASK: string;
CNAVAS: string;
IMAGE: string;
types: INumberMap;
create(typeName: string): number;
};
declare class Point implements IPoint {
x: number;
y: number;
constructor(x?: number | IPointData, y?: number);
set(x?: number, y?: number): void;
copy(point: IPointData): IPoint;
clone(): IPoint;
rotate(angle: number, center?: IPointData): IPoint;
toInnerOf(matrix: IMatrixData, to?: IPointData): IPoint;
toOuterOf(matrix: IMatrixData, to?: IPointData): IPoint;
getCenter(to: IPointData): IPointData;
getDistance(to: IPointData): number;
getAngle(to: IPointData): number;
getAtan2(to: IPointData): number;
reset(): void;
}
declare class Bounds implements IBounds {
x: number;
y: number;
width: number;
height: number;
constructor(x?: number | IBoundsData, y?: number, width?: number, height?: number);
set(x?: number, y?: number, width?: number, height?: number): void;
copy(bounds: IBoundsData): IBounds;
clone(): IBounds;
scale(scaleX: number, scaleY?: number): IBounds;
toOuterOf(matrix: IMatrixData, to?: IBoundsData): IBounds;
getFitMatrix(put: IBoundsData): IMatrix;
spread(size: number): IBounds;
ceil(): IBounds;
unsign(): IBounds;
add(bounds: IBoundsData): IBounds;
addList(boundsList: IBounds[]): IBounds;
setByList(boundsList: IBounds[], addMode?: boolean): IBounds;
addListWithHandle(list: IObject[], boundsDataHandle: IBoundsDataHandle): IBounds;
setByListWithHandle(list: IObject[], boundsDataHandle: IBoundsDataHandle, addMode?: boolean): IBounds;
setByPoints(points: IPointData[]): IBounds;
hitPoint(point: IPointData, pointMatrix?: IMatrixData): boolean;
hitRadiusPoint(point: IRadiusPointData, pointMatrix?: IMatrixWithLayoutData): boolean;
hit(bounds: IBoundsData, boundsMatrix?: IMatrixData): boolean;
includes(bounds: IBoundsData, boundsMatrix?: IMatrixData): boolean;
intersect(bounds: IBoundsData, boundsMatrix?: IMatrixData): IBounds;
getIntersect(bounds: IBoundsData, boundsMatrix?: IMatrixData): IBounds;
isSame(bounds: IBoundsData): boolean;
isEmpty(): boolean;
reset(): void;
}
declare class AutoBounds implements IAutoBounds {
top: number;
right: number;
bottom: number;
left: number;
width: number;
height: number;
constructor(top?: number | IAutoBoundsData, right?: number, bottom?: number, left?: number, width?: number, height?: number);
set(top?: number, right?: number, bottom?: number, left?: number, width?: number, height?: number): void;
copy(autoSize: IAutoBoundsData): void;
getBoundsFrom(parent: ISizeData): IBounds;
}
declare class TwoPointBounds implements ITwoPointBounds {
minX: number;
minY: number;
maxX: number;
maxY: number;
constructor(x: number, y: number);
addPoint(x: number, y: number): void;
addBounds(x: number, y: number, width: number, height: number): void;
add(pb: ITwoPointBoundsData): void;
}
declare class Matrix implements IMatrix {
a: number;
b: number;
c: number;
d: number;
e: number;
f: number;
constructor(a?: number | IMatrixData, b?: number, c?: number, d?: number, e?: number, f?: number);
set(a?: number, b?: number, c?: number, d?: number, e?: number, f?: number): void;
copy(matrix: IMatrixData): IMatrix;
clone(): IMatrix;
translate(x: number, y: number): IMatrix;
translateInner(x: number, y: number): IMatrix;
scale(x: number, y?: number): IMatrix;
scaleOfOuter(origin: IPointData, x: number, y?: number): IMatrix;
scaleOfInner(origin: IPointData, x: number, y?: number): IMatrix;
rotate(angle: number): IMatrix;
rotateOfOuter(origin: IPointData, angle: number): IMatrix;
rotateOfInner(origin: IPointData, angle: number): IMatrix;
skew(x: number, y?: number): IMatrix;
skewOfOuter(origin: IPointData, x: number, y?: number): IMatrix;
skewOfInner(origin: IPointData, x: number, y?: number): IMatrix;
multiply(matrix: IMatrixData): IMatrix;
preMultiply(matrix: IMatrixData): IMatrix;
divide(matrix: IMatrixData): IMatrix;
invert(): IMatrix;
toOuterPoint(inner: IPointData, to?: IPointData, distance?: boolean): void;
toInnerPoint(outer: IPointData, to?: IPointData, distance?: boolean): void;
decompose(): IMatrixDecompositionData;
reset(): void;
}
declare const PointHelper: {
defaultPoint: IPointData;
tempPoint: IPointData;
tempRadiusPoint: IRadiusPointData;
set(t: IPointData, x?: number, y?: number): void;
setRadius(t: IRadiusPointData, x: number, y?: number): void;
copy(t: IPointData, point: IPointData): void;
move(t: IPointData, x: number, y: number): void;
rotate(t: IPointData, rotation: number, center?: IPointData): void;
tempToInnerOf(t: IPointData, matrix: IMatrixData): IPointData;
tempToOuterOf(t: IPointData, matrix: IMatrixData): IPointData;
tempToInnerRadiusPointOf(t: IRadiusPointData, matrix: IMatrixWithLayoutData): IRadiusPointData;
toInnerRadiusPointOf(t: IRadiusPointData, matrix: IMatrixWithLayoutData, to?: IRadiusPointData): void;
toInnerOf(t: IPointData, matrix: IMatrixData, to?: IPointData): void;
toOuterOf(t: IPointData, matrix: IMatrixData, to?: IPointData): void;
getCenter(t: IPointData, to: IPointData): IPointData;
getDistance(t: IPointData, point: IPointData): number;
getAngle(t: IPointData, to: IPointData): number;
getChangeAngle(t: IPointData, orign: IPointData, to: IPointData, toOrigin?: IPointData): number;
getAtan2(t: IPointData, to: IPointData): number;
getDistancePoint(t: IPointData, to: IPointData, distance: number): IPointData;
reset(t: IPointData): void;
};
declare const BoundsHelper: {
tempBounds: IBoundsData;
set(t: IBoundsData, x?: number, y?: number, width?: number, height?: number): void;
copy(t: IBoundsData, bounds: IBoundsData): void;
copyAndSpread(t: IBoundsData, bounds: IBoundsData, spreadX: number, spreadY?: number): void;
right(t: IBoundsData): number;
bottom(t: IBoundsData): number;
move(t: IBoundsData, x: number, y: number): void;
getByMove(t: IBoundsData, x: number, y: number): IBoundsData;
toOffsetOutBounds(t: IBoundsData, to?: IOffsetBoundsData, parent?: IBoundsData): void;
scale(t: IBoundsData, scaleX: number, scaleY?: number): void;
tempToOuterOf(t: IBoundsData, matrix: IMatrixData): IBoundsData;
getOuterOf(t: IBoundsData, matrix: IMatrixData): IBoundsData;
toOuterOf(t: IBoundsData, matrix: IMatrixData, to?: IBoundsData): void;
getFitMatrix(t: IBoundsData, put: IBoundsData): IMatrix;
getSpread(t: IBoundsData, spreadX: number, spreadY?: number): IBoundsData;
spread(t: IBoundsData, spreadX: number, spreadY?: number): void;
ceil(t: IBoundsData): void;
unsign(t: IBoundsData): void;
add(t: IBoundsData, bounds: IBoundsData): void;
addList(t: IBoundsData, list: IBoundsData[]): void;
setByList(t: IBoundsData, list: IBoundsData[], addMode?: boolean): void;
addListWithHandle(t: IBoundsData, list: IObject[], boundsDataHandle: IBoundsDataHandle): void;
setByListWithHandle(t: IBoundsData, list: IObject[], boundsDataHandle: IBoundsDataHandle, addMode?: boolean): void;
setByPoints(t: IBoundsData, points: IPointData[]): void;
hitRadiusPoint(t: IBoundsData, point: IRadiusPointData, pointMatrix?: IMatrixWithLayoutData): boolean;
hitPoint(t: IBoundsData, point: IPointData, pointMatrix?: IMatrixData): boolean;
hit(t: IBoundsData, other: IBoundsData, otherMatrix?: IMatrixData): boolean;
includes(t: IBoundsData, other: IBoundsData, otherMatrix?: IMatrixData): boolean;
getIntersectData(t: IBoundsData, other: IBoundsData, otherMatrix?: IMatrixData): IBoundsData;
intersect(t: IBoundsData, other: IBoundsData, otherMatrix?: IMatrixData): void;
isSame(t: IBoundsData, bounds: IBoundsData): boolean;
isEmpty(t: IBoundsData): boolean;
reset(t: IBoundsData): void;
};
declare const TwoPointBoundsHelper: {
tempPointBounds: ITwoPointBoundsData;
setPoint(t: ITwoPointBoundsData, minX: number, minY: number): void;
addPoint(t: ITwoPointBoundsData, x: number, y: number): void;
addBounds(t: ITwoPointBoundsData, x: number, y: number, width: number, height: number): void;
copy(t: ITwoPointBoundsData, pb: ITwoPointBoundsData): void;
add(t: ITwoPointBoundsData, pb: ITwoPointBoundsData): void;
toBounds(t: ITwoPointBoundsData, setBounds: IBoundsData): void;
};
declare function get(): IMatrixData;
declare const MatrixHelper: {
defaultMatrix: IMatrixData;
tempMatrix: IMatrixData;
set(t: IMatrixData, a?: number, b?: number, c?: number, d?: number, e?: number, f?: number): void;
get: typeof get;
copy(t: IMatrixData, matrix: IMatrixData): void;
translate(t: IMatrixData, x: number, y: number): void;
translateInner(t: IMatrixData, x: number, y: number): void;
scale(t: IMatrixData, x: number, y?: number): void;
scaleOfOuter(t: IMatrixData, origin: IPointData, x: number, y?: number): void;
scaleOfInner(t: IMatrixData, origin: IPointData, x: number, y?: number): void;
rotate(t: IMatrixData, angle: number): void;
rotateOfOuter(t: IMatrixData, origin: IPointData, angle: number): void;
rotateOfInner(t: IMatrixData, origin: IPointData, angle: number): void;
skew(t: IMatrixData, x: number, y?: number): void;
skewOfOuter(t: IMatrixData, origin: IPointData, x: number, y?: number): void;
skewOfInner(t: IMatrixData, origin: IPointData, x: number, y?: number): void;
multiply(t: IMatrixData, matrix: IMatrixData): void;
preMultiply(t: IMatrixData, matrix: IMatrixData): void;
divide(t: IMatrixData, matrix: IMatrixData): void;
tempInvert(t: IMatrixData): IMatrixData;
invert(t: IMatrixData): void;
toOuterPoint(t: IMatrixData, inner: IPointData, to?: IPointData, distance?: boolean): void;
toInnerPoint(t: IMatrixData, outer: IPointData, to?: IPointData, distance?: boolean): void;
decompose(t: IMatrixData): IMatrixDecompositionData;
reset(t: IMatrixData): void;
};
declare const MathHelper: {
within(value: number, min: number, max: number): number;
fourNumber(num: number | number[]): number[];
formatRotation(rotation: number, unsign?: boolean): number;
getGapRotation(rotation: number, gap: number): number;
formatSkew(skew: number): number;
};
declare const OneRadian: number;
declare const PI2: number;
declare const PI_2: number;
declare const StringNumberMap: INumberMap;
export { AutoBounds, Bounds, BoundsHelper, IncrementId, MathHelper, Matrix, MatrixHelper, OneRadian, PI2, PI_2, Point, PointHelper, StringNumberMap, TwoPointBounds, TwoPointBoundsHelper };
+5
-3
{
"name": "@leafer/math",
"version": "1.0.0-beta.12",
"version": "1.0.0-beta.15",
"description": "@leafer/math",

@@ -8,4 +8,6 @@ "author": "Chao (Leafer) Wan",

"main": "src/index.ts",
"types": "types/index.d.ts",
"files": [
"src"
"types",
"dist"
],

@@ -23,4 +25,4 @@ "repository": {

"devDependencies": {
"@leafer/interface": "1.0.0-beta.12"
"@leafer/interface": "1.0.0-beta.15"
}
}
import { IAutoBounds, IAutoBoundsData, IBounds, ISizeData } from '@leafer/interface'
import { Bounds } from './Bounds'
export class AutoBounds implements IAutoBounds {
public top: number
public right: number
public bottom: number
public left: number
public width: number
public height: number
constructor(top?: number | IAutoBoundsData, right?: number, bottom?: number, left?: number, width?: number, height?: number) {
typeof top === 'object' ? this.copy(top) : this.set(top, right, bottom, left, width, height)
}
set(top = 0, right = 0, bottom = 0, left = 0, width = 0, height = 0): void {
this.top = top
this.right = right
this.bottom = bottom
this.left = left
this.width = width
this.height = height
}
copy(autoSize: IAutoBoundsData): void {
const { top, right, bottom, left, width, height } = autoSize
this.set(top, right, bottom, left, width, height)
}
getBoundsFrom(parent: ISizeData): IBounds {
const { top, right, bottom, left, width, height } = this
return new Bounds(left, top, width ? width : parent.width - left - right, height ? height : parent.height - top - bottom)
}
}
import { IBounds, IBoundsData, IMatrixData, IPointData, IBoundsDataHandle, IObject, IMatrix, IRadiusPointData } from '@leafer/interface'
import { BoundsHelper as B } from './BoundsHelper'
export class Bounds implements IBounds {
public x: number
public y: number
public width: number
public height: number
constructor(x?: number | IBoundsData, y?: number, width?: number, height?: number) {
typeof x === 'object' ? B.copy(this, x) : B.set(this, x, y, width, height)
}
public set(x?: number, y?: number, width?: number, height?: number): void {
B.set(this, x, y, width, height)
}
public copy(bounds: IBoundsData): IBounds {
B.copy(this, bounds)
return this
}
public clone(): IBounds {
return new Bounds(this)
}
public scale(scale: number): IBounds {
B.scale(this, scale)
return this
}
public toOuterOf(matrix: IMatrixData, to?: IBoundsData): IBounds {
B.toOuterOf(this, matrix, to)
return this
}
public getFitMatrix(put: IBoundsData): IMatrix {
return B.getFitMatrix(this, put)
}
public spread(size: number): IBounds {
B.spread(this, size)
return this
}
public ceil(): IBounds {
B.ceil(this)
return this
}
public add(bounds: IBoundsData): IBounds {
B.add(this, bounds)
return this
}
public addList(boundsList: IBounds[]): IBounds {
B.setByList(this, boundsList, true)
return this
}
public setByList(boundsList: IBounds[], addMode?: boolean): IBounds {
B.setByList(this, boundsList, addMode)
return this
}
public addListWithHandle(list: IObject[], boundsDataHandle: IBoundsDataHandle): IBounds {
B.setByListWithHandle(this, list, boundsDataHandle, true)
return this
}
public setByListWithHandle(list: IObject[], boundsDataHandle: IBoundsDataHandle, addMode?: boolean): IBounds {
B.setByListWithHandle(this, list, boundsDataHandle, addMode)
return this
}
public setByPoints(points: IPointData[]): IBounds {
B.setByPoints(this, points)
return this
}
public hitPoint(point: IPointData, pointMatrix?: IMatrixData): boolean {
return B.hitPoint(this, point, pointMatrix)
}
public hitRadiusPoint(point: IRadiusPointData, pointMatrix?: IMatrixData): boolean {
return B.hitRadiusPoint(this, point, pointMatrix)
}
public hit(bounds: IBoundsData, boundsMatrix?: IMatrixData): boolean {
return B.hit(this, bounds, boundsMatrix)
}
public includes(bounds: IBoundsData, boundsMatrix?: IMatrixData): boolean {
return B.includes(this, bounds, boundsMatrix)
}
public intersect(bounds: IBoundsData, boundsMatrix?: IMatrixData): IBounds {
B.intersect(this, bounds, boundsMatrix)
return this
}
public getIntersect(bounds: IBoundsData, boundsMatrix?: IMatrixData): IBounds {
return new Bounds(B.getIntersectData(this, bounds, boundsMatrix))
}
public isSame(bounds: IBoundsData): boolean {
return B.isSame(this, bounds)
}
public isEmpty(): boolean {
return B.isEmpty(this)
}
public reset(): void {
B.reset(this)
}
}
import { IPointData, IBoundsData, IMatrixData, IBoundsDataHandle, IObject, IMatrix, IOffsetBoundsData, IRadiusPointData } from '@leafer/interface'
import { Matrix } from './Matrix'
import { MatrixHelper as M } from './MatrixHelper'
import { TwoPointBoundsHelper as TB } from './TwoPointBoundsHelper'
import { PointHelper as P } from './PointHelper'
const { tempPointBounds, setPoint, addPoint, toBounds } = TB
const { toOuterPoint } = M
let right: number, bottom: number, boundsRight: number, boundsBottom: number
const point = {} as IPointData
const toPoint = {} as IPointData
export const BoundsHelper = {
tempBounds: {} as IBoundsData,
set(t: IBoundsData, x = 0, y = 0, width = 0, height = 0): void {
t.x = x
t.y = y
t.width = width
t.height = height
},
copy(t: IBoundsData, bounds: IBoundsData): void {
t.x = bounds.x
t.y = bounds.y
t.width = bounds.width
t.height = bounds.height
},
copyAndSpread(t: IBoundsData, bounds: IBoundsData, spread: number): void {
B.set(t, bounds.x - spread, bounds.y - spread, bounds.width + spread * 2, bounds.height + spread * 2)
},
right(t: IBoundsData): number {
return t.x + t.width
},
bottom(t: IBoundsData): number {
return t.y + t.height
},
move(t: IBoundsData, x: number, y: number): void {
t.x += x
t.y += y
},
getByMove(t: IBoundsData, x: number, y: number): IBoundsData {
t = { ...t }
B.move(t, x, y)
return t
},
toOffsetOutBounds(t: IBoundsData, to?: IOffsetBoundsData, parent?: IBoundsData): void {
if (!to) {
to = t as IOffsetBoundsData
} else {
copy(to, t)
}
if (parent) {
to.offsetX = -(B.right(parent) - t.x)
to.offsetY = -(B.bottom(parent) - t.y)
} else {
to.offsetX = t.x + t.width
to.offsetY = t.y + t.height
}
B.move(to, -to.offsetX, -to.offsetY)
},
scale(t: IBoundsData, scale: number): void {
t.x *= scale
t.y *= scale
t.width *= scale
t.height *= scale
},
tempToOuterOf(t: IBoundsData, matrix: IMatrixData): IBoundsData {
B.copy(B.tempBounds, t)
B.toOuterOf(B.tempBounds, matrix)
return B.tempBounds
},
getOuterOf(t: IBoundsData, matrix: IMatrixData): IBoundsData {
t = { ...t }
B.toOuterOf(t, matrix)
return t
},
toOuterOf(t: IBoundsData, matrix: IMatrixData, to?: IBoundsData): void {
to || (to = t)
if (matrix.b === 0 && matrix.c === 0) {
const { a, d } = matrix
if (a > 0) {
to.width = t.width * a
to.x = matrix.e + t.x * a
} else {
to.width = t.width * -a
to.x = matrix.e + t.x * a - to.width
}
if (d > 0) {
to.height = t.height * d
to.y = matrix.f + t.y * d
} else {
to.height = t.height * -d
to.y = matrix.f + t.y * d - to.height
}
} else {
point.x = t.x
point.y = t.y
toOuterPoint(matrix, point, toPoint)
setPoint(tempPointBounds, toPoint.x, toPoint.y)
point.x = t.x + t.width
toOuterPoint(matrix, point, toPoint)
addPoint(tempPointBounds, toPoint.x, toPoint.y)
point.y = t.y + t.height
toOuterPoint(matrix, point, toPoint)
addPoint(tempPointBounds, toPoint.x, toPoint.y)
point.x = t.x
toOuterPoint(matrix, point, toPoint)
addPoint(tempPointBounds, toPoint.x, toPoint.y)
toBounds(tempPointBounds, to)
}
},
getFitMatrix(t: IBoundsData, put: IBoundsData): IMatrix {
const scale = Math.min(1, Math.min(t.width / put.width, t.height / put.height))
return new Matrix(scale, 0, 0, scale, -put.x * scale, -put.y * scale)
},
getSpread(t: IBoundsData, size: number): IBoundsData {
const n = {} as IBoundsData
B.copyAndSpread(n, t, size)
return n
},
spread(t: IBoundsData, size: number): void {
B.copyAndSpread(t, t, size)
},
ceil(t: IBoundsData): void {
t.x = Math.floor(t.x)
t.y = Math.floor(t.y)
t.width = Math.ceil(t.width)
t.height = Math.ceil(t.height)
},
add(t: IBoundsData, bounds: IBoundsData): void {
right = t.x + t.width
bottom = t.y + t.height
boundsRight = bounds.x + bounds.width
boundsBottom = bounds.y + bounds.height
right = right > boundsRight ? right : boundsRight
bottom = bottom > boundsBottom ? bottom : boundsBottom
t.x = t.x < bounds.x ? t.x : bounds.x
t.y = t.y < bounds.y ? t.y : bounds.y
t.width = right - t.x
t.height = bottom - t.y
},
addList(t: IBoundsData, list: IBoundsData[]): void {
B.setByListWithHandle(t, list, undefined, true)
},
setByList(t: IBoundsData, list: IBoundsData[], addMode = false): void {
B.setByListWithHandle(t, list, undefined, addMode)
},
addListWithHandle(t: IBoundsData, list: IObject[], boundsDataHandle: IBoundsDataHandle): void {
B.setByListWithHandle(t, list, boundsDataHandle, true)
},
setByListWithHandle(t: IBoundsData, list: IObject[], boundsDataHandle: IBoundsDataHandle, addMode = false): void {
let bounds: IBoundsData, first = true
for (let i = 0, len = list.length; i < len; i++) {
bounds = boundsDataHandle ? boundsDataHandle(list[i]) : list[i] as IBoundsData
if (bounds && (bounds.width || bounds.height)) {
if (first) {
first = false
if (!addMode) copy(t, bounds)
} else {
add(t, bounds)
}
}
}
if (first) B.reset(t)
},
setByPoints(t: IBoundsData, points: IPointData[]): void {
points.forEach((point, index) => {
index === 0 ? setPoint(tempPointBounds, point.x, point.y) : addPoint(tempPointBounds, point.x, point.y)
})
toBounds(tempPointBounds, t)
},
hitRadiusPoint(t: IBoundsData, point: IRadiusPointData, pointMatrix?: IMatrixData): boolean {
if (pointMatrix) point = P.tempToInnerRadiusPointOf(point, pointMatrix)
return (point.x >= t.x - point.radiusX && point.x <= t.x + t.width + point.radiusX) && (point.y >= t.y - point.radiusY && point.y <= t.y + t.height + point.radiusY)
},
hitPoint(t: IBoundsData, point: IPointData, pointMatrix?: IMatrixData): boolean {
if (pointMatrix) point = P.tempToInnerOf(point, pointMatrix)
return (point.x >= t.x && point.x <= t.x + t.width) && (point.y >= t.y && point.y <= t.y + t.height)
},
hit(t: IBoundsData, other: IBoundsData, otherMatrix?: IMatrixData): boolean {
if (otherMatrix) other = B.tempToOuterOf(other, otherMatrix)
return !((t.y + t.height < other.y) || (other.y + other.height < t.y) || (t.x + t.width < other.x) || (other.x + other.width < t.x))
},
includes(t: IBoundsData, other: IBoundsData, otherMatrix?: IMatrixData): boolean {
if (otherMatrix) other = B.tempToOuterOf(other, otherMatrix)
return (t.x <= other.x) && (t.y <= other.y) && (t.x + t.width >= other.x + other.width) && (t.y + t.height >= other.y + other.height)
},
getIntersectData(t: IBoundsData, other: IBoundsData, otherMatrix?: IMatrixData): IBoundsData {
if (otherMatrix) other = B.tempToOuterOf(other, otherMatrix)
let { x, y, width, height } = other
right = x + width
bottom = y + height
boundsRight = t.x + t.width
boundsBottom = t.y + t.height
x = x > t.x ? x : t.x
y = y > t.y ? y : t.y
right = right < boundsRight ? right : boundsRight
bottom = bottom < boundsBottom ? bottom : boundsBottom
width = right - x
height = bottom - y
return { x, y, width, height }
},
intersect(t: IBoundsData, other: IBoundsData, otherMatrix?: IMatrixData): void {
B.copy(t, B.getIntersectData(t, other, otherMatrix))
},
isSame(t: IBoundsData, bounds: IBoundsData): boolean {
return t.x === bounds.x && t.y === bounds.y && t.width === bounds.width && t.height === bounds.height
},
isEmpty(t: IBoundsData): boolean {
return t.x === 0 && t.y === 0 && t.width === 0 && t.height === 0
},
reset(t: IBoundsData): void {
B.set(t)
}
}
const B = BoundsHelper
const { add, copy } = B
import { INumberMap } from '@leafer/interface'
export const IncrementId = {
RUNTIME: 'runtime',
LEAF: 'leaf',
TASK: 'task',
CNAVAS: 'canvas',
IMAGE: 'image',
types: {} as INumberMap,
create(typeName: string): number {
const { types } = I
if (types[typeName]) {
return types[typeName]++
} else {
types[typeName] = 1
return 0
}
}
}
const I = IncrementId
export const MathHelper = {
within(value: number, min: number, max: number): number {
if (value < min) value = min
if (value > max) value = max
return value
},
fourNumber(num: number | number[]): number[] {
let one: number, two: number, three: number, four: number // = top right bottom left || topLeft, topRight, bottomRight, bottomLeft
if (num instanceof Array) {
switch (num.length) {
case 4:
return num
case 2:
one = three = num[0]
two = four = num[1]
break
case 3:
one = num[0]
two = four = num[1]
three = num[2]
break
case 1:
num = num[0]
break
default:
num = 0
}
}
return one === undefined ? [num as number, num as number, num as number, num as number] : [one, two, three, four]
}
}
export const OneRadian = Math.PI / 180
export const PI2 = Math.PI * 2
export const PI_2 = Math.PI / 2
import { IMatrix, IMatrixData, IPointData, IMatrixDecompositionData } from '@leafer/interface'
import { MatrixHelper as M } from './MatrixHelper'
export class Matrix implements IMatrix {
public a: number
public b: number
public c: number
public d: number
public e: number
public f: number
constructor(a?: number | IMatrixData, b?: number, c?: number, d?: number, e?: number, f?: number) {
typeof a === 'object' ? M.copy(this, a) : M.set(this, a, b, c, d, e, f)
}
public set(a?: number, b?: number, c?: number, d?: number, e?: number, f?: number): void {
M.set(this, a, b, c, d, e, f)
}
public copy(matrix: IMatrixData): IMatrix {
M.copy(this, matrix)
return this
}
public clone(): IMatrix {
return new Matrix(this)
}
public translate(x: number, y: number): IMatrix {
M.translate(this, x, y)
return this
}
public translateInner(x: number, y: number): IMatrix {
M.translateInner(this, x, y)
return this
}
public scale(x: number, y?: number): IMatrix {
M.scale(this, x, y)
return this
}
public scaleOfOuter(origin: IPointData, x: number, y?: number): IMatrix {
M.scaleOfOuter(this, origin, x, y)
return this
}
public scaleOfInner(origin: IPointData, x: number, y?: number): IMatrix {
M.scaleOfInner(this, origin, x, y)
return this
}
public rotate(angle: number): IMatrix {
M.rotate(this, angle)
return this
}
public rotateOfOuter(origin: IPointData, angle: number): IMatrix {
M.rotateOfOuter(this, origin, angle)
return this
}
public rotateOfInner(origin: IPointData, angle: number): IMatrix {
M.rotateOfInner(this, origin, angle)
return this
}
public skew(x: number, y?: number): IMatrix {
M.skew(this, x, y)
return this
}
public skewOfOuter(origin: IPointData, x: number, y?: number): IMatrix {
M.skewOfOuter(this, origin, x, y)
return this
}
public skewOfInner(origin: IPointData, x: number, y?: number): IMatrix {
M.skewOfInner(this, origin, x, y)
return this
}
public multiply(matrix: IMatrixData): IMatrix {
M.multiply(this, matrix)
return this
}
public preMultiply(matrix: IMatrixData): IMatrix {
M.preMultiply(this, matrix)
return this
}
public divide(matrix: IMatrixData): IMatrix {
M.divide(this, matrix)
return this
}
public invert(): IMatrix {
M.invert(this)
return this
}
public toOuterPoint(inner: IPointData, to?: IPointData): void {
M.toOuterPoint(this, inner, to)
}
public toInnerPoint(outer: IPointData, to?: IPointData): void {
M.toInnerPoint(this, outer, to)
}
public decompose(): IMatrixDecompositionData {
return M.decompose(this)
}
public reset(): void {
M.reset(this)
}
}
import { IMatrix, IMatrixData, IPointData, IMatrixDecompositionData } from '@leafer/interface'
import { OneRadian } from './MathHelper'
const { sin, cos, acos, atan, sqrt, PI } = Math
const tempPoint = {} as IPointData
function get(): IMatrixData {
return { a: 1, b: 0, c: 0, d: 1, e: 0, f: 0 }
}
export const MatrixHelper = {
defaultMatrix: get(),
tempMatrix: {} as IMatrixData,
set(t: IMatrixData, a = 1, b = 0, c = 0, d = 1, e = 0, f = 0): void {
t.a = a
t.b = b
t.c = c
t.d = d
t.e = e
t.f = f
},
get,
copy(t: IMatrixData, matrix: IMatrixData): void {
t.a = matrix.a
t.b = matrix.b
t.c = matrix.c
t.d = matrix.d
t.e = matrix.e
t.f = matrix.f
},
translate(t: IMatrixData, x: number, y: number): void {
t.e += x
t.f += y
},
translateInner(t: IMatrixData, x: number, y: number): void {
t.e += t.a * x + t.c * y
t.f += t.b * x + t.d * y
},
scale(t: IMatrixData, x: number, y: number = x): void {
t.a *= x
t.b *= x
t.c *= y
t.d *= y
},
scaleOfOuter(t: IMatrixData, origin: IPointData, x: number, y: number = x): void {
M.toInnerPoint(t, origin, tempPoint)
M.scaleOfInner(t, tempPoint, x, y)
},
scaleOfInner(t: IMatrixData, origin: IPointData, x: number, y: number = x): void {
M.translateInner(t, origin.x, origin.y)
M.scale(t, x, y)
M.translateInner(t, -origin.x, -origin.y)
},
rotate(t: IMatrixData, angle: number): void {
angle *= OneRadian
const cosR = cos(angle)
const sinR = sin(angle)
const { a, b, c, d } = t
t.a = (a * cosR) - (b * sinR)
t.b = (a * sinR) + (b * cosR)
t.c = (c * cosR) - (d * sinR)
t.d = (c * sinR) + (d * cosR)
},
rotateOfOuter(t: IMatrixData, origin: IPointData, angle: number): void {
M.toInnerPoint(t, origin, tempPoint)
M.rotateOfInner(t, tempPoint, angle)
},
rotateOfInner(t: IMatrixData, origin: IPointData, angle: number): void {
M.translateInner(t, origin.x, origin.y)
M.rotate(t, angle)
M.translateInner(t, -origin.x, -origin.y)
},
skew(t: IMatrixData, x: number, y?: number): void {
const { a, b, c, d } = t
if (y) {
y *= OneRadian
t.a = a + c * y
t.b = b + d * y
}
if (x) {
x *= OneRadian
t.c = c + a * x
t.d = d + b * x
}
},
skewOfOuter(t: IMatrixData, origin: IPointData, x: number, y?: number): void {
M.toInnerPoint(t, origin, tempPoint)
M.skewOfInner(t, tempPoint, x, y)
},
skewOfInner(t: IMatrixData, origin: IPointData, x: number, y?: number): void {
M.translateInner(t, origin.x, origin.y)
M.skew(t, x, y)
M.translateInner(t, -origin.x, -origin.y)
},
multiply(t: IMatrixData, matrix: IMatrixData): void {
const { a, b, c, d, e, f } = t
t.a = matrix.a * a + matrix.b * c
t.b = matrix.a * b + matrix.b * d
t.c = matrix.c * a + matrix.d * c
t.d = matrix.c * b + matrix.d * d
t.e = matrix.e * a + matrix.f * c + e
t.f = matrix.e * b + matrix.f * d + f
},
preMultiply(t: IMatrixData, matrix: IMatrixData): void {
const { a, b, c, d, e, f } = t
if (matrix.a !== 1 || matrix.b !== 0 || matrix.c !== 0 || matrix.d !== 1) {
t.a = (a * matrix.a) + (b * matrix.c)
t.b = (a * matrix.b) + (b * matrix.d)
t.c = (c * matrix.a) + (d * matrix.c)
t.d = (c * matrix.b) + (d * matrix.d)
}
t.e = (e * matrix.a) + (f * matrix.c) + matrix.e
t.f = (e * matrix.b) + (f * matrix.d) + matrix.f
},
divide(t: IMatrixData, matrix: IMatrixData): void {
M.multiply(t, M.tempInvert(matrix))
},
tempInvert(t: IMatrixData): IMatrixData {
const { tempMatrix: temp } = M
M.copy(temp, t)
M.invert(temp)
return temp
},
invert(t: IMatrixData): void {
const { a, b, c, d, e, f } = t
const s = 1 / (a * d - b * c)
t.a = d * s
t.b = -b * s
t.c = -c * s
t.d = a * s
t.e = -(e * d - f * c) * s
t.f = -(f * a - e * b) * s
},
toOuterPoint(t: IMatrixData, inner: IPointData, to?: IPointData, isMovePoint?: boolean): void {
const { x, y } = inner
// outer
to || (to = inner)
to.x = (x * t.a) + (y * t.c)
to.y = (x * t.b) + (y * t.d)
if (!isMovePoint) {
to.x += t.e
to.y += t.f
}
},
toInnerPoint(t: IMatrixData, outer: IPointData, to?: IPointData, isMovePoint?: boolean): void {
const { x, y } = outer
const { a, b, c, d } = t
const s = 1 / (a * d - b * c)
// inner
to || (to = outer)
to.x = (x * d - y * c) * s
to.y = (y * a - x * b) * s
if (!isMovePoint) {
const { e, f } = t
to.x -= (e * d - f * c) * s
to.y -= (f * a - e * b) * s
}
},
decompose(t: IMatrixData): IMatrixDecompositionData {
const { a, b, c, d } = t
let scaleX = a, scaleY = d, rotation = 0, skewX = 0, skewY = 0
if (b || c) {
const s = a * d - b * c
const k = a * c + b * d
if (b) {
const ab = a * a + b * b
scaleX = sqrt(ab)
scaleY = s / scaleX
const r = a / scaleX
rotation = b > 0 ? acos(r) : -acos(r)
skewX = atan(k / ab) / OneRadian
} else {
const cd = c * c + d * d
scaleY = sqrt(cd)
scaleX = s / scaleY
const r = c / scaleY
rotation = PI / 2 - (d > 0 ? acos(-r) : -acos(r))
skewY = atan(k / cd) / OneRadian
}
rotation /= OneRadian
}
return { x: t.e, y: t.f, scaleX, scaleY, rotation, skewX, skewY }
},
reset(t: IMatrix): void {
M.set(t)
}
}
const M = MatrixHelper
import { IPoint, IPointData, IMatrixData } from '@leafer/interface'
import { PointHelper as P } from './PointHelper'
export class Point implements IPoint {
public x: number
public y: number
constructor(x?: number | IPointData, y?: number) {
typeof x === 'object' ? P.copy(this, x) : P.set(this, x, y)
}
public set(x?: number, y?: number): void {
P.set(this, x, y)
}
public copy(point: IPointData): IPoint {
P.copy(this, point)
return this
}
public clone(): IPoint {
return new Point(this)
}
public rotate(angle: number, center?: IPointData): IPoint {
P.rotate(this, angle, center)
return this
}
public toInnerOf(matrix: IMatrixData, to?: IPointData): IPoint {
P.toInnerOf(this, matrix, to)
return this
}
public toOuterOf(matrix: IMatrixData, to?: IPointData): IPoint {
P.toOuterOf(this, matrix, to)
return this
}
public getCenter(to: IPointData): IPointData {
return P.getCenter(this, to)
}
public getDistance(to: IPointData): number {
return P.getDistance(this, to)
}
public getAngle(to: IPointData): number {
return P.getAngle(this, to)
}
public getAtan2(to: IPointData): number {
return P.getAtan2(this, to)
}
public reset(): void {
P.reset(this)
}
}
import { IPointData, IMatrixData, IRadiusPointData } from '@leafer/interface'
import { OneRadian } from './MathHelper'
import { MatrixHelper as M } from './MatrixHelper'
const { toInnerPoint, toOuterPoint } = M
const { sin, cos, abs, sqrt, atan2 } = Math
export const PointHelper = {
defaultPoint: { x: 0, y: 0 } as IPointData,
tempPoint: {} as IPointData,
tempRadiusPoint: {} as IRadiusPointData,
set(t: IPointData, x = 0, y = 0): void {
t.x = x
t.y = y
},
copy(t: IPointData, point: IPointData): void {
t.x = point.x
t.y = point.y
},
move(t: IPointData, x: number, y: number): void {
t.x += x
t.y += y
},
rotate(t: IPointData, rotation: number, center?: IPointData): void {
if (!center) center = P.defaultPoint
const cosR = cos(rotation * OneRadian)
const sinR = sin(rotation * OneRadian)
const rx = t.x - center.x
const ry = t.y - center.y
t.x = center.x + rx * cosR - ry * sinR
t.y = center.y + rx * sinR + ry * cosR
},
tempToInnerOf(t: IPointData, matrix: IMatrixData): IPointData {
const { tempPoint: temp } = P
P.copy(temp, t)
toInnerPoint(matrix, temp, temp)
return temp
},
tempToOuterOf(t: IPointData, matrix: IMatrixData): IPointData {
const { tempPoint: temp } = P
P.copy(temp, t)
toOuterPoint(matrix, temp, temp)
return temp
},
tempToInnerRadiusPointOf(t: IRadiusPointData, matrix: IMatrixData): IRadiusPointData {
const { tempRadiusPoint: temp } = P
P.copy(temp, t)
P.toInnerRadiusPointOf(t, matrix, temp)
return temp
},
toInnerRadiusPointOf(t: IRadiusPointData, matrix: IMatrixData, to?: IRadiusPointData): void {
to || (to = t)
toInnerPoint(matrix, t, to)
to.radiusX = t.radiusX / matrix.a
to.radiusY = t.radiusY / matrix.d
},
toInnerOf(t: IPointData, matrix: IMatrixData, to?: IPointData): void {
toInnerPoint(matrix, t, to)
},
toOuterOf(t: IPointData, matrix: IMatrixData, to?: IPointData): void {
toOuterPoint(matrix, t, to)
},
getCenter(t: IPointData, to: IPointData): IPointData {
return { x: t.x + (to.x - t.x) / 2, y: t.y + (to.y - t.y) / 2 }
},
getDistance(t: IPointData, point: IPointData): number {
const x = abs(point.x - t.x)
const y = abs(point.y - t.y)
return sqrt(x * x + y * y)
},
getAngle(t: IPointData, to: IPointData): number {
return P.getAtan2(t, to) / OneRadian
},
getAtan2(t: IPointData, to: IPointData): number {
return atan2(to.y - t.y, to.x - t.x)
},
getDistancePoint(t: IPointData, to: IPointData, distance: number): IPointData {
const r = P.getAtan2(t, to)
return { x: t.x + cos(r) * distance, y: t.y + sin(r) * distance }
},
reset(t: IPointData): void {
P.reset(t)
}
}
const P = PointHelper
import { INumberMap } from '@leafer/interface'
export const StringNumberMap: INumberMap = {
'0': 1,
'1': 1,
'2': 1,
'3': 1,
'4': 1,
'5': 1,
'6': 1,
'7': 1,
'8': 1,
'9': 1,
'.': 1,
'e': 1,
'E': 1
}
import { ITwoPointBounds, ITwoPointBoundsData } from '@leafer/interface'
import { TwoPointBoundsHelper as P } from './TwoPointBoundsHelper'
export class TwoPointBounds implements ITwoPointBounds {
public minX: number
public minY: number
public maxX: number
public maxY: number
constructor(x: number, y: number) {
P.setPoint(this, x, y)
}
addPoint(x: number, y: number): void {
P.addPoint(this, x, y)
}
addBounds(x: number, y: number, width: number, height: number): void {
P.addBounds(this, x, y, width, height)
}
add(pb: ITwoPointBoundsData): void {
P.add(this, pb)
}
}
import { ITwoPointBoundsData, IBoundsData } from '@leafer/interface'
export const TwoPointBoundsHelper = {
tempPointBounds: {} as ITwoPointBoundsData,
setPoint(t: ITwoPointBoundsData, minX: number, minY: number): void {
t.minX = t.maxX = minX
t.minY = t.maxY = minY
},
addPoint(t: ITwoPointBoundsData, x: number, y: number): void {
t.minX = x < t.minX ? x : t.minX
t.minY = y < t.minY ? y : t.minY
t.maxX = x > t.maxX ? x : t.maxX
t.maxY = y > t.maxY ? y : t.maxY
},
addBounds(t: ITwoPointBoundsData, x: number, y: number, width: number, height: number): void {
addPoint(t, x, y)
addPoint(t, x + width, y + height)
},
copy(t: ITwoPointBoundsData, pb: ITwoPointBoundsData): void {
t.minX = pb.minX
t.minY = pb.minY
t.maxX = pb.maxX
t.maxY = pb.maxY
},
add(t: ITwoPointBoundsData, pb: ITwoPointBoundsData): void {
t.minX = pb.minX < t.minX ? pb.minX : t.minX
t.minY = pb.minY < t.minY ? pb.minY : t.minY
t.maxX = pb.maxX > t.maxX ? pb.maxX : t.maxX
t.maxY = pb.maxY > t.maxY ? pb.maxY : t.maxY
},
toBounds(t: ITwoPointBoundsData, setBounds: IBoundsData): void {
setBounds.x = t.minX
setBounds.y = t.minY
setBounds.width = t.maxX - t.minX
setBounds.height = t.maxY - t.minY
}
}
const { addPoint } = TwoPointBoundsHelper