Skip to content

Commit

Permalink
fix: player多次渲染& 子组件更新
Browse files Browse the repository at this point in the history
  • Loading branch information
xuying.xu committed Mar 27, 2024
1 parent c329c03 commit 49760ed
Show file tree
Hide file tree
Showing 4 changed files with 162 additions and 4 deletions.
4 changes: 4 additions & 0 deletions packages/f-engine/src/canvas/timeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ class Timeline {
this.play = playComponent;
}

clear() {
const { frame } = this;
this.animations[frame] = [];
}
setPlayState(state) {
this.playState = state;
const { animator } = this.play;
Expand Down
27 changes: 25 additions & 2 deletions packages/f-engine/src/player.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { JSX } from './jsx/jsx-namespace';
import Component from './component';
import Timeline from './canvas/timeline';
import { generateFrameElement, playerFrame } from './playerFrames';
import equal from './canvas/equal';
import { IContext } from './types';

// 播放状态
type playState = 'play' | 'pause' | 'finish';
Expand All @@ -19,7 +21,7 @@ export interface PlayerProps {

keyFrames?: Record<string, playerFrame>[];
/**
* 播放结束
* 协议动画播放结束
*/
onend?: Function;
}
Expand All @@ -28,6 +30,11 @@ class Player extends Component<PlayerProps> {
playerFrames;
index: number;
onend: Function;
/**
* 协议动画状态 play pause finish
*/
isEnd: boolean;

constructor(props) {
super(props);
const { keyFrames = [], children } = props;
Expand Down Expand Up @@ -62,6 +69,7 @@ class Player extends Component<PlayerProps> {
const { animator, props } = this;
const { state } = props;
animator.on('end', this.next);

if (state === 'finish') {
this.setState(({ count }) => ({
index: count - 1,
Expand All @@ -81,16 +89,31 @@ class Player extends Component<PlayerProps> {
}
}

willReceiveProps(_nextProps: PlayerProps, _context?: IContext): void {
if (!equal(_nextProps, this.props)) {
this.playerFrames = _nextProps?.keyFrames.reduce((array, cur) => {
const frames = generateFrameElement(cur, array[array.length - 1] || _nextProps?.children);
array.push(frames);
return array;
}, []);
}
}

next = () => {
const { index, count } = this.state;
const { onend = () => {}, state } = this.props;
const { onend = () => { }, state } = this.props;
// @ts-ignore
const { timeline } = this.context;
timeline.clear();

if (this.isEnd) return
if (index < count - 1 && state === 'play') {
this.setState(() => ({
index: index + 1,
}));
} else {
onend();
this.isEnd = true
}
};

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
135 changes: 133 additions & 2 deletions packages/f-engine/test/timeline/keyFrames.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,22 @@ import { createContext, delay } from '../util';
describe('player', () => {
class View extends Component {
render() {

const {
width = '80px',
height = '80px',
opacity = 1,
fill = 'red',
visible = true,
fillFunc
} = this.props;
if (!visible) return;
return (
<rect
style={{
width,
height,
fill,
fill: fillFunc ? fillFunc() : fill ,
opacity,
}}
animation={{
Expand All @@ -29,7 +31,7 @@ describe('player', () => {
update: {
easing: 'linear',
duration: 500,
property: ['x', 'width', 'height'],
property: ['x', 'fill','width', 'height'],
},
}}
/>
Expand Down Expand Up @@ -275,6 +277,135 @@ describe('player', () => {
expect(context).toMatchImageSnapshot();
});

it('更新子组件 props', async () => {
const context = createContext('更新子组件 props');
const ref = { current: null };
const callback = jest.fn();
let color = "red"
const { props } = (
<Canvas context={context} >
<Player
state="play"
ref={ref}
onend={callback}
keyFrames={[
// 先出现,再变宽
{
view: {
to: {
visible: false,
width: '5px',
},
},
},
{
view: {
to: {
visible: true,
width: '80px',
},
},
},
]}
>
<View key={'view'} fillFunc={()=>{
return color
}}/>
</Player>
</Canvas>
);

const canvas = new Canvas(props);
await canvas.render();
await delay(2000);

color = "yellow"
const { props: nextProps } = (
<Canvas context={context}>
<Player
state="play"
keyFrames={[
// 先出现,再变宽
{
view: {
to: {
visible: false,
width: '5px',
},
},
},
{
view: {
to: {
visible: true,
width: '80px',
},
},
},
]}
onend={callback}
>
<View
key={'view'}
fillFunc={()=>{
return color
}}/>
</Player>
</Canvas>
);
canvas.update(nextProps)
await delay(2000);

expect(callback.mock.calls.length).toBe(1);
expect(context).toMatchImageSnapshot();
});

it('执行完清空动画', async () => {
const context = createContext('清空动画');
const ref = {current: null}
const { props } = (
<Canvas context={context}>
<Player
ref={ref}
state="play"
keyFrames={[
// 先出现,再变宽
{
view: {
to: {
visible: true,
},
},
},
{
view1: {
to: {
visible: true,
},
},
},
{
view1: {
to: {
visible: false,
},
},
},
]}
>
<group>
<View key={'view'} />
<View1 key={'view1'}></View1>
</group>
</Player>
</Canvas>
);

const canvas = new Canvas(props);
await canvas.render();
await delay(2000);
expect(ref.current.context.timeline.animations[0].length).toEqual(0)
});
it.skip('leave 动画', async () => {
const context = createContext('动画 finish');
const ref = { current: null };
Expand Down

0 comments on commit 49760ed

Please sign in to comment.