feat: before update animate
This commit is contained in:
10
CHANGELOG.md
10
CHANGELOG.md
@@ -1,3 +1,13 @@
|
||||
## 0.11.11
|
||||
|
||||
修复动画导致旋转预览不生效。
|
||||
|
||||
新增容器overflow配置。
|
||||
|
||||
timeline部分样式调整。
|
||||
|
||||
example部分样式调整。
|
||||
|
||||
## 0.11.10
|
||||
|
||||
新增对markline颜色样式设置
|
||||
|
@@ -351,7 +351,6 @@ function AnimateControl(props: AnimateControlProps) {
|
||||
}
|
||||
});
|
||||
store.setData(cloneData);
|
||||
props.config.timelineNeedleConfig.resetFunc();
|
||||
}}
|
||||
>
|
||||
添加动画
|
||||
|
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "0.11.10",
|
||||
"version": "0.11.11",
|
||||
"license": "MIT",
|
||||
"main": "dist/index.js",
|
||||
"module": "dist/dooringx-lib.esm.js",
|
||||
|
@@ -101,7 +101,7 @@ function Blocks(props: PropsWithChildren<BlockProps>) {
|
||||
animationDelay: '',
|
||||
animationDuration: '',
|
||||
animationIterationCount: '',
|
||||
animationFillMode: 'forwards',
|
||||
// animationFillMode: 'forwards',// 这个属性和transform冲突
|
||||
animationTimingFunction: '',
|
||||
};
|
||||
props.data.animate.forEach((v) => {
|
||||
@@ -129,12 +129,6 @@ function Blocks(props: PropsWithChildren<BlockProps>) {
|
||||
return select;
|
||||
}, [props.data.animate]);
|
||||
|
||||
const animationPlayState: CSSProperties = useMemo(() => {
|
||||
return {
|
||||
animationPlayState: props.data.animatePlayState || '',
|
||||
};
|
||||
}, [props.data.animatePlayState]);
|
||||
|
||||
const render = useMemo(() => {
|
||||
// 如果是编辑模式下,则需要包裹不能选中层,位移层,缩放控制层,平面移动层。
|
||||
if (state && props.context === 'edit') {
|
||||
@@ -170,7 +164,14 @@ function Blocks(props: PropsWithChildren<BlockProps>) {
|
||||
>
|
||||
{/* 绝对定位元素 */}
|
||||
{props.data.position !== 'static' && (
|
||||
<div style={{ ...style, ...animateProps, ...animationPlayState }}>{state}</div>
|
||||
<div
|
||||
style={{
|
||||
...style,
|
||||
...animateProps,
|
||||
}}
|
||||
>
|
||||
{state}
|
||||
</div>
|
||||
)}
|
||||
{/* 静态定位 非行内 这里暂不考虑布局影响 */}
|
||||
{props.data.position === 'static' && props.data.display !== 'inline' && (
|
||||
@@ -180,7 +181,6 @@ function Blocks(props: PropsWithChildren<BlockProps>) {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
...animateProps,
|
||||
...animationPlayState,
|
||||
}}
|
||||
>
|
||||
{state}
|
||||
@@ -188,7 +188,12 @@ function Blocks(props: PropsWithChildren<BlockProps>) {
|
||||
)}
|
||||
{/* 静态定位 行内 这里暂不考虑布局影响 */}
|
||||
{props.data.position === 'static' && props.data.display === 'inline' && (
|
||||
<span style={{ pointerEvents: 'none', ...animateProps, ...animationPlayState }}>
|
||||
<span
|
||||
style={{
|
||||
pointerEvents: 'none',
|
||||
...animateProps,
|
||||
}}
|
||||
>
|
||||
{state}
|
||||
</span>
|
||||
)}
|
||||
@@ -210,7 +215,6 @@ function Blocks(props: PropsWithChildren<BlockProps>) {
|
||||
display: props.data.display,
|
||||
transform: `rotate(${props.data.rotate.value}deg)`,
|
||||
...animateProps,
|
||||
...animationPlayState,
|
||||
}}
|
||||
>
|
||||
{state}
|
||||
@@ -221,11 +225,10 @@ function Blocks(props: PropsWithChildren<BlockProps>) {
|
||||
state,
|
||||
props.context,
|
||||
props.data,
|
||||
props.iframe,
|
||||
props.config,
|
||||
props.iframe,
|
||||
innerDragData,
|
||||
animateProps,
|
||||
animationPlayState,
|
||||
previewState.top,
|
||||
previewState.left,
|
||||
previewState.width,
|
||||
|
@@ -4,7 +4,7 @@ import { innerContainerDrag } from '../core/innerDrag';
|
||||
import { NormalMarkLineRender } from '../core/markline';
|
||||
import { IStoreData } from '../core/store/storetype';
|
||||
import { wrapperMoveState } from './wrapperMove/event';
|
||||
import { CSSProperties, PropsWithChildren, useMemo } from 'react';
|
||||
import { CSSProperties, PropsWithChildren, useMemo, useState } from 'react';
|
||||
import Blocks from './blocks';
|
||||
import { containerResizer } from '../core/resizeHandler/containerResizer';
|
||||
import React from 'react';
|
||||
@@ -37,6 +37,10 @@ function Container(props: PropsWithChildren<ContainerProps>) {
|
||||
return props.state.globalState.containerColor;
|
||||
}
|
||||
};
|
||||
const forceUpdate = useState(0)[1];
|
||||
props.config.containerForceUpdate = () => {
|
||||
forceUpdate((p) => p + 1);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -59,7 +63,7 @@ function Container(props: PropsWithChildren<ContainerProps>) {
|
||||
width: `${props.state.container.width}px`,
|
||||
backgroundColor: bgColor(),
|
||||
position: 'relative',
|
||||
overflow: 'hidden',
|
||||
overflow: props.config.containerOverFlow ? 'hidden' : 'visible',
|
||||
cursor: 'default',
|
||||
...editContainerStyle,
|
||||
}}
|
||||
|
@@ -45,7 +45,7 @@ function SettingsModal(props: SettingsModalPropsType) {
|
||||
onCancel={() => props.onCancel()}
|
||||
onOk={() => {
|
||||
const res = form.getFieldsValue();
|
||||
const { min, max, borderStyle } = res;
|
||||
const { min, max, borderStyle, containerOverFlow } = res;
|
||||
if (max < min) {
|
||||
props.message.error(replaceLocale('error.minmax', zhCN['error.minmax'], props.config));
|
||||
return;
|
||||
@@ -57,7 +57,9 @@ function SettingsModal(props: SettingsModalPropsType) {
|
||||
}
|
||||
props.config.marklineConfig.borderColor = `rgba(${color.r}, ${color.g}, ${color.b}, ${color.a})`;
|
||||
props.config.marklineConfig.borderStyle = borderStyle;
|
||||
props.config.containerOverFlow = containerOverFlow;
|
||||
props.onOk(res);
|
||||
props.config.containerForceUpdate();
|
||||
return;
|
||||
}}
|
||||
>
|
||||
@@ -70,6 +72,7 @@ function SettingsModal(props: SettingsModalPropsType) {
|
||||
max: props.config.scaleState.maxValue,
|
||||
autofocus: props.config.timelineConfig.autoFocus,
|
||||
borderStyle: props.config.marklineConfig.borderStyle,
|
||||
containerOverFlow: props.config.containerOverFlow,
|
||||
}}
|
||||
form={form}
|
||||
>
|
||||
@@ -142,6 +145,19 @@ function SettingsModal(props: SettingsModalPropsType) {
|
||||
<Radio value={false}>{replaceLocale('off', zhCN['off'], props.config)}</Radio>
|
||||
</Radio.Group>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="containerOverFlow"
|
||||
label={replaceLocale(
|
||||
'settings.containerOverflow',
|
||||
zhCN['settings.containerOverflow'],
|
||||
props.config
|
||||
)}
|
||||
>
|
||||
<Radio.Group>
|
||||
<Radio value={true}>{replaceLocale('on', zhCN['on'], props.config)}</Radio>
|
||||
<Radio value={false}>{replaceLocale('off', zhCN['off'], props.config)}</Radio>
|
||||
</Radio.Group>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Modal>
|
||||
);
|
||||
|
@@ -40,9 +40,10 @@ export interface TimeLineConfigType {
|
||||
scrollDom: null | HTMLDivElement;
|
||||
}
|
||||
export interface TimeLineNeedleConfigType {
|
||||
status: 'stop' | 'start';
|
||||
status: 'stop' | 'start' | 'pause';
|
||||
runFunc: Function;
|
||||
resetFunc: Function;
|
||||
current: number;
|
||||
}
|
||||
|
||||
const animateTicker = new Array(iter).fill(1).map((_, y) => y);
|
||||
@@ -164,9 +165,9 @@ const SortableList = SortableContainer(
|
||||
|
||||
let cacheBlock: IBlockType[] = [];
|
||||
|
||||
const needleWidth = 2;
|
||||
const initialLeft = 20 - needleWidth / 2;
|
||||
let timer: number | null = null;
|
||||
// const needleWidth = 2;
|
||||
// const initialLeft = 20 - needleWidth / 2;
|
||||
// let timer: number | null = null;
|
||||
export function TimeLine(props: TimeLineProps) {
|
||||
const store = props.config.getStore();
|
||||
const data = store.getData().block;
|
||||
@@ -222,32 +223,71 @@ export function TimeLine(props: TimeLineProps) {
|
||||
}
|
||||
}, [props.config]);
|
||||
|
||||
const [needle, setNeedle] = useState(initialLeft);
|
||||
// const [needle, setNeedle] = useState(initialLeft);
|
||||
|
||||
const needleStart = () => {
|
||||
setNeedle(initialLeft);
|
||||
//每过0.1秒移动2
|
||||
if (timer) {
|
||||
window.clearInterval(timer);
|
||||
}
|
||||
props.config.timelineNeedleConfig.status = 'start';
|
||||
timer = window.setInterval(() => {
|
||||
if (needle < ruleWidth) {
|
||||
setNeedle((pre) => pre + 2);
|
||||
}
|
||||
}, 100);
|
||||
};
|
||||
//const needleStart = () => {
|
||||
// props.config.timelineNeedleConfig.current = 0;
|
||||
// setNeedle(initialLeft);
|
||||
// //每过0.1秒移动2
|
||||
// if (timer) {
|
||||
// window.clearInterval(timer);
|
||||
// }
|
||||
// props.config.timelineNeedleConfig.status = 'start';
|
||||
// const cloneData: IStoreData = deepcopy(store.getData());
|
||||
// store.setData(cloneData);
|
||||
// store.cleanLast();
|
||||
// timer = window.setInterval(() => {
|
||||
// if (needle < ruleWidth) {
|
||||
// setNeedle((pre) => {
|
||||
// props.config.timelineNeedleConfig.current = (pre - initialLeft) / 20;
|
||||
// console.log(props.config.timelineNeedleConfig.current);
|
||||
// return pre + 2;
|
||||
// });
|
||||
// }
|
||||
// }, 100);
|
||||
// };
|
||||
|
||||
const needleReset = () => {
|
||||
if (timer) {
|
||||
window.clearInterval(timer);
|
||||
}
|
||||
setNeedle(initialLeft);
|
||||
props.config.timelineNeedleConfig.status = 'stop';
|
||||
};
|
||||
// const needlePlay = async () => {
|
||||
// if (timer) {
|
||||
// window.clearInterval(timer);
|
||||
// }
|
||||
// await resetAnimate();
|
||||
// setTimeout(() => {
|
||||
// props.config.timelineNeedleConfig.status = 'pause';
|
||||
// timer = window.setInterval(() => {
|
||||
// if (needle < ruleWidth) {
|
||||
// setNeedle((pre) => {
|
||||
// props.config.timelineNeedleConfig.current = (pre - initialLeft) / 20;
|
||||
// return pre + 2;
|
||||
// });
|
||||
// }
|
||||
// }, 100);
|
||||
// });
|
||||
// };
|
||||
|
||||
props.config.timelineNeedleConfig.resetFunc = needleReset;
|
||||
props.config.timelineNeedleConfig.runFunc = needleStart;
|
||||
// const needleReset = () => {
|
||||
// if (timer) {
|
||||
// window.clearInterval(timer);
|
||||
// }
|
||||
// props.config.timelineNeedleConfig.status = 'pause';
|
||||
// props.config.timelineNeedleConfig.current = 0;
|
||||
// resetAnimate();
|
||||
// setNeedle(initialLeft);
|
||||
// store.cleanLast();
|
||||
// };
|
||||
|
||||
// const needlePause = () => {
|
||||
// props.config.timelineNeedleConfig.status = 'pause';
|
||||
// if (timer) {
|
||||
// window.clearInterval(timer);
|
||||
// }
|
||||
// const cloneData: IStoreData = deepcopy(store.getData());
|
||||
// store.setData(cloneData);
|
||||
// store.cleanLast();
|
||||
// };
|
||||
|
||||
// props.config.timelineNeedleConfig.resetFunc = needleReset;
|
||||
// props.config.timelineNeedleConfig.runFunc = needleStart;
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -280,44 +320,70 @@ export function TimeLine(props: TimeLineProps) {
|
||||
minWidth: leftWidth,
|
||||
borderBottom: '1px solid #dadada',
|
||||
height: itemHeight,
|
||||
display: 'flex',
|
||||
}}
|
||||
>
|
||||
{replaceLocale('timeline.name', '组件名称', props.config)}
|
||||
<span
|
||||
title="play"
|
||||
<div
|
||||
style={{
|
||||
display: 'inline-block',
|
||||
marginLeft: '20px',
|
||||
cursor: 'pointer',
|
||||
}}
|
||||
onClick={() => {
|
||||
//缓存所有animate后执行
|
||||
if (!WAIT) {
|
||||
WAIT = true;
|
||||
props.config.waitAnimate = true;
|
||||
const cache = data.map((v) => {
|
||||
return v.animate;
|
||||
});
|
||||
const cloneData: IStoreData = deepcopy(store.getData());
|
||||
cloneData.block.forEach((v) => {
|
||||
v.animate = [];
|
||||
});
|
||||
store.setData(cloneData);
|
||||
setTimeout(() => {
|
||||
const cloneData: IStoreData = deepcopy(store.getData());
|
||||
cloneData.block.forEach((v, i) => {
|
||||
v.animate = cache[i];
|
||||
});
|
||||
WAIT = false;
|
||||
props.config.waitAnimate = false;
|
||||
store.setData(cloneData);
|
||||
needleStart();
|
||||
});
|
||||
}
|
||||
flex: 1,
|
||||
textAlign: 'right',
|
||||
}}
|
||||
>
|
||||
<PlayCircleOutlined />
|
||||
</span>
|
||||
{/* <span
|
||||
style={{
|
||||
display: 'inline-block',
|
||||
cursor: 'pointer',
|
||||
marginRight: '10px',
|
||||
}}
|
||||
>
|
||||
<ReloadOutlined onClick={() => needleReset()} />
|
||||
</span>
|
||||
<span
|
||||
style={{
|
||||
display: 'inline-block',
|
||||
cursor: 'pointer',
|
||||
marginRight: '10px',
|
||||
}}
|
||||
>
|
||||
<PauseCircleOutlined onClick={() => needlePause()} />
|
||||
</span> */}
|
||||
<span
|
||||
title="play"
|
||||
style={{
|
||||
display: 'inline-block',
|
||||
marginRight: '20px',
|
||||
cursor: 'pointer',
|
||||
}}
|
||||
onClick={() => {
|
||||
//缓存所有animate后执行
|
||||
if (!WAIT) {
|
||||
WAIT = true;
|
||||
props.config.waitAnimate = true;
|
||||
const cache = data.map((v) => {
|
||||
return v.animate;
|
||||
});
|
||||
const cloneData: IStoreData = deepcopy(store.getData());
|
||||
cloneData.block.forEach((v) => {
|
||||
v.animate = [];
|
||||
});
|
||||
store.setData(cloneData);
|
||||
setTimeout(() => {
|
||||
const cloneData: IStoreData = deepcopy(store.getData());
|
||||
cloneData.block.forEach((v, i) => {
|
||||
v.animate = cache[i];
|
||||
});
|
||||
WAIT = false;
|
||||
props.config.waitAnimate = false;
|
||||
store.setData(cloneData);
|
||||
store.cleanLast();
|
||||
});
|
||||
}
|
||||
}}
|
||||
>
|
||||
<PlayCircleOutlined />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
{content}
|
||||
</div>
|
||||
@@ -330,7 +396,7 @@ export function TimeLine(props: TimeLineProps) {
|
||||
position: 'relative',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
{/* <div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
transform: `translate(-${scrollx}px, 0px)`,
|
||||
@@ -342,7 +408,7 @@ export function TimeLine(props: TimeLineProps) {
|
||||
transition: 'left linear',
|
||||
willChange: 'left',
|
||||
}}
|
||||
></div>
|
||||
></div> */}
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
|
@@ -348,6 +348,8 @@ export class UserConfig {
|
||||
public focusState = focusState;
|
||||
public collapsed = false;
|
||||
public ticker = true;
|
||||
public containerOverFlow = true;
|
||||
public containerForceUpdate = () => {};
|
||||
public timeline = false;
|
||||
public timelineConfig: TimeLineConfigType = {
|
||||
autoFocus: true,
|
||||
@@ -357,6 +359,7 @@ export class UserConfig {
|
||||
status: 'stop',
|
||||
runFunc: () => {},
|
||||
resetFunc: () => {},
|
||||
current: 0,
|
||||
};
|
||||
public waitAnimate = false;
|
||||
public wrapperMoveState = wrapperMoveState;
|
||||
|
@@ -43,6 +43,5 @@ export function createBlock(
|
||||
value: 0,
|
||||
canRotate: true,
|
||||
},
|
||||
animatePlayState: ComponentItem.initData.animatePlayState || '',
|
||||
};
|
||||
}
|
||||
|
@@ -51,6 +51,5 @@ export interface IBlockType {
|
||||
canRotate: boolean;
|
||||
};
|
||||
animate: AnimateItem[];
|
||||
animatePlayState: string;
|
||||
fixed: boolean; // 用于制作fixed组件
|
||||
}
|
||||
|
@@ -46,7 +46,6 @@ function createDefaultModalBlock(): IStoreData['block'] {
|
||||
value: 0,
|
||||
canRotate: false,
|
||||
},
|
||||
animatePlayState: '',
|
||||
},
|
||||
];
|
||||
}
|
||||
|
@@ -49,4 +49,5 @@ export const en: typeof zhCN = {
|
||||
'error.minmax': 'The maximum value should be greater than or equal to the minimum value',
|
||||
'settings.marklineColor': 'Markline color',
|
||||
'settings.marklineStyle': 'Markline style',
|
||||
'settings.containerOverflow': 'Container Overflow',
|
||||
};
|
||||
|
@@ -46,4 +46,5 @@ export const zhCN = {
|
||||
'error.minmax': '最大值应大于等于最小值',
|
||||
'settings.marklineColor': '辅助线颜色',
|
||||
'settings.marklineStyle': '辅助线样式',
|
||||
'settings.containerOverflow': '容器边界外不显示元素',
|
||||
};
|
||||
|
Reference in New Issue
Block a user