Merge pull request #3762 from sveltejs/gh-3761

allow spring/tweened values to be initially undefined
pull/3817/head
Rich Harris 5 years ago committed by GitHub
commit e931a56854
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -433,6 +433,19 @@ Out of the box, Svelte will interpolate between two numbers, two arrays or two o
---
If the initial value is `undefined` or `null`, the first value change will take effect immediately. This is useful when you have tweened values that are based on props, and don't want any motion when the component first renders.
```js
const size = tweened(undefined, {
duration: 300,
easing: cubicOut
});
$: $size = big ? 100 : 10;
```
---
The `interpolate` option allows you to tween between *any* arbitrary values. It must be an `(a, b) => t => value` function, where `a` is the starting value, `b` is the target value, `t` is a number between 0 and 1, and `value` is the result. For example, we can use the [d3-interpolate](https://github.com/d3/d3-interpolate) package to smoothly interpolate between two colours.
```html
@ -493,6 +506,15 @@ Both `set` and `update` can take a second argument — an object with `hard` or
</script>
```
---
If the initial value is `undefined` or `null`, the first value change will take effect immediately, just as with `tweened` values (see above).
```js
const size = spring();
$: $size = big ? 100 : 10;
```
### `svelte/transition`
The `svelte/transition` module exports six functions: `fade`, `fly`, `slide`, `scale`, `draw` and `crossfade`. They are for use with svelte [`transitions`](docs#Transitions).

@ -65,7 +65,7 @@ interface Spring<T> extends Readable<T>{
stiffness: number;
}
export function spring<T=any>(value: T, opts: SpringOpts = {}): Spring<T> {
export function spring<T=any>(value?: T, opts: SpringOpts = {}): Spring<T> {
const store = writable(value);
const { stiffness = 0.15, damping = 0.8, precision = 0.01 } = opts;
@ -84,12 +84,12 @@ export function spring<T=any>(value: T, opts: SpringOpts = {}): Spring<T> {
target_value = new_value;
const token = current_token = {};
if (opts.hard || (spring.stiffness >= 1 && spring.damping >= 1)) {
if (value == null || opts.hard || (spring.stiffness >= 1 && spring.damping >= 1)) {
cancel_task = true; // cancel any running animation
last_time = now();
last_value = value;
last_value = new_value;
store.set(value = target_value);
return new Promise(f => f()); // fulfil immediately
return Promise.resolve();
} else if (opts.soft) {
const rate = opts.soft === true ? .5 : +opts.soft;
inv_mass_recovery_rate = 1 / (rate * 60);

@ -69,13 +69,18 @@ interface Tweened<T> extends Readable<T> {
update(updater: Updater<T>, opts: Options<T>): Promise<void>;
}
export function tweened<T>(value: T, defaults: Options<T> = {}): Tweened<T> {
export function tweened<T>(value?: T, defaults: Options<T> = {}): Tweened<T> {
const store = writable(value);
let task: Task;
let target_value = value;
function set(new_value: T, opts: Options<T>) {
if (value == null) {
store.set(value = new_value);
return Promise.resolve();
}
target_value = new_value;
let previous_task = task;

@ -0,0 +1,23 @@
import * as assert from 'assert';
import { get } from '../../store';
import { spring, tweened } from '../../motion';
describe('motion', () => {
describe('spring', () => {
it('handles initially undefined values', () => {
const size = spring();
size.set(100);
assert.equal(get(size), 100);
});
});
describe('tweened', () => {
it('handles initially undefined values', () => {
const size = tweened();
size.set(100);
assert.equal(get(size), 100);
});
});
});
Loading…
Cancel
Save