This commit is contained in:
hufeixiong
2022-03-29 18:02:59 +08:00
parent a1d6c398b6
commit 3495aa7956
3 changed files with 262 additions and 149 deletions

View File

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

View 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);
});
}
}

View File

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