animate restruct
This commit is contained in:
@@ -1,9 +1,9 @@
|
|||||||
import React, { useMemo, useState } from 'react';
|
import React, { useMemo, useState } from 'react';
|
||||||
import { UserConfig, deepCopy } from 'dooringx-lib';
|
import { UserConfig, deepCopy } from 'dooringx-lib';
|
||||||
import { Col, Row, Select, InputNumber } from 'antd';
|
import { Col, Row, Select, InputNumber, Button } from 'antd';
|
||||||
import { FormMap, FormBaseType } from '../formTypes';
|
import { FormMap, FormBaseType } from '../formTypes';
|
||||||
import { CreateOptionsRes } from 'dooringx-lib/dist/core/components/formTypes';
|
import { CreateOptionsRes } from 'dooringx-lib/dist/core/components/formTypes';
|
||||||
import { IBlockType } from 'dooringx-lib/dist/core/store/storetype';
|
import { AnimateItem, IBlockType, IStoreData } from 'dooringx-lib/dist/core/store/storetype';
|
||||||
|
|
||||||
export interface FormAnimateControlType extends FormBaseType {}
|
export interface FormAnimateControlType extends FormBaseType {}
|
||||||
|
|
||||||
@@ -112,195 +112,134 @@ const animateCategory: Record<string, string> = {
|
|||||||
animate__slideOutDown: 'slideOutDown',
|
animate__slideOutDown: 'slideOutDown',
|
||||||
animate__slideOutLeft: 'slideOutLeft',
|
animate__slideOutLeft: 'slideOutLeft',
|
||||||
animate__slideOutRight: 'slideOutRight',
|
animate__slideOutRight: 'slideOutRight',
|
||||||
animate__slideOutUp: 'slideOutUp',
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const animateRepeat: Record<string, string> = {
|
const duration = ['0s', '1s', '2s', '3s', '4s', '5s', '6s', '7s', '8s', '9s', '10s'];
|
||||||
'': '无',
|
|
||||||
'1': '1次',
|
const delay = ['0s', '1s', '2s', '3s', '4s', '5s', '6s', '7s', '8s', '9s', '10s'];
|
||||||
'2': '2次',
|
|
||||||
'3': '3次',
|
const repeat = ['1', '2', '3', '4', '5', 'infinite'];
|
||||||
'4': '4次',
|
|
||||||
infinite: '无限',
|
const timeFunction = {
|
||||||
|
平滑: 'linear',
|
||||||
|
缓入: 'ease in',
|
||||||
};
|
};
|
||||||
|
|
||||||
const animateSpeed: Record<string, string> = {
|
|
||||||
'': '普通',
|
|
||||||
animate__slow: '特慢',
|
|
||||||
animate__slower: '慢速',
|
|
||||||
animate__fast: '快速',
|
|
||||||
animate__faster: '特快',
|
|
||||||
};
|
|
||||||
|
|
||||||
let lastAnimate = '';
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* 这个控制组件配置项写死,只可能出现或者不出现
|
|
||||||
* @return {*}
|
|
||||||
*/
|
|
||||||
function AnimateControl(props: AnimateControlProps) {
|
function AnimateControl(props: AnimateControlProps) {
|
||||||
const [count, setCount] = useState<number | null>(null);
|
const animate = props.current.animate;
|
||||||
const [sign, setSign] = useState(false);
|
const store = props.config.getStore();
|
||||||
const v1 = useMemo(() => {
|
|
||||||
if (sign) {
|
|
||||||
return lastAnimate;
|
|
||||||
} else {
|
|
||||||
const val = props.current.animate.animate
|
|
||||||
? animateCategory[props.current.animate.animate]
|
|
||||||
: '';
|
|
||||||
lastAnimate = val;
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
}, [props.current.animate.animate, sign]);
|
|
||||||
|
|
||||||
const v2 = useMemo(() => {
|
|
||||||
if (typeof props.current.animate.animationIterationCount === 'number') {
|
|
||||||
setCount(props.current.animate.animationIterationCount);
|
|
||||||
return '';
|
|
||||||
} else {
|
|
||||||
setCount(null);
|
|
||||||
return props.current.animate.animationIterationCount
|
|
||||||
? animateRepeat[props.current.animate.animationIterationCount]
|
|
||||||
: '';
|
|
||||||
}
|
|
||||||
}, [props.current.animate.animationIterationCount]);
|
|
||||||
|
|
||||||
const v3 = useMemo(() => {
|
|
||||||
return animateSpeed[props.current.animate.speed ?? ''];
|
|
||||||
}, [props.current.animate.speed]);
|
|
||||||
|
|
||||||
const changeAnimation = (
|
|
||||||
e: any,
|
|
||||||
props: AnimateControlProps,
|
|
||||||
type: 'animate' | 'animationIterationCount' | 'speed'
|
|
||||||
) => {
|
|
||||||
if (type === 'animationIterationCount') {
|
|
||||||
setCount(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
const clonedata = deepCopy(props.config.getStore().getData());
|
|
||||||
const newblock = clonedata.block.map((v: IBlockType) => {
|
|
||||||
if (v.id === props.current.id) {
|
|
||||||
if (type === 'animationIterationCount') {
|
|
||||||
v.animate[type] = Number(e);
|
|
||||||
}
|
|
||||||
v.animate[type] = e;
|
|
||||||
}
|
|
||||||
return v;
|
|
||||||
});
|
|
||||||
const [item] = clonedata.block.filter((item: IBlockType) => item.id === props.current.id);
|
|
||||||
if (item?.animate?.animate) {
|
|
||||||
const cloneNewBlock = deepCopy(newblock);
|
|
||||||
const temporaryBlock = cloneNewBlock.map((item: IBlockType) => {
|
|
||||||
if (item.id === props.current.id) {
|
|
||||||
delete item.animate.animate;
|
|
||||||
}
|
|
||||||
return item;
|
|
||||||
});
|
|
||||||
setSign(true);
|
|
||||||
// 若有动画属性则删除动画属性再将动画属性添加
|
|
||||||
props.config.getStore().setData({ ...clonedata, block: [...temporaryBlock] });
|
|
||||||
}
|
|
||||||
setTimeout(() => {
|
|
||||||
props.config.getStore().setData({ ...clonedata, block: [...newblock] });
|
|
||||||
setSign(false);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Row style={{ padding: '20px' }}>
|
{animate.map((v, i) => {
|
||||||
<Col span={6} style={{ lineHeight: '30px' }}>
|
return (
|
||||||
动画种类
|
<div key={props.current.id + i}>
|
||||||
</Col>
|
<Row style={{ padding: '20px', alignItems: 'center' }}>
|
||||||
<Col span={18}>
|
<Col span={3}>动画:</Col>
|
||||||
<Select
|
<Col span={8}>
|
||||||
value={v1}
|
<Select style={{ width: '80%' }}>
|
||||||
onChange={(e) => changeAnimation(e, props, 'animate')}
|
{Object.keys(animateCategory).map((v, i) => {
|
||||||
style={{ width: '100%' }}
|
return (
|
||||||
>
|
<Select.Option key={i} value={animateCategory[v]}>
|
||||||
{Object.keys(animateCategory).map((v) => {
|
{animateCategory[v]}
|
||||||
return (
|
</Select.Option>
|
||||||
<Select.Option value={v} key={v}>
|
);
|
||||||
{animateCategory[v]}
|
})}
|
||||||
</Select.Option>
|
</Select>
|
||||||
);
|
</Col>
|
||||||
})}
|
<Col span={5}>持续时间:</Col>
|
||||||
</Select>
|
<Col span={8}>
|
||||||
</Col>
|
<Select style={{ width: '100%' }}>
|
||||||
</Row>
|
{duration.map((v, i) => {
|
||||||
<Row style={{ padding: '20px' }}>
|
return (
|
||||||
<Col span={6} style={{ lineHeight: '30px' }}>
|
<Select.Option key={i} value={v}>
|
||||||
频率
|
{v}
|
||||||
</Col>
|
</Select.Option>
|
||||||
<Col span={18} style={{ display: 'flex', justifyContent: 'space-between' }}>
|
);
|
||||||
<InputNumber
|
})}
|
||||||
min={1}
|
</Select>
|
||||||
value={count as number}
|
</Col>
|
||||||
onChange={(value) => {
|
</Row>
|
||||||
setCount(value);
|
<Row style={{ padding: '20px', alignItems: 'center' }}>
|
||||||
const clonedata = deepCopy(props.config.getStore().getData());
|
<Col span={3}>延迟:</Col>
|
||||||
const newblock = clonedata.block.map((v: IBlockType) => {
|
<Col span={8}>
|
||||||
if (v.id === props.current.id) {
|
<Select style={{ width: '80%' }}>
|
||||||
v.animate.animationIterationCount = value;
|
{delay.map((v, i) => {
|
||||||
}
|
return (
|
||||||
return v;
|
<Select.Option key={i} value={v}>
|
||||||
});
|
{v}
|
||||||
|
</Select.Option>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Select>
|
||||||
|
</Col>
|
||||||
|
<Col span={5}>重复次数:</Col>
|
||||||
|
<Col span={8}>
|
||||||
|
<Select style={{ width: '100%' }}>
|
||||||
|
{repeat.map((v, i) => {
|
||||||
|
return (
|
||||||
|
<Select.Option key={i} value={v}>
|
||||||
|
{v}
|
||||||
|
</Select.Option>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Select>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row style={{ padding: '20px' }}>
|
||||||
|
<Col span={3}>延迟:</Col>
|
||||||
|
<Col span={8}>
|
||||||
|
<Select style={{ width: '80%' }}>
|
||||||
|
{delay.map((v, i) => {
|
||||||
|
return (
|
||||||
|
<Select.Option key={i} value={v}>
|
||||||
|
{v}
|
||||||
|
</Select.Option>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Select>
|
||||||
|
</Col>
|
||||||
|
<Col span={8} style={{ justifyContent: 'flex-end' }}>
|
||||||
|
<Button
|
||||||
|
danger
|
||||||
|
onClick={() => {
|
||||||
|
const cloneData: IStoreData = deepCopy(store.getData());
|
||||||
|
cloneData.block.map((v) => {
|
||||||
|
if (v.id === props.current.id) {
|
||||||
|
v.animate.splice(i, 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
store.setData(cloneData);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</Button>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
|
||||||
const [item] = clonedata.block.filter(
|
<Row style={{ padding: '20px', justifyContent: 'center' }}>
|
||||||
(item: IBlockType) => item.id === props.current.id
|
<Button
|
||||||
);
|
onClick={() => {
|
||||||
|
const cloneData: IStoreData = deepCopy(store.getData());
|
||||||
if (item?.animate?.animate) {
|
const newItem: AnimateItem = {
|
||||||
const cloneNewBlock = deepCopy(newblock);
|
animationName: '',
|
||||||
const temporaryBlock = cloneNewBlock.map((item: IBlockType) => {
|
animationDelay: '0s',
|
||||||
if (item.id === props.current.id) {
|
animationDuration: '1s',
|
||||||
delete item.animate.animate;
|
animationTimingFunction: 'linear',
|
||||||
}
|
animationIterationCount: 1,
|
||||||
return item;
|
};
|
||||||
});
|
cloneData.block.map((v) => {
|
||||||
setSign(true);
|
if (v.id === props.current.id) {
|
||||||
props.config.getStore().setData({ ...clonedata, block: [...temporaryBlock] });
|
v.animate.push(newItem);
|
||||||
}
|
}
|
||||||
setTimeout(() => {
|
});
|
||||||
props.config.getStore().setData({ ...clonedata, block: [...newblock] });
|
store.setData(cloneData);
|
||||||
setSign(false);
|
}}
|
||||||
});
|
>
|
||||||
}}
|
添加动画
|
||||||
></InputNumber>
|
</Button>
|
||||||
<Select
|
|
||||||
value={v2}
|
|
||||||
onChange={(e) => changeAnimation(e, props, 'animationIterationCount')}
|
|
||||||
style={{ width: '60%' }}
|
|
||||||
>
|
|
||||||
{Object.keys(animateRepeat).map((v) => {
|
|
||||||
return (
|
|
||||||
<Select.Option value={v} key={v}>
|
|
||||||
{animateRepeat[v]}
|
|
||||||
</Select.Option>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</Select>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
<Row style={{ padding: '20px' }}>
|
|
||||||
<Col span={6} style={{ lineHeight: '30px' }}>
|
|
||||||
动画速度
|
|
||||||
</Col>
|
|
||||||
<Col span={18}>
|
|
||||||
<Select
|
|
||||||
value={v3}
|
|
||||||
onChange={(e: any) => changeAnimation(e, props, 'speed')}
|
|
||||||
style={{ width: '100%' }}
|
|
||||||
>
|
|
||||||
{Object.keys(animateSpeed).map((v) => {
|
|
||||||
return (
|
|
||||||
<Select.Option value={v} key={v}>
|
|
||||||
{animateSpeed[v]}
|
|
||||||
</Select.Option>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</Select>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
</Row>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@@ -95,22 +95,7 @@ function Blocks(props: PropsWithChildren<BlockProps>) {
|
|||||||
props.data.fixed,
|
props.data.fixed,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const animatecss = useMemo(() => {
|
console.log(props.data.animate);
|
||||||
const animate = props.data.animate;
|
|
||||||
if (Object.keys(animate).length > 0) {
|
|
||||||
return `animate__animated ${animate.animate ?? ''} ${animate.delay ?? ''} ${
|
|
||||||
animate.speed ?? ''
|
|
||||||
}`;
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
}, [props.data.animate]);
|
|
||||||
const animateCount = useMemo(() => {
|
|
||||||
const animate = props.data.animate;
|
|
||||||
if (Object.keys(animate).length > 0) {
|
|
||||||
return { animationIterationCount: animate.animationIterationCount };
|
|
||||||
}
|
|
||||||
return { animationIterationCount: '' };
|
|
||||||
}, [props.data.animate]);
|
|
||||||
|
|
||||||
const render = useMemo(() => {
|
const render = useMemo(() => {
|
||||||
// 如果是编辑模式下,则需要包裹不能选中层,位移层,缩放控制层,平面移动层。
|
// 如果是编辑模式下,则需要包裹不能选中层,位移层,缩放控制层,平面移动层。
|
||||||
@@ -141,20 +126,14 @@ function Blocks(props: PropsWithChildren<BlockProps>) {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{/* 绝对定位元素 */}
|
{/* 绝对定位元素 */}
|
||||||
{props.data.position !== 'static' && (
|
{props.data.position !== 'static' && <div style={{ ...style }}>{state}</div>}
|
||||||
<div className={animatecss} style={{ ...style, ...animateCount }}>
|
|
||||||
{state}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{/* 静态定位 非行内 这里暂不考虑布局影响 */}
|
{/* 静态定位 非行内 这里暂不考虑布局影响 */}
|
||||||
{props.data.position === 'static' && props.data.display !== 'inline' && (
|
{props.data.position === 'static' && props.data.display !== 'inline' && (
|
||||||
<div
|
<div
|
||||||
className={animatecss}
|
|
||||||
style={{
|
style={{
|
||||||
pointerEvents: 'none',
|
pointerEvents: 'none',
|
||||||
width: '100%',
|
width: '100%',
|
||||||
height: '100%',
|
height: '100%',
|
||||||
...animateCount,
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{state}
|
{state}
|
||||||
@@ -171,7 +150,6 @@ function Blocks(props: PropsWithChildren<BlockProps>) {
|
|||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={animatecss}
|
|
||||||
style={{
|
style={{
|
||||||
position: props.data.fixed ? 'fixed' : props.data.position,
|
position: props.data.fixed ? 'fixed' : props.data.position,
|
||||||
top: previewState.top,
|
top: previewState.top,
|
||||||
@@ -181,7 +159,6 @@ function Blocks(props: PropsWithChildren<BlockProps>) {
|
|||||||
zIndex: props.data.zIndex,
|
zIndex: props.data.zIndex,
|
||||||
display: props.data.display,
|
display: props.data.display,
|
||||||
transform: `rotate(${props.data.rotate.value}deg)`,
|
transform: `rotate(${props.data.rotate.value}deg)`,
|
||||||
...animateCount,
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{state}
|
{state}
|
||||||
@@ -195,8 +172,6 @@ function Blocks(props: PropsWithChildren<BlockProps>) {
|
|||||||
props.iframe,
|
props.iframe,
|
||||||
props.config,
|
props.config,
|
||||||
innerDragData,
|
innerDragData,
|
||||||
animatecss,
|
|
||||||
animateCount,
|
|
||||||
previewState.top,
|
previewState.top,
|
||||||
previewState.left,
|
previewState.left,
|
||||||
previewState.width,
|
previewState.width,
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* @Author: yehuozhili
|
* @Author: yehuozhili
|
||||||
* @Date: 2021-03-14 04:29:09
|
* @Date: 2021-03-14 04:29:09
|
||||||
* @LastEditors: yehuozhili
|
* @LastEditors: yehuozhili
|
||||||
* @LastEditTime: 2021-07-21 20:56:01
|
* @LastEditTime: 2021-08-06 10:24:32
|
||||||
* @FilePath: \dooringx\packages\dooringx-lib\src\core\components\createBlock.ts
|
* @FilePath: \dooringx\packages\dooringx-lib\src\core\components\createBlock.ts
|
||||||
*/
|
*/
|
||||||
import { IBlockType } from '../store/storetype';
|
import { IBlockType } from '../store/storetype';
|
||||||
@@ -28,7 +28,7 @@ export function createBlock(top: number, left: number, ComponentItem: ComponentI
|
|||||||
canDrag: ComponentItem.initData.canDrag ?? true,
|
canDrag: ComponentItem.initData.canDrag ?? true,
|
||||||
eventMap: ComponentItem.initData.eventMap || {},
|
eventMap: ComponentItem.initData.eventMap || {},
|
||||||
functionList: ComponentItem.initData.functionList || [],
|
functionList: ComponentItem.initData.functionList || [],
|
||||||
animate: ComponentItem.initData.animate || {},
|
animate: ComponentItem.initData.animate || [],
|
||||||
fixed: ComponentItem.initData.fixed || false,
|
fixed: ComponentItem.initData.fixed || false,
|
||||||
rotate: ComponentItem.initData.rotate || {
|
rotate: ComponentItem.initData.rotate || {
|
||||||
value: 0,
|
value: 0,
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* @Author: yehuozhili
|
* @Author: yehuozhili
|
||||||
* @Date: 2021-03-14 04:29:09
|
* @Date: 2021-03-14 04:29:09
|
||||||
* @LastEditors: yehuozhili
|
* @LastEditors: yehuozhili
|
||||||
* @LastEditTime: 2021-07-21 20:54:38
|
* @LastEditTime: 2021-08-06 21:27:19
|
||||||
* @FilePath: \dooringx\packages\dooringx-lib\src\core\store\storetype.ts
|
* @FilePath: \dooringx\packages\dooringx-lib\src\core\store\storetype.ts
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -19,6 +19,13 @@ export interface IStoreData {
|
|||||||
globalState: Record<string, any>;
|
globalState: Record<string, any>;
|
||||||
modalConfig: Record<string, any>;
|
modalConfig: Record<string, any>;
|
||||||
}
|
}
|
||||||
|
export interface AnimateItem {
|
||||||
|
animationName: string;
|
||||||
|
animationDuration: string;
|
||||||
|
animationDelay: string;
|
||||||
|
animationIterationCount: string;
|
||||||
|
animationTimingFunction: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface IBlockType {
|
export interface IBlockType {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -41,13 +48,6 @@ export interface IBlockType {
|
|||||||
value: number;
|
value: number;
|
||||||
canRotate: boolean;
|
canRotate: boolean;
|
||||||
};
|
};
|
||||||
animate: {
|
animate: AnimateItem[];
|
||||||
animate?: string; //动画名
|
|
||||||
animationIterationCount?: number | string;
|
|
||||||
speed?: //动画速度
|
|
||||||
'animate__slow' | 'animate__slower' | 'animate__fast' | 'animate__faster' | '';
|
|
||||||
delay?: //首次延迟
|
|
||||||
'animate__delay-2s' | 'animate__delay-3s' | 'animate__delay-4s' | 'animate__delay-5s' | '';
|
|
||||||
};
|
|
||||||
fixed: boolean; // 用于制作fixed组件
|
fixed: boolean; // 用于制作fixed组件
|
||||||
}
|
}
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* @Author: yehuozhili
|
* @Author: yehuozhili
|
||||||
* @Date: 2021-04-05 14:55:31
|
* @Date: 2021-04-05 14:55:31
|
||||||
* @LastEditors: yehuozhili
|
* @LastEditors: yehuozhili
|
||||||
* @LastEditTime: 2021-07-27 16:50:09
|
* @LastEditTime: 2021-08-06 16:21:01
|
||||||
* @FilePath: \dooringx\packages\dooringx-lib\src\core\storeChanger\index.ts
|
* @FilePath: \dooringx\packages\dooringx-lib\src\core\storeChanger\index.ts
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ function createDefaultModalBlock(): IStoreData['block'] {
|
|||||||
canDrag: false,
|
canDrag: false,
|
||||||
eventMap: {},
|
eventMap: {},
|
||||||
functionList: [],
|
functionList: [],
|
||||||
animate: {},
|
animate: [],
|
||||||
fixed: true,
|
fixed: true,
|
||||||
rotate: {
|
rotate: {
|
||||||
value: 0,
|
value: 0,
|
||||||
|
Reference in New Issue
Block a user