Skip to content

feat: css units in fly & blur transitions #7623

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Mar 15, 2023
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
7 changes: 4 additions & 3 deletions site/content/docs/04-run-time.md
Original file line number Diff line number Diff line change
Expand Up @@ -670,7 +670,7 @@ Animates a `blur` filter alongside an element's opacity.
* `duration` (`number`, default 400) — milliseconds the transition lasts
* `easing` (`function`, default `cubicInOut`) — an [easing function](/docs#run-time-svelte-easing)
* `opacity` (`number`, default 0) - the opacity value to animate out to and in from
* `amount` (`number`, default 5) - the size of the blur in pixels
* `amount` (`number | string`, default 5) - the size of the blur. Supports css units (for example: `"4rem"`). The default unit is `px`

```sv
<script>
Expand Down Expand Up @@ -705,10 +705,11 @@ Animates the x and y positions and the opacity of an element. `in` transitions a
* `delay` (`number`, default 0) — milliseconds before starting
* `duration` (`number`, default 400) — milliseconds the transition lasts
* `easing` (`function`, default `cubicOut`) — an [easing function](/docs#run-time-svelte-easing)
* `x` (`number`, default 0) - the x offset to animate out to and in from
* `y` (`number`, default 0) - the y offset to animate out to and in from
* `x` (`number | string`, default 0) - the x offset to animate out to and in from
* `y` (`number | string`, default 0) - the y offset to animate out to and in from
* `opacity` (`number`, default 0) - the opacity value to animate out to and in from

x and y use `px` by default but support css units, for example `x: '100vw'` or `y: '50%'`.
You can see the `fly` transition in action in the [transition tutorial](/tutorial/adding-parameters-to-transitions).

```sv
Expand Down
5 changes: 5 additions & 0 deletions src/runtime/internal/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,3 +189,8 @@ export const has_prop = (obj, prop) => Object.prototype.hasOwnProperty.call(obj,
export function action_destroyer(action_result) {
return action_result && is_function(action_result.destroy) ? action_result.destroy : noop;
}

export function split_css_unit(value: number | string): [number, string] {
const split = typeof value === 'string' && value.match(/^\s*(-?[\d.]+)([^\s]*)\s*$/);
return split ? [parseFloat(split[1]), split[2] || 'px'] : [value as number, 'px'];
}
17 changes: 9 additions & 8 deletions src/runtime/transition/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { cubicOut, cubicInOut, linear } from 'svelte/easing';
import { assign, is_function } from 'svelte/internal';
import { assign, split_css_unit, is_function } from 'svelte/internal';

export type EasingFunction = (t: number) => number;

Expand All @@ -15,7 +15,7 @@ export interface BlurParams {
delay?: number;
duration?: number;
easing?: EasingFunction;
amount?: number;
amount?: number | string;
opacity?: number;
}

Expand All @@ -31,12 +31,12 @@ export function blur(node: Element, {
const f = style.filter === 'none' ? '' : style.filter;

const od = target_opacity * (1 - opacity);

const [value, unit] = split_css_unit(amount);
return {
delay,
duration,
easing,
css: (_t, u) => `opacity: ${target_opacity - (od * u)}; filter: ${f} blur(${u * amount}px);`
css: (_t, u) => `opacity: ${target_opacity - (od * u)}; filter: ${f} blur(${u * value}${unit});`
};
}

Expand Down Expand Up @@ -65,8 +65,8 @@ export interface FlyParams {
delay?: number;
duration?: number;
easing?: EasingFunction;
x?: number;
y?: number;
x?: number | string;
y?: number | string;
opacity?: number;
}

Expand All @@ -83,13 +83,14 @@ export function fly(node: Element, {
const transform = style.transform === 'none' ? '' : style.transform;

const od = target_opacity * (1 - opacity);

const [xValue, xUnit] = split_css_unit(x);
const [yValue, yUnit] = split_css_unit(y);
return {
delay,
duration,
easing,
css: (t, u) => `
transform: ${transform} translate(${(1 - t) * x}px, ${(1 - t) * y}px);
transform: ${transform} translate(${(1 - t) * xValue}${xUnit}, ${(1 - t) * yValue}${yUnit});
opacity: ${target_opacity - (od * u)}`
};
}
Expand Down
14 changes: 14 additions & 0 deletions test/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as assert from 'assert';
import { trim_start, trim_end } from '../../src/compiler/utils/trim';
import { split_css_unit } from '../../src/runtime/internal/utils';

describe('utils', () => {
describe('trim', () => {
Expand All @@ -13,4 +14,17 @@ describe('utils', () => {
assert.equal(value, ' \r\n\t svelte content');
});
});

describe('split_css_unit', () => {
it('should use px as default', () => {
assert.deepEqual(split_css_unit(10), [10, 'px']);
assert.deepEqual(split_css_unit('10'), [10, 'px']);
});

it('should split the css notation into value and unit', () => {
assert.deepEqual(split_css_unit('-50%'), [-50, '%']);
assert.deepEqual(split_css_unit('0.1rem'), [0.1, 'rem']);
assert.deepEqual(split_css_unit('.1rem'), [0.1, 'rem']);
});
});
});