diff --git a/__tests__/unit/dom/index.spec.ts b/__tests__/unit/dom/index.spec.ts new file mode 100644 index 0000000..4193a88 --- /dev/null +++ b/__tests__/unit/dom/index.spec.ts @@ -0,0 +1,26 @@ +import { createDOM, modifyCSS } from '../../../src'; + +describe('dom', function () { + it('createDOM', () => { + const dom = createDOM(`
createDOM by string
`); + expect(dom).not.toBeUndefined(); + expect(dom.innerHTML).toBe('createDOM by string'); + }); + + it('modifyCSS', () => { + const dom = createDOM(`
modifyCSS dom
`); + + expect(dom.style.color).toBe(''); + expect(dom.style.fontSize).toBe(''); + + modifyCSS(dom, { + color: 'red', + fontSize: '20px', + }); + + expect(dom.style.color).toBe('red'); + expect(dom.style.fontSize).toBe('20px'); + + expect(modifyCSS(null, { color: 'red' })).toBeUndefined(); + }); +}); diff --git a/package.json b/package.json index 931260b..9dceffb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@antv/util", - "version": "3.3.4", + "version": "3.3.5", "license": "MIT", "sideEffects": false, "main": "lib/index.js", @@ -90,6 +90,7 @@ }, "dependencies": { "fast-deep-equal": "^3.1.3", + "flru": "^1.0.2", "gl-matrix": "^3.3.0", "tslib": "^2.3.1" }, diff --git a/src/color/index.ts b/src/color/index.ts index f0c4241..723eccf 100644 --- a/src/color/index.ts +++ b/src/color/index.ts @@ -1,5 +1,4 @@ export { rgb2arr } from './rgb2arr'; export { gradient } from './gradient'; -// todo 没有 memoize export { toRGB } from './torgb'; export { toCSSGradient } from './tocssgradient'; diff --git a/src/color/torgb.ts b/src/color/torgb.ts index 20a3230..68c67f2 100644 --- a/src/color/torgb.ts +++ b/src/color/torgb.ts @@ -1,3 +1,4 @@ +import { memoize } from '../lodash'; import { arr2rgb } from './arr2rgb'; const RGB_REG = /rgba?\(([\s.,0-9]+)\)/; @@ -21,7 +22,7 @@ let iEl: HTMLElement; * @param {color} color 颜色 * @return 将颜色转换到 '#ffffff' 的格式 */ -export function toRGB(color: string): string { +function toRGBString(color: string): string { // 如果已经是 rgb的格式 if (color[0] === '#' && color.length === 7) { return color; @@ -43,3 +44,10 @@ export function toRGB(color: string): string { return rst; } + +/** + * export with memoize. + * @param color + * @returns + */ +export const toRGB = memoize(toRGBString, (color) => color, 256); diff --git a/src/dom/create-dom.ts b/src/dom/create-dom.ts new file mode 100644 index 0000000..c1e085c --- /dev/null +++ b/src/dom/create-dom.ts @@ -0,0 +1,15 @@ +/** + * Create DOM from a html string. + * @param str + * @returns + */ +export function createDOM(str: string): HTMLElement { + const container = document.createElement('div'); + container.innerHTML = str; + + const dom = container.childNodes[0]; + if (dom && container.contains(dom)) { + container.removeChild(dom); + } + return dom as HTMLElement; +} diff --git a/src/dom/index.ts b/src/dom/index.ts new file mode 100644 index 0000000..6696c5c --- /dev/null +++ b/src/dom/index.ts @@ -0,0 +1,2 @@ +export { createDOM } from './create-dom'; +export { modifyCSS } from './modify-css'; diff --git a/src/dom/modify-css.ts b/src/dom/modify-css.ts new file mode 100644 index 0000000..723148d --- /dev/null +++ b/src/dom/modify-css.ts @@ -0,0 +1,14 @@ +/** + * Modify the CSS of a DOM. + * @param dom + * @param css + * @returns + */ +export function modifyCSS(dom: HTMLElement | null | undefined, css: { [key: string]: any }): HTMLElement { + if (!dom) return; + + Object.keys(css).forEach((key) => { + dom.style[key] = css[key]; + }); + return dom; +} diff --git a/src/helper/index.ts b/src/helper/index.ts deleted file mode 100644 index 5e51e1d..0000000 --- a/src/helper/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { mod } from './mod'; -export { toRadian } from './to-radian'; diff --git a/src/helper/mod.ts b/src/helper/mod.ts deleted file mode 100644 index 85a72c0..0000000 --- a/src/helper/mod.ts +++ /dev/null @@ -1,3 +0,0 @@ -export function mod(n: number, m: number): number { - return ((n % m) + m) % m; -} diff --git a/src/helper/to-radian.ts b/src/helper/to-radian.ts deleted file mode 100644 index ef19113..0000000 --- a/src/helper/to-radian.ts +++ /dev/null @@ -1,5 +0,0 @@ -const RADIAN = Math.PI / 180; - -export function toRadian(degree: number): number { - return RADIAN * degree; -} diff --git a/src/index.ts b/src/index.ts index 370b32c..96c262c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,3 +3,4 @@ export * from './matrix'; export * from './path'; export * from './lodash'; export * from './math'; +export * from './dom'; diff --git a/src/lodash/memoize.ts b/src/lodash/memoize.ts index da71a2d..5b2b430 100644 --- a/src/lodash/memoize.ts +++ b/src/lodash/memoize.ts @@ -1,3 +1,4 @@ +import flru from 'flru'; import isFunction from './is-function'; /** @@ -5,8 +6,9 @@ import isFunction from './is-function'; * _.memoize(calColor, (...args) => args[0]); * @param f * @param resolver + * @param maxSize lru maxSize */ -export default (f: Function, resolver?: (...args: any[]) => string) => { +export default (f: Function, resolver?: (...args: any[]) => string, maxSize = 128) => { if (!isFunction(f)) { throw new TypeError('Expected a function'); } @@ -25,7 +27,7 @@ export default (f: Function, resolver?: (...args: any[]) => string) => { return result; }; - memoized.cache = new Map(); + memoized.cache = flru(maxSize); return memoized; }; diff --git a/src/matrix/angle-to.ts b/src/matrix/angle-to.ts new file mode 100644 index 0000000..7554371 --- /dev/null +++ b/src/matrix/angle-to.ts @@ -0,0 +1,24 @@ +import { vec2 } from 'gl-matrix'; +import { direction } from './direction'; + +/** + * 二维向量 v1 到 v2 的夹角 + * @param v1 + * @param v2 + * @param direct + */ +export function angleTo(v1: [number, number], v2: [number, number], direct?: boolean): number { + const ang = vec2.angle(v1, v2); + const angleLargeThanPI = direction(v1, v2) >= 0; + if (direct) { + if (angleLargeThanPI) { + return Math.PI * 2 - ang; + } + return ang; + } + + if (angleLargeThanPI) { + return ang; + } + return Math.PI * 2 - ang; +} diff --git a/src/matrix/direction.ts b/src/matrix/direction.ts new file mode 100644 index 0000000..d7c9bac --- /dev/null +++ b/src/matrix/direction.ts @@ -0,0 +1,9 @@ +/** + * 向量 v1 到 向量 v2 夹角的方向 + * @param {Array} v1 向量 + * @param {Array} v2 向量 + * @return {Boolean} >= 0 顺时针 < 0 逆时针 + */ +export function direction(v1: number[], v2: number[]): number { + return v1[0] * v2[1] - v2[0] * v1[1]; +} diff --git a/src/matrix/index.ts b/src/matrix/index.ts index 024fbd1..49527b3 100644 --- a/src/matrix/index.ts +++ b/src/matrix/index.ts @@ -1,108 +1,7 @@ /** * @description 扩展方法,提供 gl-matrix 为提供的方法 - * */ -import { mat3, vec2 } from 'gl-matrix'; - -type mat3Type = [number, number, number, number, number, number, number, number, number]; - -function leftTranslate(out, a, v) { - const transMat: mat3Type = [0, 0, 0, 0, 0, 0, 0, 0, 0]; - mat3.fromTranslation(transMat, v); - return mat3.multiply(out, transMat, a); -} - -function leftRotate(out, a, rad) { - const rotateMat: mat3Type = [0, 0, 0, 0, 0, 0, 0, 0, 0]; - mat3.fromRotation(rotateMat, rad); - return mat3.multiply(out, rotateMat, a); -} - -function leftScale(out, a, v) { - const scaleMat: mat3Type = [0, 0, 0, 0, 0, 0, 0, 0, 0]; - mat3.fromScaling(scaleMat, v); - return mat3.multiply(out, scaleMat, a); -} - -function leftMultiply(out, a, a1) { - return mat3.multiply(out, a1, a); -} -/** - * 根据 actions 来做 transform - * @param m - * @param actions - */ -export function transform(m: number[], actions: any[][]) { - const matrix = m ? [].concat(m) : [1, 0, 0, 0, 1, 0, 0, 0, 1]; - - for (let i = 0, len = actions.length; i < len; i++) { - const action = actions[i]; - switch (action[0]) { - case 't': - leftTranslate(matrix, matrix, [action[1], action[2]]); - break; - case 's': - leftScale(matrix, matrix, [action[1], action[2]]); - break; - case 'r': - leftRotate(matrix, matrix, action[1]); - break; - case 'm': - leftMultiply(matrix, matrix, action[1]); - break; - default: - break; - } - } - - return matrix; -} - -/** - * 向量 v1 到 向量 v2 夹角的方向 - * @param {Array} v1 向量 - * @param {Array} v2 向量 - * @return {Boolean} >= 0 顺时针 < 0 逆时针 - */ -export function direction(v1: number[], v2: number[]): number { - return v1[0] * v2[1] - v2[0] * v1[1]; -} - -/** - * 二维向量 v1 到 v2 的夹角 - * @param v1 - * @param v2 - * @param direct - */ -export function angleTo(v1: [number, number], v2: [number, number], direct?: boolean): number { - const ang = vec2.angle(v1, v2); - const angleLargeThanPI = direction(v1, v2) >= 0; - if (direct) { - if (angleLargeThanPI) { - return Math.PI * 2 - ang; - } - return ang; - } - - if (angleLargeThanPI) { - return ang; - } - return Math.PI * 2 - ang; -} - -/** - * 计算二维向量的垂直向量 - * @param out - * @param v - * @param flag - */ -export function vertical(out: number[], v: number[], flag: boolean): number[] { - if (flag) { - out[0] = v[1]; - out[1] = -1 * v[0]; - } else { - out[0] = -1 * v[1]; - out[1] = v[0]; - } - - return out; -} + **/ +export { transform } from './transform'; +export { angleTo } from './angle-to'; +export { direction } from './direction'; +export { vertical } from './vertical'; diff --git a/src/matrix/transform.ts b/src/matrix/transform.ts new file mode 100644 index 0000000..058bb39 --- /dev/null +++ b/src/matrix/transform.ts @@ -0,0 +1,55 @@ +import { mat3 } from 'gl-matrix'; + +type mat3Type = [number, number, number, number, number, number, number, number, number]; + +function leftTranslate(out, a, v) { + const transMat: mat3Type = [0, 0, 0, 0, 0, 0, 0, 0, 0]; + mat3.fromTranslation(transMat, v); + return mat3.multiply(out, transMat, a); +} + +function leftRotate(out, a, rad) { + const rotateMat: mat3Type = [0, 0, 0, 0, 0, 0, 0, 0, 0]; + mat3.fromRotation(rotateMat, rad); + return mat3.multiply(out, rotateMat, a); +} + +function leftScale(out, a, v) { + const scaleMat: mat3Type = [0, 0, 0, 0, 0, 0, 0, 0, 0]; + mat3.fromScaling(scaleMat, v); + return mat3.multiply(out, scaleMat, a); +} + +function leftMultiply(out, a, a1) { + return mat3.multiply(out, a1, a); +} +/** + * 根据 actions 来做 transform + * @param m + * @param actions + */ +export function transform(m: number[], actions: any[][]) { + const matrix = m ? [].concat(m) : [1, 0, 0, 0, 1, 0, 0, 0, 1]; + + for (let i = 0, len = actions.length; i < len; i++) { + const action = actions[i]; + switch (action[0]) { + case 't': + leftTranslate(matrix, matrix, [action[1], action[2]]); + break; + case 's': + leftScale(matrix, matrix, [action[1], action[2]]); + break; + case 'r': + leftRotate(matrix, matrix, action[1]); + break; + case 'm': + leftMultiply(matrix, matrix, action[1]); + break; + default: + break; + } + } + + return matrix; +} diff --git a/src/matrix/vertical.ts b/src/matrix/vertical.ts new file mode 100644 index 0000000..939d20f --- /dev/null +++ b/src/matrix/vertical.ts @@ -0,0 +1,17 @@ +/** + * 计算二维向量的垂直向量 + * @param out + * @param v + * @param flag + */ +export function vertical(out: number[], v: number[], flag: boolean): number[] { + if (flag) { + out[0] = v[1]; + out[1] = -1 * v[0]; + } else { + out[0] = -1 * v[1]; + out[1] = v[0]; + } + + return out; +} diff --git a/src/path/util/path-length-factory.ts b/src/path/util/path-length-factory.ts index 3811ec2..50df62e 100644 --- a/src/path/util/path-length-factory.ts +++ b/src/path/util/path-length-factory.ts @@ -25,8 +25,8 @@ export function pathLengthFactory( let mx = 0; let my = 0; let seg; - let MIN = []; - let MAX = []; + const MIN = []; + const MAX = []; let length = 0; let min = { x: 0, y: 0 }; let max = min; diff --git a/src/path/util/segment-arc-factory.ts b/src/path/util/segment-arc-factory.ts index 50cfc9e..f1490be 100644 --- a/src/path/util/segment-arc-factory.ts +++ b/src/path/util/segment-arc-factory.ts @@ -145,7 +145,7 @@ export function segmentArcFactory( let cur: [number, number] = [x, y]; let t = 0; let POINT = { x: 0, y: 0 }; - let POINTS = [{ x, y }]; + const POINTS = [{ x, y }]; if (distanceIsNumber && distance <= 0) { POINT = { x, y }; diff --git a/src/path/util/segment-cubic-factory.ts b/src/path/util/segment-cubic-factory.ts index 74e1f4c..ef6f8fc 100644 --- a/src/path/util/segment-cubic-factory.ts +++ b/src/path/util/segment-cubic-factory.ts @@ -48,7 +48,7 @@ export function segmentCubicFactory( let cur: [number, number] = [x, y]; let t = 0; let POINT = { x: 0, y: 0 }; - let POINTS = [{ x, y }]; + const POINTS = [{ x, y }]; if (distanceIsNumber && distance <= 0) { POINT = { x, y }; diff --git a/src/path/util/segment-quad-factory.ts b/src/path/util/segment-quad-factory.ts index dbd52b0..c6c3c5b 100644 --- a/src/path/util/segment-quad-factory.ts +++ b/src/path/util/segment-quad-factory.ts @@ -46,7 +46,7 @@ export function segmentQuadFactory( let cur: [number, number] = [x, y]; let t = 0; let POINT = { x: 0, y: 0 }; - let POINTS = [{ x, y }]; + const POINTS = [{ x, y }]; if (distanceIsNumber && distance <= 0) { POINT = { x, y };