mirror of
https://github.com/motajs/template.git
synced 2026-11-12 14:04:31 +08:00
init: 2.B
This commit is contained in:
commit
6bf32174d8
610 files changed
+151444
No files matched your search
@@ -0,0 +1,121 @@
|
||||
import {
|
||||
ComponentOptionsMixin,
|
||||
defineComponent,
|
||||
DefineComponent,
|
||||
h,
|
||||
ReservedProps,
|
||||
VNodeProps
|
||||
} from 'vue';
|
||||
import EventEmitter from 'eventemitter3';
|
||||
import {
|
||||
BaseProps,
|
||||
BezierProps,
|
||||
CirclesProps,
|
||||
CommentProps,
|
||||
ConatinerCustomProps,
|
||||
ContainerProps,
|
||||
CustomProps,
|
||||
EllipseProps,
|
||||
ImageProps,
|
||||
LineProps,
|
||||
PathProps,
|
||||
QuadraticProps,
|
||||
RectProps,
|
||||
RectRProps,
|
||||
ShaderProps,
|
||||
SpriteProps,
|
||||
TextProps
|
||||
} from './props';
|
||||
import {
|
||||
ERenderItemEvent,
|
||||
RenderItem,
|
||||
ESpriteEvent,
|
||||
EContainerEvent,
|
||||
EShaderEvent
|
||||
} from '@motajs/render-core';
|
||||
import {
|
||||
EImageEvent,
|
||||
ETextEvent,
|
||||
EGraphicItemEvent
|
||||
} from '@motajs/render-elements';
|
||||
|
||||
export type WrapEventEmitterEvents<T extends EventEmitter.ValidEventTypes> =
|
||||
T extends string | symbol
|
||||
? T
|
||||
: {
|
||||
[P in keyof T]: T[P] extends any[]
|
||||
? (...args: T[P]) => void
|
||||
: (...args: any[]) => void;
|
||||
};
|
||||
|
||||
type MappingEvent<E extends ERenderItemEvent> = {
|
||||
[P in keyof WrapEventEmitterEvents<E> as P extends string
|
||||
? `on${Capitalize<P>}`
|
||||
: never]?: WrapEventEmitterEvents<E>[P];
|
||||
};
|
||||
|
||||
type _Define<P extends BaseProps, E extends ERenderItemEvent> = DefineComponent<
|
||||
P,
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
ComponentOptionsMixin,
|
||||
ComponentOptionsMixin,
|
||||
WrapEventEmitterEvents<E>,
|
||||
Exclude<keyof WrapEventEmitterEvents<E>, number | symbol>,
|
||||
VNodeProps,
|
||||
Readonly<P & MappingEvent<E>>
|
||||
>;
|
||||
|
||||
export type TagDefine<T extends object, E extends ERenderItemEvent> = T &
|
||||
MappingEvent<E> &
|
||||
ReservedProps;
|
||||
|
||||
declare module 'vue/jsx-runtime' {
|
||||
namespace JSX {
|
||||
export interface IntrinsicElements {
|
||||
sprite: TagDefine<SpriteProps, ESpriteEvent>;
|
||||
container: TagDefine<ContainerProps, EContainerEvent>;
|
||||
'container-custom': TagDefine<
|
||||
ConatinerCustomProps,
|
||||
EContainerEvent
|
||||
>;
|
||||
shader: TagDefine<ShaderProps, EShaderEvent>;
|
||||
text: TagDefine<TextProps, ETextEvent>;
|
||||
image: TagDefine<ImageProps, EImageEvent>;
|
||||
comment: TagDefine<CommentProps, ERenderItemEvent>;
|
||||
custom: TagDefine<CustomProps, ERenderItemEvent>;
|
||||
'g-rect': TagDefine<RectProps, EGraphicItemEvent>;
|
||||
'g-circle': TagDefine<CirclesProps, EGraphicItemEvent>;
|
||||
'g-ellipse': TagDefine<EllipseProps, EGraphicItemEvent>;
|
||||
'g-line': TagDefine<LineProps, EGraphicItemEvent>;
|
||||
'g-bezier': TagDefine<BezierProps, EGraphicItemEvent>;
|
||||
'g-quad': TagDefine<QuadraticProps, EGraphicItemEvent>;
|
||||
'g-path': TagDefine<PathProps, EGraphicItemEvent>;
|
||||
'g-rectr': TagDefine<RectRProps, EGraphicItemEvent>;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export interface InstancedElementProp {
|
||||
item: RenderItem;
|
||||
}
|
||||
|
||||
export function wrapInstancedComponent<
|
||||
P extends BaseProps = BaseProps,
|
||||
E extends ERenderItemEvent = ERenderItemEvent,
|
||||
C extends RenderItem = RenderItem
|
||||
>(onCreate: (props: P) => C): _Define<P, E> {
|
||||
const Com = defineComponent((props, ctx) => {
|
||||
return () => {
|
||||
const p = {
|
||||
...props,
|
||||
...ctx.attrs,
|
||||
_item: onCreate
|
||||
};
|
||||
return h('custom', p, ctx.slots);
|
||||
};
|
||||
});
|
||||
return Com as _Define<P, E>;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import { ERenderItemEvent } from '@motajs/render-core';
|
||||
import { TagDefine } from './elements';
|
||||
import { BaseProps } from './props';
|
||||
|
||||
export type DefaultProps<
|
||||
P extends BaseProps = BaseProps,
|
||||
E extends ERenderItemEvent = ERenderItemEvent
|
||||
> = TagDefine<P, E>;
|
||||
|
||||
export * from './elements';
|
||||
export * from './map';
|
||||
export * from './props';
|
||||
export * from './renderer';
|
||||
export * from './use';
|
||||
@@ -0,0 +1,204 @@
|
||||
import { logger } from '@motajs/common';
|
||||
import {
|
||||
ERenderItemEvent,
|
||||
RenderItem,
|
||||
RenderItemPosition,
|
||||
Container,
|
||||
ContainerCustom,
|
||||
MotaRenderer,
|
||||
Sprite,
|
||||
Shader
|
||||
} from '@motajs/render-core';
|
||||
import {
|
||||
Comment,
|
||||
ETextEvent,
|
||||
Image,
|
||||
Text,
|
||||
BezierCurve,
|
||||
Circle,
|
||||
Ellipse,
|
||||
Line,
|
||||
Path,
|
||||
QuadraticCurve,
|
||||
Rect,
|
||||
RectR
|
||||
} from '@motajs/render-elements';
|
||||
import { ElementNamespace, VNodeProps } from 'vue';
|
||||
|
||||
type OnItemCreate<
|
||||
E extends ERenderItemEvent = ERenderItemEvent,
|
||||
T extends RenderItem<E> = RenderItem<E>
|
||||
> = (
|
||||
namespace?: ElementNamespace,
|
||||
isCustomizedBuiltIn?: string,
|
||||
vnodeProps?: (VNodeProps & { [key: string]: any }) | null
|
||||
) => T;
|
||||
|
||||
class RenderTagMap {
|
||||
private map: Map<string, OnItemCreate> = new Map();
|
||||
|
||||
/**
|
||||
* 注册一个标签,每个标签对应一类元素,重复注册会覆盖之前的
|
||||
* @param tag 标签名称
|
||||
* @param ele 对应的元素类或其构造器
|
||||
*/
|
||||
register<E extends ERenderItemEvent, T extends RenderItem<E>>(
|
||||
tag: string,
|
||||
onCreate: OnItemCreate<E, T>
|
||||
) {
|
||||
if (this.map.has(tag)) {
|
||||
logger.warn(34, tag);
|
||||
}
|
||||
this.map.set(tag, onCreate);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取一个标签对应的元素构造器
|
||||
* @param tag 标签名
|
||||
*/
|
||||
get<E extends ERenderItemEvent, T extends RenderItem<E>>(
|
||||
tag: string
|
||||
): OnItemCreate<E, T> | undefined {
|
||||
return this.map.get(tag) as OnItemCreate<E, T>;
|
||||
}
|
||||
}
|
||||
|
||||
export const tagMap = new RenderTagMap();
|
||||
|
||||
export const standardElement = (
|
||||
Item: new (
|
||||
type: RenderItemPosition,
|
||||
cache?: boolean,
|
||||
fall?: boolean
|
||||
) => RenderItem
|
||||
) => {
|
||||
return (_0: any, _1: any, props?: any) => {
|
||||
if (!props) return new Item('static');
|
||||
else {
|
||||
const {
|
||||
type = 'static',
|
||||
cache = true,
|
||||
fall = false,
|
||||
nocache = false
|
||||
} = props;
|
||||
return new Item(type, cache && !nocache, fall);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export const standardElementNoCache = (
|
||||
Item: new (
|
||||
type: RenderItemPosition,
|
||||
cache?: boolean,
|
||||
fall?: boolean
|
||||
) => RenderItem
|
||||
) => {
|
||||
return (_0: any, _1: any, props?: any) => {
|
||||
if (!props) return new Item('static');
|
||||
else {
|
||||
const {
|
||||
type = 'static',
|
||||
cache = false,
|
||||
fall = false,
|
||||
nocache = true
|
||||
} = props;
|
||||
return new Item(type, cache && !nocache, fall);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const enum ElementState {
|
||||
None = 0,
|
||||
Cache = 1,
|
||||
Fall = 2
|
||||
}
|
||||
|
||||
/**
|
||||
* standardElementFor
|
||||
*/
|
||||
const _se = (
|
||||
Item: new (
|
||||
type: RenderItemPosition,
|
||||
cache?: boolean,
|
||||
fall?: boolean
|
||||
) => RenderItem,
|
||||
position: RenderItemPosition,
|
||||
state: ElementState
|
||||
) => {
|
||||
const defaultCache = !!(state & ElementState.Cache);
|
||||
const defautFall = !!(state & ElementState.Fall);
|
||||
|
||||
return (_0: any, _1: any, props?: any) => {
|
||||
if (!props) return new Item('absolute');
|
||||
else {
|
||||
const {
|
||||
type = position,
|
||||
cache = defaultCache,
|
||||
fall = defautFall,
|
||||
nocache = !defaultCache
|
||||
} = props;
|
||||
return new Item(type, cache && !nocache, fall);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Default elements
|
||||
tagMap.register('container', standardElement(Container));
|
||||
tagMap.register('container-custom', standardElement(ContainerCustom));
|
||||
tagMap.register('template', standardElement(Container));
|
||||
tagMap.register('mota-renderer', (_0, _1, props) => {
|
||||
return new MotaRenderer(props?.id);
|
||||
});
|
||||
tagMap.register('sprite', standardElement(Sprite));
|
||||
tagMap.register<ETextEvent, Text>('text', (_0, _1, props) => {
|
||||
if (!props) return new Text();
|
||||
else {
|
||||
const { type = 'static', text = '' } = props;
|
||||
return new Text(text, type);
|
||||
}
|
||||
});
|
||||
const emptyImage = document.createElement('canvas');
|
||||
emptyImage.width = 1;
|
||||
emptyImage.height = 1;
|
||||
tagMap.register('image', (_0, _1, props) => {
|
||||
if (!props) return new Image(emptyImage);
|
||||
else {
|
||||
const { image = emptyImage, type = 'static' } = props;
|
||||
return new Image(image, type);
|
||||
}
|
||||
});
|
||||
tagMap.register('comment', (_0, _1, props) => {
|
||||
if (!props) return new Comment();
|
||||
else {
|
||||
const { text = '' } = props;
|
||||
return new Comment(text);
|
||||
}
|
||||
});
|
||||
tagMap.register('shader', (_0, _1, props) => {
|
||||
if (!props) return new Shader();
|
||||
else {
|
||||
const { type = 'static' } = props;
|
||||
return new Shader(type);
|
||||
}
|
||||
});
|
||||
tagMap.register('custom', (_0, _1, props) => {
|
||||
if (!props) {
|
||||
logger.error(22);
|
||||
throw new Error('Cannot create custom element.');
|
||||
} else {
|
||||
const item = props._item;
|
||||
if (!item) {
|
||||
logger.error(22);
|
||||
throw new Error('Cannot create custom element.');
|
||||
}
|
||||
return item(props);
|
||||
}
|
||||
});
|
||||
tagMap.register('g-rect', standardElementNoCache(Rect));
|
||||
tagMap.register('g-circle', standardElementNoCache(Circle));
|
||||
tagMap.register('g-ellipse', standardElementNoCache(Ellipse));
|
||||
tagMap.register('g-line', standardElementNoCache(Line));
|
||||
tagMap.register('g-bezier', standardElementNoCache(BezierCurve));
|
||||
tagMap.register('g-quad', standardElementNoCache(QuadraticCurve));
|
||||
tagMap.register('g-path', standardElementNoCache(Path));
|
||||
tagMap.register('g-rectr', standardElementNoCache(RectR));
|
||||
@@ -0,0 +1,225 @@
|
||||
import {
|
||||
RenderFunction,
|
||||
RenderItem,
|
||||
RenderItemPosition,
|
||||
Transform,
|
||||
ElementAnchor,
|
||||
ElementLocator,
|
||||
ElementScale,
|
||||
CustomContainerRenderFn,
|
||||
CustomContainerPropagateFn,
|
||||
CanvasStyle
|
||||
} from '@motajs/render-core';
|
||||
import {
|
||||
BezierParams,
|
||||
CircleParams,
|
||||
EllipseParams,
|
||||
ILineProperty,
|
||||
LineParams,
|
||||
QuadParams,
|
||||
RectRCircleParams,
|
||||
RectREllipseParams
|
||||
} from '@motajs/render-elements';
|
||||
import { Font } from '@motajs/render-style';
|
||||
|
||||
export interface CustomProps {
|
||||
_item: (props: BaseProps) => RenderItem;
|
||||
}
|
||||
|
||||
export interface BaseProps {
|
||||
/** 元素的横坐标 */
|
||||
x?: number;
|
||||
/** 元素的纵坐标 */
|
||||
y?: number;
|
||||
/** 元素的横向锚点位置 */
|
||||
anchorX?: number;
|
||||
/** 元素的纵向锚点位置 */
|
||||
anchorY?: number;
|
||||
/** 元素的纵深,值越大越靠上 */
|
||||
zIndex?: number;
|
||||
/** 元素的宽度 */
|
||||
width?: number;
|
||||
/** 元素的高度 */
|
||||
height?: number;
|
||||
/** 元素的滤镜 */
|
||||
filter?: string;
|
||||
/** 是否启用高清画布 */
|
||||
hd?: boolean;
|
||||
/** 是否启用抗锯齿 */
|
||||
anti?: boolean;
|
||||
/** 是否不启用抗锯齿,优先级大于 anti,主要用于像素图片渲染 */
|
||||
noanti?: boolean;
|
||||
/** 元素是否隐藏,可以用于一些画面效果,也可以用于调试 */
|
||||
hidden?: boolean;
|
||||
/** 元素的变换矩阵 */
|
||||
transform?: Transform;
|
||||
/** 元素的定位模式,static 表示常规定位,absolute 定位模式下元素位置始终处于左上角 */
|
||||
type?: RenderItemPosition;
|
||||
/** 是否启用缓存,用处较少,主要用于一些默认不启用缓存的元素的特殊优化 */
|
||||
cache?: boolean;
|
||||
/** 是否不启用缓存,优先级大于 cache,用处较少,主要用于一些特殊优化 */
|
||||
nocache?: boolean;
|
||||
/** 是否启用变换矩阵下穿,下穿模式下,当前元素会使用由父元素传递过来的变换矩阵,而非元素自身的 */
|
||||
fall?: boolean;
|
||||
/** 这个元素的唯一标识符,不可重复 */
|
||||
id?: string;
|
||||
/** 这个元素的不透明度 */
|
||||
alpha?: number;
|
||||
/** 这个元素与已渲染内容的混合模式,默认为 source-over */
|
||||
composite?: GlobalCompositeOperation;
|
||||
/** 鼠标放在这个元素上时的光标样式 */
|
||||
cursor?: string;
|
||||
/**
|
||||
* 定位属性,可以填 `[横坐标,纵坐标,宽度,高度,x锚点,y锚点]`,
|
||||
* 对于横坐标与纵坐标、宽度与高度、x锚点与y锚点,两两一组要么都填,要么都不填
|
||||
* 是 x, y, width, height, anchorX, anchorY 的简写属性
|
||||
*/
|
||||
loc?: ElementLocator;
|
||||
/** 锚点属性,可以填 `[x锚点,y锚点]`,是 anchorX, anchorY 的简写属性 */
|
||||
anc?: ElementAnchor;
|
||||
/** 放缩属性,可以填 `[x比例,y比例]`,是 transform 的简写属性之一 */
|
||||
scale?: ElementScale;
|
||||
/** 旋转属性,单位弧度,是 transform 的简写属性之一 */
|
||||
rotate?: number;
|
||||
/** 这个元素是否不会触发任何交互事件(cursor 属性也会无效),当执行到此元素时,会下穿至下一个元素 */
|
||||
noevent?: boolean;
|
||||
}
|
||||
|
||||
export interface SpriteProps extends BaseProps {
|
||||
/** 自定义的渲染函数 */
|
||||
render?: RenderFunction;
|
||||
}
|
||||
|
||||
export interface ContainerProps extends BaseProps {}
|
||||
|
||||
export interface ConatinerCustomProps extends ContainerProps {
|
||||
/** 自定义容器渲染函数 */
|
||||
render?: CustomContainerRenderFn;
|
||||
/** 自定义容器事件传递函数 */
|
||||
propagate?: CustomContainerPropagateFn;
|
||||
}
|
||||
|
||||
export interface GL2Props extends BaseProps {}
|
||||
|
||||
export interface ShaderProps extends BaseProps {}
|
||||
|
||||
export interface TextProps extends BaseProps {
|
||||
/** 要渲染的文字 */
|
||||
text?: string;
|
||||
/** 文字的填充样式 */
|
||||
fillStyle?: CanvasStyle;
|
||||
/** 文字的描边样式 */
|
||||
strokeStyle?: CanvasStyle;
|
||||
/** 文字的字体 */
|
||||
font?: Font;
|
||||
/** 文字的描边粗细 */
|
||||
strokeWidth?: number;
|
||||
}
|
||||
|
||||
export interface ImageProps extends BaseProps {
|
||||
/** 图片对象 */
|
||||
image: CanvasImageSource;
|
||||
}
|
||||
|
||||
export interface CommentProps extends BaseProps {
|
||||
text?: string;
|
||||
}
|
||||
|
||||
export interface GraphicPropsBase extends BaseProps, Partial<ILineProperty> {
|
||||
/** 是否填充,若填写 {@link stroke},那么表现为先填充后描边 */
|
||||
fill?: boolean;
|
||||
/** 是否描边,若填写 {@link fill},那么表现为先填充后描边 */
|
||||
stroke?: boolean;
|
||||
/** 是否先描边后填充,优先级最高,若设置,则 {@link fill} 与 {@link stroke} 无效。 */
|
||||
strokeAndFill?: boolean;
|
||||
/** 填充原则,比如 `nonzero` 表示非零环绕原则,默认为奇偶环绕原则 `evenodd` */
|
||||
fillRule?: CanvasFillRule;
|
||||
/** 填充样式 */
|
||||
fillStyle?: CanvasStyle;
|
||||
/** 描边样式 */
|
||||
strokeStyle?: CanvasStyle;
|
||||
/** 在交互时,是否只检查交互位置只在描边上,对 fill, stroke, strokeAndFill 均有效 */
|
||||
actionStroke?: boolean;
|
||||
}
|
||||
|
||||
export interface RectProps extends GraphicPropsBase {}
|
||||
|
||||
export interface CirclesProps extends GraphicPropsBase {
|
||||
radius?: number;
|
||||
start?: number;
|
||||
end?: number;
|
||||
/**
|
||||
* 圆属性参数,可以填 `[圆心 x 坐标,圆心 y 坐标,半径,起始角度,终止角度]`,是 x, y, radius, start, end 的简写,
|
||||
* 其中半径可选,后两项要么都填,要么都不填
|
||||
*/
|
||||
circle?: CircleParams;
|
||||
}
|
||||
|
||||
export interface EllipseProps extends GraphicPropsBase {
|
||||
radiusX?: number;
|
||||
radiusY?: number;
|
||||
start?: number;
|
||||
end?: number;
|
||||
/**
|
||||
* 椭圆属性参数,可以填 `[圆心 x 坐标,圆心 y 坐标,x半径,y半径,起始角度,终止角度]`,是 x, y, radiusX, radiusY, start, end 的简写,
|
||||
* 其中每两项要么都填,要么都不填
|
||||
*/
|
||||
ellipse?: EllipseParams;
|
||||
}
|
||||
|
||||
export interface LineProps extends GraphicPropsBase {
|
||||
x1?: number;
|
||||
y1?: number;
|
||||
x2?: number;
|
||||
y2?: number;
|
||||
/** 直线属性参数,可以填 `[x1, y1, x2, y2]`,都是必填 */
|
||||
line?: LineParams;
|
||||
}
|
||||
|
||||
export interface BezierProps extends GraphicPropsBase {
|
||||
sx?: number;
|
||||
sy?: number;
|
||||
cp1x?: number;
|
||||
cp1y?: number;
|
||||
cp2x?: number;
|
||||
cp2y?: number;
|
||||
ex?: number;
|
||||
ey?: number;
|
||||
/** 三次贝塞尔曲线参数,可以填 `[sx, sy, cp1x, cp1y, cp2x, cp2y, ex, ey]`,都是必填 */
|
||||
curve?: BezierParams;
|
||||
}
|
||||
|
||||
export interface QuadraticProps extends GraphicPropsBase {
|
||||
sx?: number;
|
||||
sy?: number;
|
||||
cpx?: number;
|
||||
cpy?: number;
|
||||
ex?: number;
|
||||
ey?: number;
|
||||
/** 二次贝塞尔曲线参数,可以填 `[sx, sy, cpx, cpy, ex, ey]`,都是必填 */
|
||||
curve?: QuadParams;
|
||||
}
|
||||
|
||||
export interface PathProps extends GraphicPropsBase {
|
||||
path?: Path2D;
|
||||
}
|
||||
|
||||
export interface RectRProps extends GraphicPropsBase {
|
||||
/**
|
||||
* 圆形圆角参数,可以填 `[r1, r2, r3, r4]`,后三项可选。填写不同数量下的表现:
|
||||
* - 1个:每个角都是 `r1` 半径的圆
|
||||
* - 2个:左上和右下是 `r1` 半径的圆,右上和左下是 `r2` 半径的圆
|
||||
* - 3个:左上是 `r1` 半径的圆,右上和左下是 `r2` 半径的圆,右下是 `r3` 半径的圆
|
||||
* - 4个:左上、右上、左下、右下 分别是 `r1, r2, r3, r4` 半径的圆
|
||||
*/
|
||||
circle?: RectRCircleParams;
|
||||
/**
|
||||
* 椭圆圆角参数,可以填 `[rx1, ry1, rx2, ry2, rx3, ry3, rx4, ry4]`,
|
||||
* 两两一组,后三组可选,填写不同数量下的表现:
|
||||
* - 1组:每个角都是 `[rx1, ry1]` 半径的椭圆
|
||||
* - 2组:左上和右下是 `[rx1, ry1]` 半径的椭圆,右上和左下是 `[rx2, ry2]` 半径的椭圆
|
||||
* - 3组:左上是 `[rx1, ry1]` 半径的椭圆,右上和左下是 `[rx2, ey2]` 半径的椭圆,右下是 `[rx3, ry3]` 半径的椭圆
|
||||
* - 4组:左上、右上、左下、右下 分别是 `[rx1, ry1], [rx2, ry2], [rx3, ry3], [rx4, ry4]` 半径的椭圆
|
||||
*/
|
||||
ellipse?: RectREllipseParams;
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
import { logger } from '@motajs/common';
|
||||
import { ERenderItemEvent, RenderItem } from '@motajs/render-core';
|
||||
import { ETextEvent, Text, Comment } from '@motajs/render-elements';
|
||||
import {
|
||||
ComponentInternalInstance,
|
||||
createRenderer,
|
||||
ElementNamespace,
|
||||
VNodeProps
|
||||
} from 'vue';
|
||||
import { tagMap } from './map';
|
||||
|
||||
export const { createApp, render } = createRenderer<RenderItem, RenderItem>({
|
||||
patchProp: function (
|
||||
el: RenderItem,
|
||||
key: string,
|
||||
prevValue: any,
|
||||
nextValue: any,
|
||||
namespace?: ElementNamespace,
|
||||
parentComponent?: ComponentInternalInstance | null
|
||||
): void {
|
||||
el.patchProp(key, prevValue, nextValue, namespace, parentComponent);
|
||||
},
|
||||
|
||||
insert: function (
|
||||
el: RenderItem<ERenderItemEvent>,
|
||||
parent: RenderItem,
|
||||
_anchor?: RenderItem<ERenderItemEvent> | null
|
||||
): void {
|
||||
parent.appendChild(el);
|
||||
},
|
||||
|
||||
remove: function (el: RenderItem<ERenderItemEvent>): void {
|
||||
el.destroy();
|
||||
},
|
||||
|
||||
createElement: function (
|
||||
type: string,
|
||||
namespace?: ElementNamespace,
|
||||
isCustomizedBuiltIn?: string,
|
||||
vnodeProps?: (VNodeProps & { [key: string]: any }) | null
|
||||
): RenderItem {
|
||||
const onCreate = tagMap.get(type);
|
||||
if (!onCreate) {
|
||||
logger.error(20, type);
|
||||
throw new Error(`Cannot create element '${type}'`);
|
||||
}
|
||||
return onCreate(namespace, isCustomizedBuiltIn, vnodeProps);
|
||||
},
|
||||
|
||||
createText: function (text: string): RenderItem<ETextEvent> {
|
||||
if (/^\s*$/.test(text)) {
|
||||
return new Comment();
|
||||
} else {
|
||||
logger.warn(38);
|
||||
}
|
||||
return new Text(text);
|
||||
},
|
||||
|
||||
createComment: function (text: string): RenderItem<ERenderItemEvent> {
|
||||
return new Comment(text);
|
||||
},
|
||||
|
||||
setText: function (node: RenderItem<ERenderItemEvent>, text: string): void {
|
||||
if (node instanceof Text) {
|
||||
node.setText(text);
|
||||
} else {
|
||||
logger.warn(39);
|
||||
}
|
||||
},
|
||||
|
||||
setElementText: function (node: RenderItem, text: string): void {
|
||||
if (node instanceof Text) {
|
||||
node.setText(text);
|
||||
} else {
|
||||
logger.warn(39);
|
||||
}
|
||||
},
|
||||
|
||||
parentNode: function (
|
||||
node: RenderItem<ERenderItemEvent>
|
||||
): RenderItem | null {
|
||||
return node.parent ?? null;
|
||||
},
|
||||
|
||||
nextSibling: function (
|
||||
node: RenderItem<ERenderItemEvent>
|
||||
): RenderItem<ERenderItemEvent> | null {
|
||||
if (!node) return null;
|
||||
if (!node.parent) {
|
||||
return null;
|
||||
} else {
|
||||
const parent = node.parent;
|
||||
const list = [...parent.children];
|
||||
const index = list.indexOf(node);
|
||||
return list[index] ?? null;
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,54 @@
|
||||
import { Animation, Ticker, Transition } from 'mutate-animate';
|
||||
import { ERenderItemEvent, RenderItem } from '@motajs/render-core';
|
||||
import { onMounted, onUnmounted } from 'vue';
|
||||
import EventEmitter from 'eventemitter3';
|
||||
|
||||
const ticker = new Ticker();
|
||||
|
||||
/**
|
||||
* 在组件中每帧执行一次函数
|
||||
* @param fn 每帧执行的函数
|
||||
*/
|
||||
export function onTick(fn: (time: number) => void) {
|
||||
onMounted(() => {
|
||||
ticker.add(fn);
|
||||
});
|
||||
onUnmounted(() => {
|
||||
ticker.remove(fn);
|
||||
});
|
||||
}
|
||||
|
||||
type AnimationUsing = [Animation];
|
||||
type TransitionUsing = [Transition];
|
||||
|
||||
/**
|
||||
* 在组件中创建一个动画实例
|
||||
*/
|
||||
export function useAnimation(): AnimationUsing {
|
||||
const ani = new Animation();
|
||||
onUnmounted(() => {
|
||||
ani.ticker.destroy();
|
||||
});
|
||||
return [ani];
|
||||
}
|
||||
|
||||
/**
|
||||
* 在组件中创建一个渐变实例
|
||||
*/
|
||||
export function useTransition(): TransitionUsing {
|
||||
const tran = new Transition();
|
||||
onUnmounted(() => {
|
||||
tran.ticker.destroy();
|
||||
});
|
||||
return [tran];
|
||||
}
|
||||
|
||||
export function onEvent<
|
||||
T extends ERenderItemEvent,
|
||||
K extends EventEmitter.EventNames<T>
|
||||
>(item: RenderItem<T>, key: K, listener: EventEmitter.EventListener<T, K>) {
|
||||
item.on(key, listener);
|
||||
onUnmounted(() => {
|
||||
item.off(key, listener);
|
||||
});
|
||||
}
|
||||
Reference in new issue
Block a user