generic animation interrupt
This commit is contained in:
parent
1bd42742f4
commit
dc12340294
|
|
@ -281,22 +281,7 @@ export class RecordPlayer extends HTMLElement {
|
||||||
|
|
||||||
const arm = this.shadowRoot!.querySelector('.tone-arm') as HTMLElement;
|
const arm = this.shadowRoot!.querySelector('.tone-arm') as HTMLElement;
|
||||||
|
|
||||||
const animation = arm.getAnimations()[0];
|
reverseAnimation(arm);
|
||||||
|
|
||||||
if (animation) {
|
|
||||||
animation.commitStyles();
|
|
||||||
animation.cancel();
|
|
||||||
const rotate = arm.style.rotate;
|
|
||||||
arm.style.rotate = '';
|
|
||||||
arm.animate(
|
|
||||||
[
|
|
||||||
{ offset: 0, rotate },
|
|
||||||
{ offset: 0.2, rotate, transform: 'rotateX(20deg)' },
|
|
||||||
{ offset: 0.8, transform: 'rotateX(20deg)' },
|
|
||||||
],
|
|
||||||
{ duration: 3000 }
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
clearTimeout(this.#playTimeout);
|
clearTimeout(this.#playTimeout);
|
||||||
this.#internals.states.delete('playing');
|
this.#internals.states.delete('playing');
|
||||||
|
|
@ -332,3 +317,72 @@ export class RecordPlayer extends HTMLElement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function reverseAnimation(el: HTMLElement) {
|
||||||
|
const animation = el.getAnimations()[0];
|
||||||
|
|
||||||
|
if (!animation || !(animation.effect instanceof KeyframeEffect)) return;
|
||||||
|
|
||||||
|
const originalStyles = createStyleMap(el.getAttribute('style') || '');
|
||||||
|
|
||||||
|
animation.commitStyles();
|
||||||
|
animation.cancel();
|
||||||
|
|
||||||
|
const animationStyles = createStyleMap(el.getAttribute('style') || '');
|
||||||
|
|
||||||
|
const changedProperties = diffStyles(originalStyles, animationStyles);
|
||||||
|
|
||||||
|
// reset styles
|
||||||
|
for (const property of changedProperties) {
|
||||||
|
el.style.setProperty(property, originalStyles.get(property) || '');
|
||||||
|
}
|
||||||
|
|
||||||
|
// reverse current animation
|
||||||
|
const { progress = 0 } = animation.effect.getComputedTiming();
|
||||||
|
const keyframes = animation.effect.getKeyframes();
|
||||||
|
|
||||||
|
const rotate = animationStyles.get('rotate') || 0;
|
||||||
|
|
||||||
|
// TODO: dont hard code this
|
||||||
|
el.animate(
|
||||||
|
[
|
||||||
|
{ offset: 0, rotate },
|
||||||
|
{ offset: 0.2, rotate, transform: 'rotateX(20deg)' },
|
||||||
|
{ offset: 0.8, transform: 'rotateX(20deg)' },
|
||||||
|
],
|
||||||
|
{ duration: 3000 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function createStyleMap(style: string): Map<string, string> {
|
||||||
|
const stylesMaps = new Map<string, string>();
|
||||||
|
|
||||||
|
for (const declaration of style.split(';')) {
|
||||||
|
if (declaration.length > 0) {
|
||||||
|
const [property, value] = declaration.split(':');
|
||||||
|
stylesMaps.set(property.trim(), value.trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return stylesMaps;
|
||||||
|
}
|
||||||
|
|
||||||
|
function diffStyles(stylesA: Map<string, string>, stylesB: Map<string, string>): Set<string> {
|
||||||
|
const changedProperties = new Set<string>();
|
||||||
|
|
||||||
|
stylesA.forEach((valueA, property) => {
|
||||||
|
const valueB = stylesB.get(property);
|
||||||
|
|
||||||
|
if (valueB === undefined || valueA !== valueB) {
|
||||||
|
changedProperties.add(property);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
stylesB.forEach((_, property) => {
|
||||||
|
if (!changedProperties.has(property)) {
|
||||||
|
changedProperties.add(property);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return changedProperties;
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue