-
Notifications
You must be signed in to change notification settings - Fork 171
/
Copy pathAnimatedGenericArrow.tsx
77 lines (67 loc) · 2.57 KB
/
AnimatedGenericArrow.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import { ArrowConfig } from 'konva/lib/shapes/Arrow';
import { PathConfig } from 'konva/lib/shapes/Path';
import { Group } from 'react-konva';
import { SharedProperties } from 'src/commons/utils/TypeHelper';
import { GenericArrow } from '../../components/arrows/GenericArrow';
import { Visible } from '../../components/Visible';
import { defaultStrokeColor, reachedStrokeColor } from '../../CseMachineUtils';
import { Animatable, AnimatableTo, AnimationConfig } from './Animatable';
import { AnimatedArrowComponent, AnimatedPathComponent } from './AnimationComponents';
type PathArrowSharedConfig = Omit<SharedProperties<PathConfig, ArrowConfig>, 'width' | 'height'>;
export class AnimatedGenericArrow<
Source extends Visible,
Target extends Visible
> extends AnimatableTo<PathArrowSharedConfig> {
private pathComponent: AnimatedPathComponent;
private arrowComponent: AnimatedArrowComponent;
private onPropsChange = (props: PathConfig) => {
if (props.x) this._x = this.arrow.x() + props.x;
if (props.y) this._y = this.arrow.y() + props.y;
};
constructor(
private arrow: GenericArrow<Source, Target>,
props?: PathArrowSharedConfig
) {
super();
this._x = arrow.x();
this._y = arrow.y();
this._width = arrow.width();
this._height = arrow.height();
this.pathComponent = new AnimatedPathComponent({
stroke: arrow.source.isReachable() ? reachedStrokeColor() : defaultStrokeColor(),
data: arrow.path(),
...props
});
this.pathComponent.addListener(this.onPropsChange);
this.arrowComponent = new AnimatedArrowComponent({
fill: arrow.source.isReachable() ? reachedStrokeColor() : defaultStrokeColor(),
points: arrow.points.slice(arrow.points.length - 4),
...props
});
}
draw(): React.ReactNode {
return (
<Group ref={this.ref} key={Animatable.key--}>
{this.pathComponent.draw()}
{this.arrowComponent.draw()}
</Group>
);
}
animatePathTo(to: Partial<PathConfig>, animationConfig?: AnimationConfig) {
return this.pathComponent.animateTo(to, animationConfig);
}
animateArrowTo(to: Partial<ArrowConfig>, animationConfig?: AnimationConfig) {
return this.arrowComponent.animateTo(to, animationConfig);
}
async animateTo(to: Partial<PathArrowSharedConfig>, animationConfig?: AnimationConfig) {
await Promise.all([
this.animatePathTo(to, animationConfig),
this.animateArrowTo(to, animationConfig)
]);
}
destroy() {
this.pathComponent.removeListener(this.onPropsChange);
this.pathComponent.destroy();
this.arrowComponent.destroy();
}
}