Skip to content

Commit 6aee49b

Browse files
bfangerBob Fangerdummdidummbenmccann
authored
feat: css units in fly & blur transitions (#7623)
Closes #6050 --------- Co-authored-by: Bob Fanger <[email protected]> Co-authored-by: Simon H <[email protected]> Co-authored-by: Ben McCann <[email protected]>
1 parent 8015a36 commit 6aee49b

File tree

4 files changed

+32
-11
lines changed

4 files changed

+32
-11
lines changed

site/content/docs/04-run-time.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -693,7 +693,7 @@ Animates a `blur` filter alongside an element's opacity.
693693
* `duration` (`number`, default 400) — milliseconds the transition lasts
694694
* `easing` (`function`, default `cubicInOut`) — an [easing function](/docs#run-time-svelte-easing)
695695
* `opacity` (`number`, default 0) - the opacity value to animate out to and in from
696-
* `amount` (`number`, default 5) - the size of the blur in pixels
696+
* `amount` (`number | string`, default 5) - the size of the blur. Supports css units (for example: `"4rem"`). The default unit is `px`
697697

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

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

737738
```sv

src/runtime/internal/utils.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,3 +189,8 @@ export const has_prop = (obj, prop) => Object.prototype.hasOwnProperty.call(obj,
189189
export function action_destroyer(action_result) {
190190
return action_result && is_function(action_result.destroy) ? action_result.destroy : noop;
191191
}
192+
193+
export function split_css_unit(value: number | string): [number, string] {
194+
const split = typeof value === 'string' && value.match(/^\s*(-?[\d.]+)([^\s]*)\s*$/);
195+
return split ? [parseFloat(split[1]), split[2] || 'px'] : [value as number, 'px'];
196+
}

src/runtime/transition/index.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { cubicOut, cubicInOut, linear } from 'svelte/easing';
2-
import { assign, is_function } from 'svelte/internal';
2+
import { assign, split_css_unit, is_function } from 'svelte/internal';
33

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

@@ -15,7 +15,7 @@ export interface BlurParams {
1515
delay?: number;
1616
duration?: number;
1717
easing?: EasingFunction;
18-
amount?: number;
18+
amount?: number | string;
1919
opacity?: number;
2020
}
2121

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

3333
const od = target_opacity * (1 - opacity);
34-
34+
const [value, unit] = split_css_unit(amount);
3535
return {
3636
delay,
3737
duration,
3838
easing,
39-
css: (_t, u) => `opacity: ${target_opacity - (od * u)}; filter: ${f} blur(${u * amount}px);`
39+
css: (_t, u) => `opacity: ${target_opacity - (od * u)}; filter: ${f} blur(${u * value}${unit});`
4040
};
4141
}
4242

@@ -65,8 +65,8 @@ export interface FlyParams {
6565
delay?: number;
6666
duration?: number;
6767
easing?: EasingFunction;
68-
x?: number;
69-
y?: number;
68+
x?: number | string;
69+
y?: number | string;
7070
opacity?: number;
7171
}
7272

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

8585
const od = target_opacity * (1 - opacity);
86-
86+
const [xValue, xUnit] = split_css_unit(x);
87+
const [yValue, yUnit] = split_css_unit(y);
8788
return {
8889
delay,
8990
duration,
9091
easing,
9192
css: (t, u) => `
92-
transform: ${transform} translate(${(1 - t) * x}px, ${(1 - t) * y}px);
93+
transform: ${transform} translate(${(1 - t) * xValue}${xUnit}, ${(1 - t) * yValue}${yUnit});
9394
opacity: ${target_opacity - (od * u)}`
9495
};
9596
}

test/utils/index.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import * as assert from 'assert';
22
import { trim_start, trim_end } from '../../src/compiler/utils/trim';
3+
import { split_css_unit } from '../../src/runtime/internal/utils';
34

45
describe('utils', () => {
56
describe('trim', () => {
@@ -13,4 +14,17 @@ describe('utils', () => {
1314
assert.equal(value, ' \r\n\t svelte content');
1415
});
1516
});
17+
18+
describe('split_css_unit', () => {
19+
it('should use px as default', () => {
20+
assert.deepEqual(split_css_unit(10), [10, 'px']);
21+
assert.deepEqual(split_css_unit('10'), [10, 'px']);
22+
});
23+
24+
it('should split the css notation into value and unit', () => {
25+
assert.deepEqual(split_css_unit('-50%'), [-50, '%']);
26+
assert.deepEqual(split_css_unit('0.1rem'), [0.1, 'rem']);
27+
assert.deepEqual(split_css_unit('.1rem'), [0.1, 'rem']);
28+
});
29+
});
1630
});

0 commit comments

Comments
 (0)