mirror of
https://github.com/idrawjs/idraw
synced 2026-05-24 10:08:34 +00:00
feat: prefect @idraw/renderer
This commit is contained in:
parent
265c901b34
commit
6d4d3151c6
24 changed files with 113 additions and 752 deletions
|
|
@ -15,6 +15,13 @@ const renderer = new Renderer({
|
|||
// onlyRender: true,
|
||||
});
|
||||
|
||||
renderer.on('load', (e) => {
|
||||
console.log('load =', e)
|
||||
})
|
||||
renderer.on('loadComplete', (e) => {
|
||||
console.log('loadComplete =', e)
|
||||
})
|
||||
|
||||
renderer.on('drawFrame', (e) => {
|
||||
console.log('drawFrame =', e)
|
||||
})
|
||||
|
|
@ -25,6 +32,8 @@ renderer.on('drawFrameComplete', (e) => {
|
|||
renderer.render(canvas, data)
|
||||
renderer.render(canvas, { elements: data.elements.splice(1, 2) }, { forceUpdate: false })
|
||||
|
||||
console.log(renderer.getContext())
|
||||
|
||||
// setTimeout(() => {
|
||||
// renderer.render(canvas, { elements: data.elements.splice(1, 2) }, { forceUpdate: false })
|
||||
// }, 2000);
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
|
||||
const elementTypes = {
|
||||
'text': {}, // TODO
|
||||
'rect': {}, // TODO
|
||||
'image': {}, // TODO
|
||||
'svg': {}, // TODO
|
||||
'circle': {}, // TODO
|
||||
'html': {}, // TODO
|
||||
};
|
||||
|
||||
export const elementNames = Object.keys(elementTypes);
|
||||
|
||||
|
||||
// limitQbliqueAngle
|
||||
export const LIMIT_QBLIQUE_ANGLE = 15;
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
export enum Mode {
|
||||
NULL = 'null',
|
||||
SELECT_ELEMENT = 'select-element',
|
||||
SELECT_ELEMENT_LIST = 'select-element-list',
|
||||
SELECT_ELEMENT_WRAPPER_CONTROLLER = 'select-element-wrapper-controller',
|
||||
SELECT_AREA = 'select-area',
|
||||
}
|
||||
|
||||
export enum CursorStatus {
|
||||
DRAGGING = 'dragging',
|
||||
NULL = 'null',
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
import { TypeData, TypeContext, TypeElement, TypeElemDesc } from '@idraw/types';
|
||||
import util from '@idraw/util';
|
||||
import { drawContext } from './lib/draw';
|
||||
import { TypeLoadDataItem } from './lib/loader-event';
|
||||
import Loader from './lib/loader';
|
||||
import { RendererEvent } from './lib/renderer-event';
|
||||
import {
|
||||
|
|
@ -8,10 +9,10 @@ import {
|
|||
_drawFrame, _retainQueueOneItem
|
||||
} from './names';
|
||||
|
||||
const { Context } = util;
|
||||
const { requestAnimationFrame } = window;
|
||||
const { createUUID } = util.uuid;
|
||||
const { deepClone } = util.data;
|
||||
const { Context } = util;
|
||||
|
||||
type QueueItem = { data: TypeData };
|
||||
enum DrawStatus {
|
||||
|
|
@ -44,15 +45,15 @@ export default class Renderer extends RendererEvent {
|
|||
this[_loader] = new Loader({
|
||||
maxParallelNum: 6
|
||||
});
|
||||
this[_loader].on('load', (res) => {
|
||||
this[_loader].on('load', (res: TypeLoadDataItem) => {
|
||||
this[_drawFrame]();
|
||||
// console.log('Load: ', res);
|
||||
this.trigger('load', { element: res.element });
|
||||
});
|
||||
this[_loader].on('error', (res) => {
|
||||
console.log('Loader Error: ', res);
|
||||
this[_loader].on('error', (res: TypeLoadDataItem) => {
|
||||
this.trigger('error', { element: res.element, error: res.error });
|
||||
});
|
||||
this[_loader].on('complete', (res) => {
|
||||
// console.log('complete: ', res);
|
||||
this[_loader].on('complete', () => {
|
||||
this.trigger('loadComplete', { t: Date.now() })
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -104,6 +105,10 @@ export default class Renderer extends RendererEvent {
|
|||
this[_loader].load(data, changeResourceUUIDs || []);
|
||||
}
|
||||
|
||||
getContext(): TypeContext | null {
|
||||
return this[_ctx]
|
||||
}
|
||||
|
||||
private [_freeze]() {
|
||||
this[_status] = DrawStatus.FREEZE;
|
||||
}
|
||||
|
|
@ -147,10 +152,10 @@ export default class Renderer extends RendererEvent {
|
|||
} else {
|
||||
this[_status] = DrawStatus.FREE;
|
||||
}
|
||||
this.trigger('drawFrame', undefined)
|
||||
this.trigger('drawFrame', { t: Date.now() })
|
||||
|
||||
if (this[_loader].isComplete() === true && this[_queue].length === 1 && this[_status] === DrawStatus.FREE) {
|
||||
this.trigger('drawFrameComplete', undefined);
|
||||
this.trigger('drawFrameComplete', { t: Date.now() });
|
||||
this[_freeze]();
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,27 +0,0 @@
|
|||
import { TypeConfig, TypeConfigStrict } from '@idraw/types';
|
||||
import util from '@idraw/util';
|
||||
|
||||
const defaultConfig: TypeConfigStrict = {
|
||||
elementWrapper: {
|
||||
color: '#2ab6f1',
|
||||
lockColor: '#aaaaaa',
|
||||
controllerSize: 6,
|
||||
lineWidth: 1,
|
||||
lineDash: [4, 3],
|
||||
}
|
||||
};
|
||||
|
||||
function mergeConfig(config?: TypeConfig): TypeConfigStrict {
|
||||
const result = util.data.deepClone(defaultConfig);
|
||||
if (config) {
|
||||
if (config.elementWrapper) {
|
||||
result.elementWrapper = {...result.elementWrapper, ...config.elementWrapper};
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export {
|
||||
mergeConfig,
|
||||
};
|
||||
|
||||
|
|
@ -1,94 +0,0 @@
|
|||
import {
|
||||
TypeElement,
|
||||
TypeElemDesc,
|
||||
TypePoint,
|
||||
TypeData,
|
||||
TypeScreenData,
|
||||
} from '@idraw/types';
|
||||
|
||||
export type TypeCoreEventSelectBaseArg = {
|
||||
index: number | null;
|
||||
uuid: string | null;
|
||||
}
|
||||
|
||||
export type TypeCoreEventArgMap = {
|
||||
'error': any;
|
||||
'mouseOverScreen': TypePoint,
|
||||
'mouseLeaveScreen': void,
|
||||
'mouseOverElement': TypeCoreEventSelectBaseArg & { element: TypeElement<keyof TypeElemDesc> }
|
||||
'mouseLeaveElement': TypeCoreEventSelectBaseArg & { element: TypeElement<keyof TypeElemDesc> }
|
||||
'screenClickElement': TypeCoreEventSelectBaseArg & { element: TypeElement<keyof TypeElemDesc> }
|
||||
'screenDoubleClickElement': TypeCoreEventSelectBaseArg & { element: TypeElement<keyof TypeElemDesc> }
|
||||
'screenSelectElement': TypeCoreEventSelectBaseArg & { element: TypeElement<keyof TypeElemDesc> }
|
||||
'screenMoveElementStart': TypeCoreEventSelectBaseArg & TypePoint,
|
||||
'screenMoveElementEnd': TypeCoreEventSelectBaseArg & TypePoint,
|
||||
'screenChangeElement': TypeCoreEventSelectBaseArg & { width: number, height: number, angle: number};
|
||||
'changeData': TypeData;
|
||||
'changeScreen': TypeScreenData,
|
||||
'drawFrameComplete': void;
|
||||
'drawFrame': void;
|
||||
}
|
||||
|
||||
export interface TypeCoreEvent {
|
||||
on<T extends keyof TypeCoreEventArgMap >(key: T, callback: (p: TypeCoreEventArgMap[T]) => void): void
|
||||
off<T extends keyof TypeCoreEventArgMap >(key: T, callback: (p: TypeCoreEventArgMap[T]) => void): void
|
||||
trigger<T extends keyof TypeCoreEventArgMap >(key: T, p: TypeCoreEventArgMap[T]): void
|
||||
}
|
||||
|
||||
|
||||
export class CoreEvent implements TypeCoreEvent {
|
||||
|
||||
private _listeners: Map<string, ((p: any) => void)[]>;
|
||||
|
||||
constructor() {
|
||||
this._listeners = new Map();
|
||||
}
|
||||
|
||||
on<T extends keyof TypeCoreEventArgMap >(eventKey: T, callback: (p: TypeCoreEventArgMap[T]) => void) {
|
||||
if (this._listeners.has(eventKey)) {
|
||||
const callbacks = this._listeners.get(eventKey);
|
||||
callbacks?.push(callback);
|
||||
this._listeners.set(eventKey, callbacks || []);
|
||||
} else {
|
||||
this._listeners.set(eventKey, [callback]);
|
||||
}
|
||||
}
|
||||
|
||||
off<T extends keyof TypeCoreEventArgMap >(eventKey: T, callback: (p: TypeCoreEventArgMap[T]) => void) {
|
||||
if (this._listeners.has(eventKey)) {
|
||||
const callbacks = this._listeners.get(eventKey);
|
||||
if (Array.isArray(callbacks)) {
|
||||
for (let i = 0; i < callbacks?.length; i++) {
|
||||
if (callbacks[i] === callback) {
|
||||
callbacks.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
this._listeners.set(eventKey, callbacks || []);
|
||||
}
|
||||
}
|
||||
|
||||
trigger<T extends keyof TypeCoreEventArgMap >(eventKey: T, arg: TypeCoreEventArgMap[T]) {
|
||||
const callbacks = this._listeners.get(eventKey);
|
||||
if (Array.isArray(callbacks)) {
|
||||
callbacks.forEach((cb) => {
|
||||
cb(arg);
|
||||
});
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
has<T extends keyof TypeCoreEventArgMap> (name: string) {
|
||||
if (this._listeners.has(name)) {
|
||||
const list: ((p: TypeCoreEventArgMap[T]) => void)[] | undefined = this._listeners.get(name);
|
||||
if (Array.isArray(list) && list.length > 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -3,11 +3,9 @@ import {
|
|||
// TypeElemDesc,
|
||||
TypeElement,
|
||||
} from '@idraw/types';
|
||||
import util from '@idraw/util';
|
||||
import util from '@idraw/util';
|
||||
import { rotateElement } from './../transform';
|
||||
import is from './../is';
|
||||
|
||||
const { istype, color } = util;
|
||||
const { is, istype, color } = util;
|
||||
|
||||
export function clearContext(ctx: TypeContext) {
|
||||
// ctx.setFillStyle('rgb(0 0 0 / 100%)');
|
||||
|
|
@ -85,7 +83,7 @@ export function drawBoxBorder(
|
|||
r = r + bw / 2;
|
||||
}
|
||||
const { desc } = elem;
|
||||
if (desc.shadowColor !== undefined && util.color.isColorStr(desc.shadowColor)) {
|
||||
if (desc.shadowColor !== undefined && color.isColorStr(desc.shadowColor)) {
|
||||
ctx.setShadowColor(desc.shadowColor);
|
||||
}
|
||||
if (desc.shadowOffsetX !== undefined && is.number(desc.shadowOffsetX)) {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
import { TypeContext, TypeElement, } from '@idraw/types';
|
||||
// import util from '@idraw/util'
|
||||
import { rotateElement } from './../transform';
|
||||
// import is from './../is';
|
||||
import { clearContext } from './base';
|
||||
|
||||
export function drawCircle(ctx: TypeContext, elem: TypeElement<'circle'>) {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,8 @@ import util from '@idraw/util';
|
|||
import Loader from '../loader';
|
||||
import { clearContext, drawBox } from './base';
|
||||
import { rotateElement } from './../transform';
|
||||
import is from './../is';
|
||||
|
||||
const { is, color } = util;
|
||||
|
||||
export function drawText(
|
||||
ctx: TypeContext,
|
||||
|
|
@ -73,7 +74,7 @@ export function drawText(
|
|||
if (lines.length * fontHeight < elem.h) {
|
||||
_y += ((elem.h - lines.length * fontHeight) / 2);
|
||||
}
|
||||
if (desc.textShadowColor !== undefined && util.color.isColorStr(desc.textShadowColor)) {
|
||||
if (desc.textShadowColor !== undefined && color.isColorStr(desc.textShadowColor)) {
|
||||
ctx.setShadowColor(desc.textShadowColor);
|
||||
}
|
||||
if (desc.textShadowOffsetX !== undefined && is.number(desc.textShadowOffsetX)) {
|
||||
|
|
@ -98,7 +99,7 @@ export function drawText(
|
|||
}
|
||||
|
||||
// draw text stroke
|
||||
if (util.color.isColorStr(desc.strokeColor) && desc.strokeWidth !== undefined && desc.strokeWidth > 0) {
|
||||
if (color.isColorStr(desc.strokeColor) && desc.strokeWidth !== undefined && desc.strokeWidth > 0) {
|
||||
let _y = elem.y;
|
||||
if (lines.length * fontHeight < elem.h) {
|
||||
_y += ((elem.h - lines.length * fontHeight) / 2);
|
||||
|
|
|
|||
|
|
@ -1,5 +0,0 @@
|
|||
class ElementBase {
|
||||
constructor() {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
|
||||
class ElementController {
|
||||
// TODO
|
||||
}
|
||||
|
||||
export default ElementController;
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
import ElementController from './element-controller';
|
||||
|
||||
class ElementHub {
|
||||
|
||||
private _controllerMap: Map<string, ElementController> = new Map();
|
||||
|
||||
constructor() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
register(type: string, controller: ElementController) {
|
||||
if (this._controllerMap.has(type) !== true) {
|
||||
this._controllerMap.set(type, controller)
|
||||
}
|
||||
}
|
||||
|
||||
clear() {
|
||||
this._controllerMap.clear();
|
||||
}
|
||||
|
||||
getDrawActions() {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
|
||||
export default ElementHub;
|
||||
|
|
@ -1,12 +1,7 @@
|
|||
export * from './draw/index';
|
||||
export * from './check';
|
||||
export * from './config';
|
||||
export * from './core-event';
|
||||
export * from './diff';
|
||||
export * from './is';
|
||||
export * from './loader-event';
|
||||
export * from './loader';
|
||||
export * from './parse';
|
||||
export * from './temp';
|
||||
export * from './transform';
|
||||
export * from './value';
|
||||
|
|
|
|||
|
|
@ -1,19 +1,23 @@
|
|||
import { TypeElement, TypeElemDesc } from '@idraw/types';
|
||||
|
||||
export type TypeLoadDataItem = {
|
||||
uuid: string,
|
||||
type: 'image' | 'svg' | 'html',
|
||||
status: 'null' | 'loaded' | 'fail',
|
||||
content: null | HTMLImageElement | HTMLCanvasElement,
|
||||
elemW: number;
|
||||
elemH: number;
|
||||
source: string,
|
||||
element: TypeElement<keyof TypeElemDesc>
|
||||
error?: any,
|
||||
}
|
||||
|
||||
export type TypeLoadData = {
|
||||
[uuid: string]: {
|
||||
type: 'image' | 'svg' | 'html',
|
||||
status: 'null' | 'loaded' | 'fail',
|
||||
content: null | HTMLImageElement | HTMLCanvasElement,
|
||||
elemW: number;
|
||||
elemH: number;
|
||||
source: string,
|
||||
error?: any,
|
||||
}
|
||||
[uuid: string]: TypeLoadDataItem
|
||||
}
|
||||
|
||||
export type TypeLoaderEventArgMap = {
|
||||
'complete': undefined;
|
||||
'complete': void;
|
||||
'load': TypeLoadData[string];
|
||||
'error': TypeLoadData[string];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import { LoaderEvent, TypeLoadData, TypeLoaderEventArgMap } from './loader-event
|
|||
import { filterScript } from './../util/filter';
|
||||
|
||||
const { loadImage, loadSVG, loadHTML } = util.loader;
|
||||
const { deepClone } = util.data;
|
||||
|
||||
type Options = {
|
||||
maxParallelNum: number
|
||||
|
|
@ -175,12 +176,14 @@ export default class Loader {
|
|||
elemH = _elem.desc.height || elem.h;
|
||||
}
|
||||
return {
|
||||
uuid: elem.uuid,
|
||||
type: type,
|
||||
status: 'null',
|
||||
content: null,
|
||||
source,
|
||||
elemW,
|
||||
elemH,
|
||||
element: deepClone(elem),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -234,12 +237,14 @@ export default class Loader {
|
|||
const status = _loadAction();
|
||||
|
||||
this._storageLoadData[uuid] = {
|
||||
uuid,
|
||||
type: this._currentLoadData[uuid].type,
|
||||
status: 'loaded',
|
||||
content: image,
|
||||
source: this._currentLoadData[uuid].source,
|
||||
elemW: this._currentLoadData[uuid].elemW,
|
||||
elemH: this._currentLoadData[uuid].elemH,
|
||||
element: this._currentLoadData[uuid].element,
|
||||
};
|
||||
|
||||
if (loadUUIDList.length === 0 && uuids.length === 0 && status === true) {
|
||||
|
|
@ -247,12 +252,14 @@ export default class Loader {
|
|||
this._loadTask();
|
||||
}
|
||||
this._event.trigger('load', {
|
||||
uuid: this._storageLoadData[uuid]?.uuid,
|
||||
type: this._storageLoadData[uuid].type,
|
||||
status: this._storageLoadData[uuid].status,
|
||||
content: this._storageLoadData[uuid].content,
|
||||
source: this._storageLoadData[uuid].source,
|
||||
elemW: this._storageLoadData[uuid].elemW,
|
||||
elemH: this._storageLoadData[uuid].elemH,
|
||||
element: this._storageLoadData[uuid]?.element,
|
||||
});
|
||||
}).catch((err) => {
|
||||
console.warn(err);
|
||||
|
|
@ -262,6 +269,7 @@ export default class Loader {
|
|||
|
||||
if (this._currentLoadData[uuid]) {
|
||||
this._storageLoadData[uuid] = {
|
||||
uuid,
|
||||
type: this._currentLoadData[uuid]?.type,
|
||||
status: 'fail',
|
||||
content: null,
|
||||
|
|
@ -269,6 +277,7 @@ export default class Loader {
|
|||
source: this._currentLoadData[uuid]?.source,
|
||||
elemW: this._currentLoadData[uuid]?.elemW,
|
||||
elemH: this._currentLoadData[uuid]?.elemH,
|
||||
element: this._currentLoadData[uuid]?.element,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -279,12 +288,14 @@ export default class Loader {
|
|||
|
||||
if (this._currentLoadData[uuid]) {
|
||||
this._event.trigger('error', {
|
||||
uuid: uuid,
|
||||
type: this._storageLoadData[uuid]?.type,
|
||||
status: this._storageLoadData[uuid]?.status,
|
||||
content: this._storageLoadData[uuid]?.content,
|
||||
source: this._storageLoadData[uuid]?.source,
|
||||
elemW: this._storageLoadData[uuid]?.elemW,
|
||||
elemH: this._storageLoadData[uuid]?.elemH,
|
||||
element: this._storageLoadData[uuid]?.element,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,12 @@
|
|||
import { TypeElement, TypeElemDesc } from '@idraw/types';
|
||||
|
||||
|
||||
export type TypeRendererEventArgMap = {
|
||||
'drawFrame': void;
|
||||
'drawFrameComplete': void;
|
||||
'drawFrame': { t: number };
|
||||
'drawFrameComplete': { t: number };
|
||||
'load': { element: TypeElement<keyof TypeElemDesc> },
|
||||
'loadComplete': { t: number },
|
||||
'error': { element: TypeElement<keyof TypeElemDesc>, error: any }
|
||||
}
|
||||
|
||||
export interface TypeRendererEvent {
|
||||
|
|
|
|||
|
|
@ -1,182 +0,0 @@
|
|||
import {
|
||||
TypeElement, TypeElemDesc, TypeElementBase,
|
||||
} from '@idraw/types';
|
||||
import util from '@idraw/util';
|
||||
import {
|
||||
_board, _data, _opts, _config, _renderer, _element, _helper,
|
||||
_tempData, _draw, _coreEvent, _emitChangeScreen, _emitChangeData,
|
||||
} from './../names';
|
||||
import { diffElementResourceChange } from './../lib/diff';
|
||||
import Core from './../index';
|
||||
import { Mode } from './../constant/static';
|
||||
|
||||
// const { time } = util;
|
||||
const { deepClone } = util.data;
|
||||
const { createUUID } = util.uuid;
|
||||
|
||||
export function getSelectedElements(core: Core): TypeElement<keyof TypeElemDesc>[] {
|
||||
const elems: TypeElement<keyof TypeElemDesc>[] = [];
|
||||
let list: string[] = [];
|
||||
const uuid = core[_tempData].get('selectedUUID');
|
||||
if (typeof uuid === 'string' && uuid) {
|
||||
list.push(uuid);
|
||||
} else {
|
||||
list = core[_tempData].get('selectedUUIDList');
|
||||
}
|
||||
list.forEach((uuid) => {
|
||||
const index = core[_helper].getElementIndexByUUID(uuid);
|
||||
if (index !== null && index >= 0) {
|
||||
const elem = core[_data]?.elements[index];
|
||||
if (elem) elems.push(elem);
|
||||
}
|
||||
});
|
||||
return deepClone(elems);
|
||||
}
|
||||
|
||||
export function getElement(core: Core, uuid: string): TypeElement<keyof TypeElemDesc>|null {
|
||||
let elem: TypeElement<keyof TypeElemDesc>|null = null;
|
||||
const index = core[_helper].getElementIndexByUUID(uuid);
|
||||
if (index !== null && core[_data].elements[index]) {
|
||||
elem = deepClone(core[_data].elements[index]);
|
||||
}
|
||||
return elem;
|
||||
}
|
||||
|
||||
export function getElementByIndex(core: Core, index: number): TypeElement<keyof TypeElemDesc>|null {
|
||||
let elem: TypeElement<keyof TypeElemDesc>|null = null;
|
||||
if (index >=0 && core[_data].elements[index]) {
|
||||
elem = deepClone(core[_data].elements[index]);
|
||||
}
|
||||
return elem;
|
||||
}
|
||||
|
||||
export function updateElement(core: Core, elem: TypeElement<keyof TypeElemDesc>) {
|
||||
const _elem = deepClone(elem) as TypeElement<keyof TypeElemDesc>;
|
||||
const data = core[_data];
|
||||
const resourceChangeUUIDs: string[] = [];
|
||||
for (let i = 0; i < data.elements.length; i++) {
|
||||
if (_elem.uuid === data.elements[i]?.uuid) {
|
||||
const result = diffElementResourceChange(data.elements[i], _elem);
|
||||
if (typeof result === 'string') {
|
||||
resourceChangeUUIDs.push(result);
|
||||
}
|
||||
data.elements[i] = _elem;
|
||||
break;
|
||||
}
|
||||
}
|
||||
core[_emitChangeData]();
|
||||
core[_draw]({ resourceChangeUUIDs });
|
||||
}
|
||||
|
||||
export function selectElementByIndex(core: Core, index: number, opts?: { useMode?: boolean }): void {
|
||||
if (core[_tempData].get('onlyRender') === true) return;
|
||||
if (core[_data].elements[index]) {
|
||||
const uuid = core[_data].elements[index].uuid;
|
||||
if (opts?.useMode === true) {
|
||||
core[_tempData].set('mode', Mode.SELECT_ELEMENT);
|
||||
} else {
|
||||
core[_tempData].set('mode', Mode.NULL);
|
||||
}
|
||||
if (typeof uuid === 'string') {
|
||||
core[_tempData].set('selectedUUID', uuid);
|
||||
core[_tempData].set('selectedUUIDList', []);
|
||||
}
|
||||
core[_draw]();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export function selectElement(core: Core, uuid: string, opts?: { useMode?: boolean }): void {
|
||||
if (core[_tempData].get('onlyRender') === true) return;
|
||||
const index = core[_helper].getElementIndexByUUID(uuid);
|
||||
if (typeof index === 'number' && index >= 0) {
|
||||
core.selectElementByIndex(index, opts);
|
||||
}
|
||||
}
|
||||
|
||||
export function moveUpElement(core: Core, uuid: string): void {
|
||||
// if (this[_onlyRender] === true) return;
|
||||
const index = core[_helper].getElementIndexByUUID(uuid);
|
||||
if (typeof index === 'number' && index >= 0 && index < core[_data].elements.length - 1) {
|
||||
const temp = core[_data].elements[index];
|
||||
core[_data].elements[index] = core[_data].elements[index + 1];
|
||||
core[_data].elements[index + 1] = temp;
|
||||
}
|
||||
core[_emitChangeData]();
|
||||
core[_draw]();
|
||||
}
|
||||
|
||||
export function moveDownElement(core: Core, uuid: string): void {
|
||||
// if (this[_onlyRender] === true) return;
|
||||
const index = core[_helper].getElementIndexByUUID(uuid);
|
||||
if (typeof index === 'number' && index > 0 && index < core[_data].elements.length) {
|
||||
const temp = core[_data].elements[index];
|
||||
core[_data].elements[index] = core[_data].elements[index - 1];
|
||||
core[_data].elements[index - 1] = temp;
|
||||
}
|
||||
core[_emitChangeData]();
|
||||
core[_draw]();
|
||||
}
|
||||
|
||||
|
||||
export function addElement(core: Core, elem: TypeElementBase<keyof TypeElemDesc>): string | null {
|
||||
// if (this[_onlyRender] === true) return null;
|
||||
const _elem = deepClone(elem);
|
||||
_elem.uuid = createUUID();
|
||||
core[_data].elements.push(_elem);
|
||||
core[_emitChangeData]();
|
||||
core[_draw]();
|
||||
return _elem.uuid;
|
||||
}
|
||||
|
||||
export function deleteElement(core: Core, uuid: string) {
|
||||
// if (this[_onlyRender] === true) return;
|
||||
const index = core[_element].getElementIndex(core[_data], uuid);
|
||||
if (index >= 0) {
|
||||
core[_data].elements.splice(index, 1);
|
||||
core[_emitChangeData]();
|
||||
core[_draw]();
|
||||
}
|
||||
}
|
||||
|
||||
export function insertElementBefore(core: Core, elem: TypeElementBase<keyof TypeElemDesc>, beforeUUID: string) {
|
||||
const index = core[_helper].getElementIndexByUUID(beforeUUID);
|
||||
if (index !== null) {
|
||||
return core.insertElementBeforeIndex(elem, index);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
export function insertElementBeforeIndex(core: Core, elem: TypeElementBase<keyof TypeElemDesc>, index: number) {
|
||||
const _elem = deepClone(elem);
|
||||
_elem.uuid = createUUID();
|
||||
if (index >= 0) {
|
||||
core[_data].elements.splice(index, 0, _elem);
|
||||
core[_emitChangeData]();
|
||||
core[_draw]();
|
||||
return _elem.uuid;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
export function insertElementAfter(core: Core, elem: TypeElementBase<keyof TypeElemDesc>, beforeUUID: string) {
|
||||
const index = core[_helper].getElementIndexByUUID(beforeUUID);
|
||||
if (index !== null) {
|
||||
return core.insertElementAfterIndex(elem, index);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export function insertElementAfterIndex(core: Core, elem: TypeElementBase<keyof TypeElemDesc>, index: number) {
|
||||
const _elem = deepClone(elem);
|
||||
_elem.uuid = createUUID();
|
||||
if (index >= 0) {
|
||||
core[_data].elements.splice(index + 1, 0, _elem);
|
||||
core[_emitChangeData]();
|
||||
core[_draw]();
|
||||
return _elem.uuid;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
@ -1,298 +0,0 @@
|
|||
import { TypePoint, TypeHelperWrapperControllerDirection } from '@idraw/types';
|
||||
import util from '@idraw/util';
|
||||
import Core from './../index';
|
||||
import {
|
||||
_board, _data, _opts, _config, _renderer, _element, _helper,
|
||||
_tempData, _draw, _coreEvent, _mapper,
|
||||
_emitChangeScreen, _emitChangeData,
|
||||
} from './../names';
|
||||
import { Mode, CursorStatus } from './../constant/static';
|
||||
|
||||
const { time } = util;
|
||||
const { deepClone } = util.data;
|
||||
|
||||
export function initEvent(core: Core): void {
|
||||
|
||||
if (core[_tempData].get('hasInited') === true) {
|
||||
return;
|
||||
}
|
||||
|
||||
core[_board].on('hover', time.throttle(handleHover(core), 32));
|
||||
core[_board].on('leave', time.throttle(handleLeave(core), 32));
|
||||
core[_board].on('point', time.throttle(handleClick(core), 16));
|
||||
core[_board].on('doubleClick', handleDoubleClick(core));
|
||||
if (core[_tempData].get('onlyRender') === true) {
|
||||
return;
|
||||
}
|
||||
core[_board].on('point', handlePoint(core));
|
||||
core[_board].on('moveStart', handleMoveStart(core));
|
||||
core[_board].on('move', time.throttle(handleMove(core), 16));
|
||||
core[_board].on('moveEnd', handleMoveEnd(core));
|
||||
|
||||
core[_renderer].on('drawFrame', () => {
|
||||
core[_coreEvent].trigger('drawFrame', undefined);
|
||||
});
|
||||
core[_renderer].on('drawFrameComplete', () => {
|
||||
core[_coreEvent].trigger('drawFrameComplete', undefined);
|
||||
})
|
||||
|
||||
core[_tempData].set('hasInited', true);
|
||||
}
|
||||
|
||||
|
||||
function handleDoubleClick(core: Core) {
|
||||
return function ( point: TypePoint) {
|
||||
const [index, uuid] = core[_element].isPointInElement(point, core[_data]);
|
||||
if (index >= 0 && uuid) {
|
||||
const elem = deepClone(core[_data].elements?.[index]);
|
||||
if (elem?.operation?.invisible !== true) {
|
||||
core[_coreEvent].trigger(
|
||||
'screenDoubleClickElement',
|
||||
{ index, uuid, element: deepClone(core[_data].elements?.[index])}
|
||||
);
|
||||
}
|
||||
}
|
||||
core[_draw]();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function handlePoint(core: Core) {
|
||||
return function(point: TypePoint): void {
|
||||
if (!core[_mapper].isEffectivePoint(point)) {
|
||||
return;
|
||||
}
|
||||
if (core[_helper].isPointInElementList(point, core[_data])) {
|
||||
// Coontroll Element-List
|
||||
core[_tempData].set('mode', Mode.SELECT_ELEMENT_LIST);
|
||||
} else {
|
||||
const {
|
||||
uuid, selectedControllerDirection
|
||||
} = core[_helper].isPointInElementWrapperController(point, core[_data]);
|
||||
if (uuid && selectedControllerDirection) {
|
||||
// Controll Element-Wrapper
|
||||
core[_tempData].set('mode', Mode.SELECT_ELEMENT_WRAPPER_CONTROLLER);
|
||||
core[_tempData].set('selectedControllerDirection', selectedControllerDirection);
|
||||
core[_tempData].set('selectedUUID', uuid);
|
||||
} else {
|
||||
const [index, uuid] = core[_element].isPointInElement(point, core[_data]);
|
||||
if (index >= 0 && core[_data].elements[index]?.operation?.invisible !== true) {
|
||||
// Controll Element
|
||||
core.selectElementByIndex(index, { useMode: true });
|
||||
if (typeof uuid === 'string' && core[_coreEvent].has('screenSelectElement')) {
|
||||
core[_coreEvent].trigger(
|
||||
'screenSelectElement',
|
||||
{ index, uuid, element: deepClone(core[_data].elements?.[index])}
|
||||
);
|
||||
core[_emitChangeScreen]();
|
||||
}
|
||||
core[_tempData].set('mode', Mode.SELECT_ELEMENT);
|
||||
} else {
|
||||
// Controll Area
|
||||
core[_tempData].set('selectedUUIDList', []);
|
||||
core[_tempData].set('selectedUUID', null);
|
||||
core[_tempData].set('mode', Mode.SELECT_AREA);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
core[_draw]();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function handleClick(core: Core) {
|
||||
return function(point: TypePoint): void {
|
||||
const [index, uuid] = core[_element].isPointInElement(point, core[_data]);
|
||||
if (index >= 0 && uuid) {
|
||||
core[_coreEvent].trigger(
|
||||
'screenClickElement',
|
||||
{ index, uuid, element: deepClone(core[_data].elements?.[index])}
|
||||
);
|
||||
}
|
||||
core[_draw]();
|
||||
}
|
||||
}
|
||||
|
||||
function handleMoveStart(core: Core) {
|
||||
return function(point: TypePoint): void {
|
||||
core[_tempData].set('prevPoint', point);
|
||||
const uuid = core[_tempData].get('selectedUUID');
|
||||
|
||||
if (core[_tempData].get('mode') === Mode.SELECT_ELEMENT_LIST) {
|
||||
// TODO
|
||||
} else if (core[_tempData].get('mode') === Mode.SELECT_ELEMENT) {
|
||||
if (typeof uuid === 'string' && core[_coreEvent].has('screenMoveElementStart')) {
|
||||
core[_coreEvent].trigger('screenMoveElementStart', {
|
||||
index: core[_element].getElementIndex(core[_data], uuid),
|
||||
uuid,
|
||||
x: point.x,
|
||||
y: point.y
|
||||
});
|
||||
}
|
||||
} else if (core[_tempData].get('mode') === Mode.SELECT_AREA) {
|
||||
core[_helper].startSelectArea(point);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function handleMove(core: Core) {
|
||||
return function(point: TypePoint): void {
|
||||
if (core[_tempData].get('mode') === Mode.SELECT_ELEMENT_LIST) {
|
||||
dragElements(core, core[_tempData].get('selectedUUIDList'), point, core[_tempData].get('prevPoint'));
|
||||
core[_draw]();
|
||||
core[_tempData].set('cursorStatus', CursorStatus.DRAGGING);
|
||||
} else if (typeof core[_tempData].get('selectedUUID') === 'string') {
|
||||
if (core[_tempData].get('mode') === Mode.SELECT_ELEMENT) {
|
||||
dragElements(core, [core[_tempData].get('selectedUUID') as string], point, core[_tempData].get('prevPoint'));
|
||||
core[_draw]();
|
||||
core[_tempData].set('cursorStatus', CursorStatus.DRAGGING);
|
||||
} else if (core[_tempData].get('mode') === Mode.SELECT_ELEMENT_WRAPPER_CONTROLLER && core[_tempData].get('selectedControllerDirection')) {
|
||||
transfromElement(
|
||||
core,
|
||||
core[_tempData].get('selectedUUID') as string,
|
||||
point,
|
||||
core[_tempData].get('prevPoint'),
|
||||
core[_tempData].get('selectedControllerDirection') as TypeHelperWrapperControllerDirection
|
||||
);
|
||||
core[_tempData].set('cursorStatus', CursorStatus.DRAGGING)
|
||||
}
|
||||
} else if (core[_tempData].get('mode') === Mode.SELECT_AREA) {
|
||||
core[_helper].changeSelectArea(point);
|
||||
core[_draw]();
|
||||
}
|
||||
core[_tempData].set('prevPoint', point)
|
||||
}
|
||||
}
|
||||
|
||||
function dragElements(core: Core, uuids: string[], point: TypePoint, prevPoint: TypePoint|null): void {
|
||||
if (!prevPoint) {
|
||||
return;
|
||||
}
|
||||
uuids.forEach((uuid) => {
|
||||
const idx = core[_helper].getElementIndexByUUID(uuid);
|
||||
if (idx === null) return;
|
||||
const elem = core[_data].elements[idx];
|
||||
if (elem?.operation?.lock !== true && elem?.operation?.invisible !== true) {
|
||||
core[_element].dragElement(core[_data], uuid, point, prevPoint, core[_board].getContext().getTransform().scale);
|
||||
}
|
||||
});
|
||||
core[_draw]();
|
||||
}
|
||||
|
||||
|
||||
function handleMoveEnd(core: Core) {
|
||||
return function (point: TypePoint): void {
|
||||
const uuid = core[_tempData].get('selectedUUID');
|
||||
if (typeof uuid === 'string') {
|
||||
const index = core[_element].getElementIndex(core[_data], uuid);
|
||||
const elem = core[_data].elements[index];
|
||||
if (elem) {
|
||||
if (core[_coreEvent].has('screenMoveElementEnd')) {
|
||||
core[_coreEvent].trigger('screenMoveElementEnd', {
|
||||
index,
|
||||
uuid,
|
||||
x: point.x,
|
||||
y: point.y
|
||||
});
|
||||
}
|
||||
if (core[_coreEvent].has('screenChangeElement')) {
|
||||
core[_coreEvent].trigger('screenChangeElement', {
|
||||
index,
|
||||
uuid,
|
||||
width: elem.w,
|
||||
height: elem.h,
|
||||
angle: elem.angle || 0
|
||||
});
|
||||
}
|
||||
core[_emitChangeData]();
|
||||
}
|
||||
} else if (core[_tempData].get('mode') === Mode.SELECT_AREA) {
|
||||
const uuids = core[_helper].calcSelectedElements(core[_data]);
|
||||
if (uuids.length > 0) {
|
||||
core[_tempData].set('selectedUUIDList', uuids);
|
||||
core[_tempData].set('selectedUUID', null);
|
||||
} else {
|
||||
core[_tempData].set('mode', Mode.NULL);
|
||||
}
|
||||
core[_helper].clearSelectedArea();
|
||||
core[_draw]();
|
||||
}
|
||||
|
||||
if (core[_tempData].get('mode') !== Mode.SELECT_ELEMENT) {
|
||||
core[_tempData].set('selectedUUID', null);
|
||||
}
|
||||
core[_tempData].set('cursorStatus', CursorStatus.NULL);
|
||||
core[_tempData].set('mode', Mode.NULL);
|
||||
}
|
||||
}
|
||||
|
||||
function handleHover(core: Core) {
|
||||
return function (point: TypePoint): void {
|
||||
let isMouseOverElement: boolean = false;
|
||||
|
||||
if (core[_tempData].get('mode') === Mode.SELECT_AREA) {
|
||||
if (core[_tempData].get('onlyRender') !== true) core[_board].resetCursor();
|
||||
} else if (core[_tempData].get('cursorStatus') === CursorStatus.NULL) {
|
||||
const { cursor, elementUUID } = core[_mapper].judgePointCursor(point, core[_data]);
|
||||
if (core[_tempData].get('onlyRender') !== true) core[_board].setCursor(cursor);
|
||||
if (elementUUID) {
|
||||
const index: number | null = core[_helper].getElementIndexByUUID(elementUUID);
|
||||
if (index !== null && index >= 0) {
|
||||
const elem = core[_data].elements[index];
|
||||
if (elem?.operation?.lock === true || elem?.operation?.invisible === true) {
|
||||
core[_board].resetCursor();
|
||||
return;
|
||||
}
|
||||
if (core[_tempData].get('hoverUUID') !== elem.uuid) {
|
||||
const preIndex = core[_helper].getElementIndexByUUID(core[_tempData].get('hoverUUID') || '');
|
||||
if (preIndex !== null && core[_data].elements[preIndex]) {
|
||||
core[_coreEvent].trigger('mouseLeaveElement', {
|
||||
uuid: core[_tempData].get('hoverUUID'),
|
||||
index: preIndex,
|
||||
element: core[_data].elements[preIndex]
|
||||
});
|
||||
}
|
||||
}
|
||||
if (elem) {
|
||||
core[_coreEvent].trigger('mouseOverElement', { uuid: elem.uuid, index, element: elem, });
|
||||
core[_tempData].set('hoverUUID', elem.uuid);
|
||||
isMouseOverElement = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isMouseOverElement !== true && core[_tempData].get('hoverUUID') !== null) {
|
||||
const uuid = core[_tempData].get('hoverUUID');
|
||||
const index: number | null = core[_helper].getElementIndexByUUID(uuid || '');
|
||||
if (index !== null) core[_coreEvent].trigger('mouseLeaveElement', { uuid, index, element: core[_data].elements[index] })
|
||||
core[_tempData].set('hoverUUID', null);
|
||||
}
|
||||
if (core[_coreEvent].has('mouseOverScreen')) core[_coreEvent].trigger('mouseOverScreen', point);
|
||||
}
|
||||
}
|
||||
|
||||
function handleLeave(core: Core) {
|
||||
return function(): void {
|
||||
if (core[_coreEvent].has('mouseLeaveScreen')) {
|
||||
core[_coreEvent].trigger('mouseLeaveScreen', undefined);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function transfromElement(
|
||||
core: Core,
|
||||
uuid: string, point: TypePoint, prevPoint: TypePoint|null, direction: TypeHelperWrapperControllerDirection
|
||||
): null | {
|
||||
width: number,
|
||||
height: number,
|
||||
angle: number,
|
||||
} {
|
||||
if (!prevPoint) {
|
||||
return null;
|
||||
}
|
||||
const result = core[_element].transformElement(core[_data], uuid, point, prevPoint, core[_board].getContext().getTransform().scale, direction);
|
||||
core[_draw]();
|
||||
return result;
|
||||
}
|
||||
|
|
@ -8,4 +8,5 @@ export * from './lib/config';
|
|||
export * from './lib/core';
|
||||
export * from './lib/screen';
|
||||
export * from './lib/device';
|
||||
export * from './lib/plugin';
|
||||
export * from './lib/plugin';
|
||||
export * from './lib/common';
|
||||
38
packages/types/src/lib/common.ts
Normal file
38
packages/types/src/lib/common.ts
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
type TypeIs = {
|
||||
x: (value: any) => boolean,
|
||||
y: (value: any) => boolean,
|
||||
w: (value: any) => boolean,
|
||||
h: (value: any) => boolean,
|
||||
angle: (value: any) => boolean,
|
||||
number: (value: any) => boolean,
|
||||
borderWidth: (value: any) => boolean,
|
||||
borderRadius: (value: any) => boolean,
|
||||
color: (value: any) => boolean,
|
||||
imageSrc: (value: any) => boolean,
|
||||
imageURL: (value: any) => boolean,
|
||||
imageBase64: (value: any) => boolean,
|
||||
svg: (value: any) => boolean,
|
||||
html: (value: any) => boolean,
|
||||
text: (value: any) => boolean,
|
||||
fontSize: (value: any) => boolean,
|
||||
fontWeight: (value: any) => boolean,
|
||||
lineHeight: (value: any) => boolean,
|
||||
textAlign: (value: any) => boolean,
|
||||
fontFamily: (value: any) => boolean,
|
||||
strokeWidth: (value: any) => boolean,
|
||||
}
|
||||
|
||||
type TypeCheck = {
|
||||
attrs: (value: any) => boolean,
|
||||
rectDesc: (value: any) => boolean,
|
||||
circleDesc: (value: any) => boolean,
|
||||
imageDesc: (value: any) => boolean,
|
||||
svgDesc: (value: any) => boolean,
|
||||
htmlDesc: (value: any) => boolean,
|
||||
textDesc: (value: any) => boolean,
|
||||
}
|
||||
|
||||
export {
|
||||
TypeIs,
|
||||
TypeCheck,
|
||||
}
|
||||
|
|
@ -8,6 +8,9 @@ const types = {
|
|||
uuid: 'Object',
|
||||
istype: 'Object',
|
||||
data: 'Object',
|
||||
is: 'Object',
|
||||
check: 'Object',
|
||||
Context: 'Function',
|
||||
}
|
||||
|
||||
function getType (data: any): string {
|
||||
|
|
|
|||
|
|
@ -6,8 +6,12 @@ import { deepClone } from './lib/data';
|
|||
import istype from './lib/istype';
|
||||
import { loadImage, loadSVG, loadHTML } from './lib/loader';
|
||||
import Context from './lib/context';
|
||||
import is from './lib/is';
|
||||
import check from './lib/check';
|
||||
|
||||
export default {
|
||||
is,
|
||||
check,
|
||||
time: {
|
||||
delay,
|
||||
compose,
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
|
||||
import { TypeElementAttrs } from '@idraw/types';
|
||||
// import { TypeElementAttrs } from '@idraw/types';
|
||||
import is from './is';
|
||||
|
||||
|
||||
function attrs(
|
||||
attrs: TypeElementAttrs
|
||||
attrs: any
|
||||
): boolean {
|
||||
const { x, y, w, h, angle } = attrs;
|
||||
if (!(is.x(x) && is.y(y) && is.w(w) && is.h(h) && is.angle(angle))) {
|
||||
|
|
@ -146,18 +145,5 @@ const check = {
|
|||
htmlDesc,
|
||||
};
|
||||
|
||||
type TypeCheck = {
|
||||
attrs: (value: any) => boolean,
|
||||
rectDesc: (value: any) => boolean,
|
||||
circleDesc: (value: any) => boolean,
|
||||
imageDesc: (value: any) => boolean,
|
||||
svgDesc: (value: any) => boolean,
|
||||
htmlDesc: (value: any) => boolean,
|
||||
textDesc: (value: any) => boolean,
|
||||
}
|
||||
|
||||
export {
|
||||
TypeCheck
|
||||
};
|
||||
|
||||
export default check;
|
||||
|
|
@ -1,8 +1,4 @@
|
|||
import util from "@idraw/util";
|
||||
|
||||
const { isColorStr } = util.color;
|
||||
|
||||
|
||||
import { isColorStr } from './color';
|
||||
|
||||
function number(value: any) {
|
||||
return (typeof value === 'number' && (value > 0 || value <= 0));
|
||||
|
|
@ -97,7 +93,7 @@ function fontWeight(value: any) {
|
|||
return ['bold'].includes(value);
|
||||
}
|
||||
|
||||
const is: TypeIs = {
|
||||
const is = {
|
||||
x, y, w, h, angle, number,
|
||||
borderWidth, borderRadius, color,
|
||||
imageSrc, imageURL, imageBase64, svg, html,
|
||||
|
|
@ -105,33 +101,5 @@ const is: TypeIs = {
|
|||
strokeWidth,
|
||||
};
|
||||
|
||||
type TypeIs = {
|
||||
x: (value: any) => boolean,
|
||||
y: (value: any) => boolean,
|
||||
w: (value: any) => boolean,
|
||||
h: (value: any) => boolean,
|
||||
angle: (value: any) => boolean,
|
||||
number: (value: any) => boolean,
|
||||
borderWidth: (value: any) => boolean,
|
||||
borderRadius: (value: any) => boolean,
|
||||
color: (value: any) => boolean,
|
||||
imageSrc: (value: any) => boolean,
|
||||
imageURL: (value: any) => boolean,
|
||||
imageBase64: (value: any) => boolean,
|
||||
svg: (value: any) => boolean,
|
||||
html: (value: any) => boolean,
|
||||
text: (value: any) => boolean,
|
||||
fontSize: (value: any) => boolean,
|
||||
fontWeight: (value: any) => boolean,
|
||||
lineHeight: (value: any) => boolean,
|
||||
textAlign: (value: any) => boolean,
|
||||
fontFamily: (value: any) => boolean,
|
||||
strokeWidth: (value: any) => boolean,
|
||||
}
|
||||
|
||||
export default is;
|
||||
|
||||
|
||||
export {
|
||||
TypeIs,
|
||||
};
|
||||
Loading…
Reference in a new issue