start centralising rAF stuff

pull/1937/head
Richard Harris 7 years ago
parent 65dc6d693b
commit d58996534d

@ -1,4 +1,5 @@
import { transitionManager, linear, generateRule, hash } from './transitions.js'; import { transitionManager, linear, generateRule, hash } from './transitions.js';
import { loop } from './loop.js';
export function wrapAnimation(node, from, fn, params) { export function wrapAnimation(node, from, fn, params) {
if (!from) return; if (!from) return;
@ -68,7 +69,35 @@ export function wrapAnimation(node, from, fn, params) {
} }
}; };
transitionManager.add(animation); // transitionManager.add(animation);
transitionManager.active += 1;
const { abort, promise } = loop(() => {
const now = window.performance.now();
if (animation.program && now >= animation.program.end) {
animation.done();
}
if (animation.pending && now >= animation.pending.start) {
animation.start(animation.pending);
}
if (animation.running) {
animation.update(now);
return true;
}
});
promise.then(() => {
transitionManager.active -= 1;
if (!transitionManager.active) {
let i = transitionManager.stylesheet.cssRules.length;
while (i--) transitionManager.stylesheet.deleteRule(i);
transitionManager.activeRules = {};
}
});
if (info.tick) info.tick(0, 1); if (info.tick) info.tick(0, 1);

@ -3,6 +3,7 @@ export * from './await-block.js';
export * from './dom.js'; export * from './dom.js';
export * from './keyed-each.js'; export * from './keyed-each.js';
export * from './lifecycle.js'; export * from './lifecycle.js';
export * from './loop.js';
export * from './scheduler.js'; export * from './scheduler.js';
export * from './spread.js'; export * from './spread.js';
export * from './ssr.js'; export * from './ssr.js';

@ -0,0 +1,38 @@
const tasks = new Set();
let running = false;
function run_tasks() {
tasks.forEach(task => {
if (!task[0]()) {
tasks.delete(task);
task[1]();
}
});
running = tasks.size > 0;
if (running) requestAnimationFrame(run_tasks);
}
export function clear_loops() {
// for testing...
tasks.forEach(task => tasks.delete(task));
running = false;
}
export function loop(fn) {
let task;
if (!running) {
running = true;
requestAnimationFrame(run_tasks);
}
return {
promise: new Promise(fulfil => {
tasks.add(task = [fn, fulfil]);
}),
abort() {
tasks.delete(task);
}
};
}

@ -1,5 +1,6 @@
import { createElement } from './dom.js'; import { createElement } from './dom.js';
import { noop, run } from './utils.js'; import { noop, run } from './utils.js';
import { loop } from './loop.js';
export function linear(t) { export function linear(t) {
return t; return t;
@ -83,8 +84,35 @@ export function wrapTransition(component, node, fn, params, intro) {
} }
if (!this.running) { if (!this.running) {
transitionManager.active += 1;
this.running = true; this.running = true;
transitionManager.add(this); // transitionManager.add(this);
const { abort, promise } = loop(() => {
const now = window.performance.now();
if (this.program && now >= this.program.end) {
this.done();
}
if (this.pending && now >= this.pending.start) {
this.start(this.pending);
}
if (this.running) {
this.update(now);
return true;
}
});
promise.then(() => {
transitionManager.active -= 1;
if (!transitionManager.active) {
let i = transitionManager.stylesheet.cssRules.length;
while (i--) transitionManager.stylesheet.deleteRule(i);
transitionManager.activeRules = {};
}
});
} }
}, },
@ -173,6 +201,7 @@ export function groupOutros() {
} }
export var transitionManager = { export var transitionManager = {
active: 0,
running: false, running: false,
transitions: [], transitions: [],
bound: null, bound: null,
@ -180,15 +209,6 @@ export var transitionManager = {
activeRules: {}, activeRules: {},
promise: null, promise: null,
add(transition) {
this.transitions.push(transition);
if (!this.running) {
this.running = true;
requestAnimationFrame(this.bound || (this.bound = this.next.bind(this)));
}
},
addRule(rule, name) { addRule(rule, name) {
if (!this.stylesheet) { if (!this.stylesheet) {
const style = createElement('style'); const style = createElement('style');
@ -202,40 +222,6 @@ export var transitionManager = {
} }
}, },
next() {
this.running = false;
const now = window.performance.now();
let i = this.transitions.length;
while (i--) {
const transition = this.transitions[i];
if (transition.program && now >= transition.program.end) {
transition.done();
}
if (transition.pending && now >= transition.pending.start) {
transition.start(transition.pending);
}
if (transition.running) {
transition.update(now);
this.running = true;
} else if (!transition.pending) {
this.transitions.splice(i, 1);
}
}
if (this.running) {
requestAnimationFrame(this.bound);
} else if (this.stylesheet) {
let i = this.stylesheet.cssRules.length;
while (i--) this.stylesheet.deleteRule(i);
this.activeRules = {};
}
},
deleteRule(node, name) { deleteRule(node, name) {
node.style.animation = node.style.animation node.style.animation = node.style.animation
.split(', ') .split(', ')

@ -1,5 +1,6 @@
import { writable } from 'svelte/store'; import { writable } from 'svelte/store';
import { add_task, is_date } from './utils.js'; import { loop } from 'svelte/internal';
import { is_date } from './utils.js';
function get_initial_velocity(value) { function get_initial_velocity(value) {
if (typeof value === 'number' || is_date(value)) return 0; if (typeof value === 'number' || is_date(value)) return 0;
@ -116,7 +117,7 @@ export function spring(value, opts = {}) {
last_time = window.performance.now(); last_time = window.performance.now();
settled = false; settled = false;
task = add_task(() => { task = loop(() => {
const time = window.performance.now(); const time = window.performance.now();
({ value, settled } = tick_spring( ({ value, settled } = tick_spring(

@ -1,7 +1,7 @@
import { writable } from 'svelte/store'; import { writable } from 'svelte/store';
import { assign } from 'svelte/internal'; import { assign, loop } from 'svelte/internal';
import { linear } from 'svelte/easing'; import { linear } from 'svelte/easing';
import { add_task, is_date } from './utils.js'; import { is_date } from './utils.js';
function get_interpolator(a, b) { function get_interpolator(a, b) {
if (a === b || a !== a) return () => a; if (a === b || a !== a) return () => a;
@ -76,7 +76,7 @@ export function tweened(value, defaults = {}) {
const start = window.performance.now() + delay; const start = window.performance.now() + delay;
let fn; let fn;
task = add_task(() => { task = loop(() => {
const time = window.performance.now(); const time = window.performance.now();
if (time < start) return true; if (time < start) return true;

@ -1,36 +1,3 @@
const tasks = new Set();
let running = false;
function run_tasks() {
tasks.forEach(task => {
if (!task[0]()) {
tasks.delete(task);
task[1]();
}
});
running = tasks.size > 0;
if (running) requestAnimationFrame(run_tasks);
}
export function add_task(fn) {
let task;
if (!running) {
running = true;
requestAnimationFrame(run_tasks);
}
return {
promise: new Promise(fulfil => {
tasks.add(task = [fn, fulfil]);
}),
abort() {
tasks.delete(task);
}
};
}
export function is_date(obj) { export function is_date(obj) {
return Object.prototype.toString.call(obj) === '[object Date]'; return Object.prototype.toString.call(obj) === '[object Date]';
} }

@ -3,7 +3,7 @@ import * as path from "path";
import * as fs from "fs"; import * as fs from "fs";
import { rollup } from 'rollup'; import { rollup } from 'rollup';
import * as virtual from 'rollup-plugin-virtual'; import * as virtual from 'rollup-plugin-virtual';
import { transitionManager } from "../../internal.js"; import { transitionManager, clear_loops } from "../../internal.js";
import { import {
showOutput, showOutput,
@ -96,6 +96,7 @@ describe("runtime", () => {
// set of hacks to support transition tests // set of hacks to support transition tests
transitionManager.running = false; transitionManager.running = false;
transitionManager.transitions = []; transitionManager.transitions = [];
clear_loops();
const raf = { const raf = {
time: 0, time: 0,

Loading…
Cancel
Save