feat: before update animate

This commit is contained in:
hufeixiong
2022-01-27 16:34:07 +08:00
parent 5629f2755d
commit 8c079e20ba
14 changed files with 183 additions and 86 deletions

View File

@@ -1,3 +1,13 @@
## 0.11.11
修复动画导致旋转预览不生效。
新增容器overflow配置。
timeline部分样式调整。
example部分样式调整。
## 0.11.10
新增对markline颜色样式设置

View File

@@ -155,8 +155,5 @@ MIT
## Todo
文档更新
重构动画
脚手架
基础组件库

View File

@@ -351,7 +351,6 @@ function AnimateControl(props: AnimateControlProps) {
}
});
store.setData(cloneData);
props.config.timelineNeedleConfig.resetFunc();
}}
>

View File

@@ -1,5 +1,5 @@
{
"version": "0.11.10",
"version": "0.11.11",
"license": "MIT",
"main": "dist/index.js",
"module": "dist/dooringx-lib.esm.js",

View File

@@ -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,

View File

@@ -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,
}}

View File

@@ -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>
);

View File

@@ -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',

View File

@@ -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;

View File

@@ -43,6 +43,5 @@ export function createBlock(
value: 0,
canRotate: true,
},
animatePlayState: ComponentItem.initData.animatePlayState || '',
};
}

View File

@@ -51,6 +51,5 @@ export interface IBlockType {
canRotate: boolean;
};
animate: AnimateItem[];
animatePlayState: string;
fixed: boolean; // 用于制作fixed组件
}

View File

@@ -46,7 +46,6 @@ function createDefaultModalBlock(): IStoreData['block'] {
value: 0,
canRotate: false,
},
animatePlayState: '',
},
];
}

View File

@@ -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',
};

View File

@@ -46,4 +46,5 @@ export const zhCN = {
'error.minmax': '最大值应大于等于最小值',
'settings.marklineColor': '辅助线颜色',
'settings.marklineStyle': '辅助线样式',
'settings.containerOverflow': '容器边界外不显示元素',
};