Skip to content
This repository has been archived by the owner on May 11, 2023. It is now read-only.

fix: improve derivation of style for controller.set #112

Merged
merged 1 commit into from
Jan 29, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions __tests__/parsers/derive-style.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { deriveStyle } from '../../src/parsers';

describe('deriveStyle', () => {
it('should derive the style of an animating element from its style property (number)', () => {
const el = document.createElement('div');
el.style.opacity = '0.5';

const { from } = deriveStyle(el, { opacity: 1 });

expect(from).toEqual({ opacity: 0.5 });
});

it('should derive the style of an animating element from its style property (string)', () => {
const el = document.createElement('div');
el.style.width = '25rem';

const { from } = deriveStyle(el, { width: '12.5rem' });

expect(from).toEqual({ width: '25rem' });
});

it('should use the computed style of an animating element no style can be found on the style property (number)', () => {
const el = document.createElement('div');

const getPropertyValueMock = jest.fn();
const getComputedStyleSpy = jest
.spyOn(window, 'getComputedStyle')
.mockImplementation(
() =>
(({
getPropertyValue: getPropertyValueMock,
} as unknown) as CSSStyleDeclaration)
);

deriveStyle(el, { opacity: 0 });

expect(getComputedStyleSpy).toHaveBeenCalledWith(el);
expect(getPropertyValueMock).toHaveBeenCalledWith('opacity');
});

it('should build a transfrom with animatable none values to match to values', () => {
const el = document.createElement('div');

const { from } = deriveStyle(el, {
transform: 'rotate(360deg) scale(1.5) perspective(200px)',
});

expect(from).toEqual({
transform: 'rotate(0deg) scale(1) perspective(0px)',
});
});

it('should merge currently applied transforms into the from value', () => {
const el = document.createElement('div');
el.style.transform = 'translateX(100px)';

const { from } = deriveStyle(el, {
transform: 'rotate(360deg) scale(1.5) perspective(200px)',
});

expect(from).toEqual({
transform: 'translateX(100px) rotate(0deg) scale(1) perspective(0px)',
});
});

it('should build a transform with animatable none values to match from values', () => {
const el = document.createElement('div');
el.style.transform = 'translateX(100px) skewY(1rad)';

const { from, to } = deriveStyle(el, {
transform: 'rotate(360deg) scale(1.5) perspective(200px)',
});

expect(from).toEqual({
transform:
'translateX(100px) skewY(1rad) rotate(0deg) scale(1) perspective(0px)',
});
expect(to).toEqual({
transform:
'rotate(360deg) scale(1.5) perspective(200px) translateX(0px) skewY(0rad)',
});
});
});
11 changes: 8 additions & 3 deletions src/parsers/derive-style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@ export const deriveStyle = (

return Object.entries(to).reduce(
(acc, [property, value]) => {
const currentValue = currentStyle.getPropertyValue(property);

// The computed value of transform is always returned as a matrix.
// To prevent having to reverse parse the matrix, we build a transform
// string from the sparse set of transforms present on style, if any.
if (property === 'transform') {
const currentValue = currentStyle.getPropertyValue(property);
const { from: fromTransform, to: toTransform } = deriveTransforms(
currentValue,
to[property] ?? ''
Expand All @@ -34,10 +35,14 @@ export const deriveStyle = (
};
}

const fromValue = currentValue
? currentValue
: computedStyle.getPropertyValue(property);

const from =
typeof to[property as keyof CSSProperties] === 'number'
? parseFloat(computedStyle.getPropertyValue(property))
: computedStyle.getPropertyValue(property);
? parseFloat(fromValue)
: fromValue;

return {
from: {
Expand Down