add tmp
This commit is contained in:
@@ -1,9 +1,10 @@
|
|||||||
import React, { useMemo } from 'react';
|
import React, { useMemo, useState } from 'react';
|
||||||
import { UserConfig, deepCopy, createUid } from 'dooringx-lib';
|
import { UserConfig, deepCopy, createUid } from 'dooringx-lib';
|
||||||
import { Col, Row, Select, InputNumber, Button } from 'antd';
|
import { Col, Row, Select, InputNumber, Button, Modal, Form, Space, Input } 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 { AnimateItem, IBlockType, IStoreData } from 'dooringx-lib/dist/core/store/storetype';
|
import { AnimateItem, IBlockType, IStoreData } from 'dooringx-lib/dist/core/store/storetype';
|
||||||
|
import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
|
||||||
|
|
||||||
export interface FormAnimateControlType extends FormBaseType {}
|
export interface FormAnimateControlType extends FormBaseType {}
|
||||||
|
|
||||||
@@ -134,167 +135,176 @@ function AnimateControl(props: AnimateControlProps) {
|
|||||||
lastAnimate = props.current.animate;
|
lastAnimate = props.current.animate;
|
||||||
return props.current.animate;
|
return props.current.animate;
|
||||||
}, [props.current.animate]);
|
}, [props.current.animate]);
|
||||||
|
|
||||||
|
const [customModal, setCustomModal] = useState(false);
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{animate.map((v, i) => {
|
{animate.map((v, i) => {
|
||||||
return (
|
return (
|
||||||
<div key={v.uid} style={{ borderBottom: '1px dotted #9e9e9e' }}>
|
<div key={v.uid} style={{ borderBottom: '1px dotted #9e9e9e' }}>
|
||||||
<Row style={{ padding: padding, alignItems: 'center' }}>
|
{v.isCustom && <div>自定义</div>}
|
||||||
<Col span={5}>动画名称:</Col>
|
{!v.isCustom && (
|
||||||
<Col span={7}>
|
<>
|
||||||
<Select
|
<Row style={{ padding: padding, alignItems: 'center' }}>
|
||||||
value={animate[i].animationName}
|
<Col span={5}>动画名称:</Col>
|
||||||
style={{ width: '100%' }}
|
<Col span={7}>
|
||||||
onChange={(d) => {
|
<Select
|
||||||
const cloneData: IStoreData = deepCopy(store.getData());
|
value={animate[i].animationName}
|
||||||
cloneData.block.forEach((w) => {
|
style={{ width: '100%' }}
|
||||||
if (w.id === props.current.id) {
|
onChange={(d) => {
|
||||||
w.animate.forEach((f) => {
|
const cloneData: IStoreData = deepCopy(store.getData());
|
||||||
if (f.uid === v.uid) {
|
cloneData.block.forEach((w) => {
|
||||||
f.animationName = d;
|
if (w.id === props.current.id) {
|
||||||
|
w.animate.forEach((f) => {
|
||||||
|
if (f.uid === v.uid) {
|
||||||
|
f.animationName = d;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
store.setData(cloneData);
|
||||||
});
|
}}
|
||||||
store.setData(cloneData);
|
>
|
||||||
}}
|
{Object.keys(animateCategory).map((v, i) => {
|
||||||
>
|
return (
|
||||||
{Object.keys(animateCategory).map((v, i) => {
|
<Select.Option key={i} value={animateCategory[v]}>
|
||||||
return (
|
{animateCategory[v]}
|
||||||
<Select.Option key={i} value={animateCategory[v]}>
|
</Select.Option>
|
||||||
{animateCategory[v]}
|
);
|
||||||
</Select.Option>
|
})}
|
||||||
);
|
</Select>
|
||||||
})}
|
</Col>
|
||||||
</Select>
|
<Col span={5} style={{ paddingLeft: '10px' }}>
|
||||||
</Col>
|
持续时间:
|
||||||
<Col span={5} style={{ paddingLeft: '10px' }}>
|
</Col>
|
||||||
持续时间:
|
<Col span={7}>
|
||||||
</Col>
|
<InputNumber
|
||||||
<Col span={7}>
|
style={{ width: '100%' }}
|
||||||
<InputNumber
|
step="0.1"
|
||||||
style={{ width: '100%' }}
|
value={animate[i].animationDuration}
|
||||||
step="0.1"
|
formatter={(value) => `${value}s`}
|
||||||
value={animate[i].animationDuration}
|
min={0}
|
||||||
formatter={(value) => `${value}s`}
|
onChange={(d) => {
|
||||||
min={0}
|
const cloneData: IStoreData = deepCopy(store.getData());
|
||||||
onChange={(d) => {
|
cloneData.block.forEach((w) => {
|
||||||
const cloneData: IStoreData = deepCopy(store.getData());
|
if (w.id === props.current.id) {
|
||||||
cloneData.block.forEach((w) => {
|
w.animate.forEach((f) => {
|
||||||
if (w.id === props.current.id) {
|
if (f.uid === v.uid) {
|
||||||
w.animate.forEach((f) => {
|
f.animationDuration = d;
|
||||||
if (f.uid === v.uid) {
|
}
|
||||||
f.animationDuration = d;
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
store.setData(cloneData);
|
||||||
});
|
}}
|
||||||
store.setData(cloneData);
|
/>
|
||||||
}}
|
</Col>
|
||||||
/>
|
</Row>
|
||||||
</Col>
|
<Row style={{ padding: padding, alignItems: 'center' }}>
|
||||||
</Row>
|
<Col span={5}>延迟时间:</Col>
|
||||||
<Row style={{ padding: padding, alignItems: 'center' }}>
|
<Col span={7}>
|
||||||
<Col span={5}>延迟时间:</Col>
|
<InputNumber
|
||||||
<Col span={7}>
|
style={{ width: '100%' }}
|
||||||
<InputNumber
|
value={animate[i].animationDelay}
|
||||||
style={{ width: '100%' }}
|
formatter={(value) => `${value}s`}
|
||||||
value={animate[i].animationDelay}
|
min={0}
|
||||||
formatter={(value) => `${value}s`}
|
step="0.1"
|
||||||
min={0}
|
onChange={(d) => {
|
||||||
step="0.1"
|
const cloneData: IStoreData = deepCopy(store.getData());
|
||||||
onChange={(d) => {
|
cloneData.block.forEach((w) => {
|
||||||
const cloneData: IStoreData = deepCopy(store.getData());
|
if (w.id === props.current.id) {
|
||||||
cloneData.block.forEach((w) => {
|
w.animate.forEach((f) => {
|
||||||
if (w.id === props.current.id) {
|
if (f.uid === v.uid) {
|
||||||
w.animate.forEach((f) => {
|
f.animationDelay = d;
|
||||||
if (f.uid === v.uid) {
|
}
|
||||||
f.animationDelay = d;
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
store.setData(cloneData);
|
||||||
});
|
}}
|
||||||
store.setData(cloneData);
|
/>
|
||||||
}}
|
</Col>
|
||||||
/>
|
<Col span={5} style={{ paddingLeft: '10px' }}>
|
||||||
</Col>
|
重复次数:
|
||||||
<Col span={5} style={{ paddingLeft: '10px' }}>
|
</Col>
|
||||||
重复次数:
|
<Col span={7}>
|
||||||
</Col>
|
<Select
|
||||||
<Col span={7}>
|
value={animate[i].animationIterationCount}
|
||||||
<Select
|
style={{ width: '100%' }}
|
||||||
value={animate[i].animationIterationCount}
|
onChange={(d) => {
|
||||||
style={{ width: '100%' }}
|
const cloneData: IStoreData = deepCopy(store.getData());
|
||||||
onChange={(d) => {
|
cloneData.block.forEach((w) => {
|
||||||
const cloneData: IStoreData = deepCopy(store.getData());
|
if (w.id === props.current.id) {
|
||||||
cloneData.block.forEach((w) => {
|
w.animate.forEach((f) => {
|
||||||
if (w.id === props.current.id) {
|
if (f.uid === v.uid) {
|
||||||
w.animate.forEach((f) => {
|
f.animationIterationCount = d;
|
||||||
if (f.uid === v.uid) {
|
}
|
||||||
f.animationIterationCount = d;
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
store.setData(cloneData);
|
||||||
});
|
}}
|
||||||
store.setData(cloneData);
|
>
|
||||||
}}
|
{repeat.map((v, i) => {
|
||||||
>
|
return (
|
||||||
{repeat.map((v, i) => {
|
<Select.Option key={i} value={v}>
|
||||||
return (
|
{v}
|
||||||
<Select.Option key={i} value={v}>
|
</Select.Option>
|
||||||
{v}
|
);
|
||||||
</Select.Option>
|
})}
|
||||||
);
|
</Select>
|
||||||
})}
|
</Col>
|
||||||
</Select>
|
</Row>
|
||||||
</Col>
|
<Row style={{ padding: padding, alignItems: 'center' }}>
|
||||||
</Row>
|
<Col span={5}>运动函数:</Col>
|
||||||
<Row style={{ padding: padding, alignItems: 'center' }}>
|
<Col span={7}>
|
||||||
<Col span={5}>运动函数:</Col>
|
<Select
|
||||||
<Col span={7}>
|
value={animate[i].animationTimingFunction}
|
||||||
<Select
|
style={{ width: '100%' }}
|
||||||
value={animate[i].animationTimingFunction}
|
onChange={(d) => {
|
||||||
style={{ width: '100%' }}
|
const cloneData: IStoreData = deepCopy(store.getData());
|
||||||
onChange={(d) => {
|
cloneData.block.forEach((w) => {
|
||||||
const cloneData: IStoreData = deepCopy(store.getData());
|
if (w.id === props.current.id) {
|
||||||
cloneData.block.forEach((w) => {
|
w.animate.forEach((f) => {
|
||||||
if (w.id === props.current.id) {
|
if (f.uid === v.uid) {
|
||||||
w.animate.forEach((f) => {
|
f.animationTimingFunction = d;
|
||||||
if (f.uid === v.uid) {
|
}
|
||||||
f.animationTimingFunction = d;
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
store.setData(cloneData);
|
||||||
});
|
}}
|
||||||
store.setData(cloneData);
|
>
|
||||||
}}
|
{Object.keys(timeFunction).map((v, i) => {
|
||||||
>
|
return (
|
||||||
{Object.keys(timeFunction).map((v, i) => {
|
<Select.Option key={i} value={timeFunction[v]}>
|
||||||
return (
|
{v}
|
||||||
<Select.Option key={i} value={timeFunction[v]}>
|
</Select.Option>
|
||||||
{v}
|
);
|
||||||
</Select.Option>
|
})}
|
||||||
);
|
</Select>
|
||||||
})}
|
</Col>
|
||||||
</Select>
|
<Col style={{ justifyContent: 'flex-end', flex: 1, textAlign: 'end' }}>
|
||||||
</Col>
|
<Button
|
||||||
<Col style={{ justifyContent: 'flex-end', flex: 1, textAlign: 'end' }}>
|
danger
|
||||||
<Button
|
onClick={() => {
|
||||||
danger
|
const cloneData: IStoreData = deepCopy(store.getData());
|
||||||
onClick={() => {
|
cloneData.block.map((v) => {
|
||||||
const cloneData: IStoreData = deepCopy(store.getData());
|
if (v.id === props.current.id) {
|
||||||
cloneData.block.map((v) => {
|
v.animate.splice(i, 1);
|
||||||
if (v.id === props.current.id) {
|
}
|
||||||
v.animate.splice(i, 1);
|
});
|
||||||
}
|
store.setData(cloneData);
|
||||||
});
|
}}
|
||||||
store.setData(cloneData);
|
>
|
||||||
}}
|
删除
|
||||||
>
|
</Button>
|
||||||
删除
|
</Col>
|
||||||
</Button>
|
</Row>
|
||||||
</Col>
|
</>
|
||||||
</Row>
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
@@ -356,8 +366,68 @@ function AnimateControl(props: AnimateControlProps) {
|
|||||||
>
|
>
|
||||||
添加动画
|
添加动画
|
||||||
</Button>
|
</Button>
|
||||||
<Button>添加自定义动画</Button>
|
<Button
|
||||||
|
onClick={() => {
|
||||||
|
setCustomModal(true);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
添加自定义动画
|
||||||
|
</Button>
|
||||||
</Row>
|
</Row>
|
||||||
|
<Modal
|
||||||
|
width={800}
|
||||||
|
title={'设置自定义动画'}
|
||||||
|
forceRender
|
||||||
|
visible={customModal}
|
||||||
|
onOk={() => {
|
||||||
|
console.log('ok', form.getFieldsValue());
|
||||||
|
}}
|
||||||
|
onCancel={() => {
|
||||||
|
setCustomModal(false);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Form form={form}>
|
||||||
|
<Col>
|
||||||
|
<Form.Item name={'kkk'} label="解决">
|
||||||
|
<Select></Select>
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col>
|
||||||
|
<Form.Item name={'dfd'} label="解决">
|
||||||
|
<Select></Select>
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Form.List name="users">
|
||||||
|
{(fields, { add, remove }) => (
|
||||||
|
<>
|
||||||
|
{fields.map(({ key, name, ...restField }) => (
|
||||||
|
<Space key={key} style={{ display: 'flex', marginBottom: 8 }} align="baseline">
|
||||||
|
<Form.Item label="坐标" {...restField} name={[name, 'xx']}>
|
||||||
|
<Input placeholder="First Name" />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="坐标" {...restField} name={[name, 'cc']}>
|
||||||
|
<Input placeholder="Last Name" />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="坐标" {...restField} name={[name, '坐标']}>
|
||||||
|
<Input placeholder="First Name" />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="坐标" {...restField} name={[name, '旋转']}>
|
||||||
|
<Input placeholder="Last Name" />
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
|
<MinusCircleOutlined onClick={() => remove(name)} />
|
||||||
|
</Space>
|
||||||
|
))}
|
||||||
|
<Form.Item>
|
||||||
|
<Button type="dashed" onClick={() => add()} block icon={<PlusOutlined />}>
|
||||||
|
Add field
|
||||||
|
</Button>
|
||||||
|
</Form.Item>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Form.List>
|
||||||
|
</Form>
|
||||||
|
</Modal>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
42
packages/dooringx-lib/src/core/dynamicAnimate/index.ts
Normal file
42
packages/dooringx-lib/src/core/dynamicAnimate/index.ts
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
// 批量情况
|
||||||
|
|
||||||
|
export class DynamicAnimate {
|
||||||
|
getStyleSheets() {
|
||||||
|
return document.styleSheets;
|
||||||
|
}
|
||||||
|
|
||||||
|
inserKeyframeAnimate(ruleText: string, keyframeName: string) {
|
||||||
|
const sheets = this.getStyleSheets();
|
||||||
|
if (sheets.length === 0) {
|
||||||
|
let style = document.createElement('style');
|
||||||
|
style.appendChild(document.createTextNode(''));
|
||||||
|
document.head.appendChild(style);
|
||||||
|
}
|
||||||
|
const len = sheets.length;
|
||||||
|
let ss: number | null = null;
|
||||||
|
let st: number | null = null;
|
||||||
|
for (let i = 0; i < len; i++) {
|
||||||
|
for (let k = 0; k < sheets[i].cssRules.length; k++) {
|
||||||
|
const rule = sheets[i].cssRules[k] as CSSKeyframesRule;
|
||||||
|
const name = rule?.name;
|
||||||
|
if (name && name === keyframeName) {
|
||||||
|
// 删除该keyframe
|
||||||
|
ss = i;
|
||||||
|
st = k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ss !== null && st !== null) {
|
||||||
|
sheets[ss].deleteRule(st);
|
||||||
|
}
|
||||||
|
let sheet = sheets[ss ? ss : sheets.length - 1] as CSSStyleSheet;
|
||||||
|
sheet.insertRule(ruleText, sheet.rules ? sheet.rules.length : sheet.cssRules.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
fromObjInsertKeyFrame(obj: Record<string, string>) {
|
||||||
|
// name 唯一
|
||||||
|
Object.keys(obj).forEach((v) => {
|
||||||
|
this.inserKeyframeAnimate(obj[v], v);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@@ -27,6 +27,7 @@ export interface AnimateItem {
|
|||||||
animationIterationCount: string;
|
animationIterationCount: string;
|
||||||
animationTimingFunction: string;
|
animationTimingFunction: string;
|
||||||
isCustom?: boolean;
|
isCustom?: boolean;
|
||||||
|
customKeyFrame?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IBlockType {
|
export interface IBlockType {
|
||||||
|
Reference in New Issue
Block a user