Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

framesync

Package Overview
Dependencies
Maintainers
1
Versions
41
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

framesync - npm Package Compare versions

Comparing version 3.1.9 to 4.0.0

lib/_)index.d.ts

182

dist/framesync.es.js

@@ -1,96 +0,136 @@

var hasRAF = typeof window !== 'undefined' && window.requestAnimationFrame !== undefined;
import { invariant } from 'hey-listen';
var prevTime = 0;
var onNextFrame = hasRAF
var onNextFrame = typeof window !== 'undefined' && window.requestAnimationFrame !== undefined
? function (callback) { return window.requestAnimationFrame(callback); }
: function (callback) {
var currentTime = Date.now();
var timeToCall = Math.max(0, 16.7 - (currentTime - prevTime));
prevTime = currentTime + timeToCall;
var timestamp = Date.now();
var timeToCall = Math.max(0, 16.7 - (timestamp - prevTime));
prevTime = timestamp + timeToCall;
setTimeout(function () { return callback(prevTime); }, timeToCall);
};
function createRenderStep(startRenderLoop) {
var functionsToRun = [];
var functionsToRunNextFrame = [];
var createStep = (function (setRunNextFrame) {
var processToRun = [];
var processToRunNextFrame = [];
var numThisFrame = 0;
var isProcessing = false;
var i = 0;
return {
cancel: function (callback) {
var indexOfCallback = functionsToRunNextFrame.indexOf(callback);
var cancelled = new WeakSet();
var toKeepAlive = new WeakSet();
var renderStep = {
cancel: function (process) {
var indexOfCallback = processToRunNextFrame.indexOf(process);
cancelled.add(process);
if (indexOfCallback !== -1) {
functionsToRunNextFrame.splice(indexOfCallback, 1);
processToRunNextFrame.splice(indexOfCallback, 1);
}
},
process: function () {
process: function (frame) {
var _a;
isProcessing = true;
_a = [functionsToRunNextFrame, functionsToRun], functionsToRun = _a[0], functionsToRunNextFrame = _a[1];
functionsToRunNextFrame.length = 0;
numThisFrame = functionsToRun.length;
for (i = 0; i < numThisFrame; i++) {
functionsToRun[i]();
_a = [
processToRunNextFrame,
processToRun
], processToRun = _a[0], processToRunNextFrame = _a[1];
processToRunNextFrame.length = 0;
numThisFrame = processToRun.length;
if (numThisFrame) {
var process_1;
for (i = 0; i < numThisFrame; i++) {
process_1 = processToRun[i];
process_1(frame);
if (toKeepAlive.has(process_1) === true && !cancelled.has(process_1)) {
renderStep.schedule(process_1);
setRunNextFrame(true);
}
}
}
isProcessing = false;
var _a;
},
schedule: function (callback, immediate) {
if (immediate === void 0) { immediate = false; }
startRenderLoop();
schedule: function (process, keepAlive, immediate) {
invariant(typeof process === 'function', 'Argument must be a function');
var addToCurrentBuffer = immediate && isProcessing;
var buffer = addToCurrentBuffer ? functionsToRun : functionsToRunNextFrame;
if (buffer.indexOf(callback) === -1) {
buffer.push(callback);
if (addToCurrentBuffer) {
numThisFrame = functionsToRun.length;
}
var buffer = addToCurrentBuffer ? processToRun : processToRunNextFrame;
if (keepAlive)
toKeepAlive.add(process);
if (buffer.indexOf(process) === -1) {
buffer.push(process);
if (addToCurrentBuffer)
numThisFrame = processToRun.length;
}
},
}
};
}
return renderStep;
});
var HAS_PERFORMANCE_NOW = typeof performance !== 'undefined' && performance.now !== undefined;
var currentTime = HAS_PERFORMANCE_NOW ? function () { return performance.now(); } : function () { return Date.now(); };
var willRenderNextFrame = false;
var MAX_ELAPSED = 40;
var defaultElapsed = 16.7;
var StepId;
(function (StepId) {
StepId["Read"] = "read";
StepId["Update"] = "update";
StepId["Render"] = "render";
StepId["PostRender"] = "postRender";
StepId["FixedUpdate"] = "fixedUpdate";
})(StepId || (StepId = {}));
var maxElapsed = 40;
var defaultElapsed = (1 / 60) * 1000;
var useDefaultElapsed = true;
var currentFramestamp = 0;
var elapsed = 0;
function startRenderLoop() {
if (willRenderNextFrame)
return;
willRenderNextFrame = true;
useDefaultElapsed = true;
onNextFrame(processFrame);
}
var frameStart = createRenderStep(startRenderLoop);
var frameUpdate = createRenderStep(startRenderLoop);
var frameRender = createRenderStep(startRenderLoop);
var frameEnd = createRenderStep(startRenderLoop);
function processFrame(framestamp) {
willRenderNextFrame = false;
elapsed = useDefaultElapsed
var willRunNextFrame = false;
var isProcessing = false;
var frame = {
delta: 0,
timestamp: 0
};
var stepsOrder = [
StepId.Read,
StepId.Update,
StepId.Render,
StepId.PostRender
];
var setWillRunNextFrame = function (willRun) { return (willRunNextFrame = willRun); };
var _a = stepsOrder.reduce(function (acc, key) {
var step = createStep(setWillRunNextFrame);
acc.sync[key] = function (process, keepAlive, immediate) {
if (keepAlive === void 0) { keepAlive = false; }
if (immediate === void 0) { immediate = false; }
if (!willRunNextFrame)
startLoop();
step.schedule(process, keepAlive, immediate);
return process;
};
acc.cancelSync[key] = function (process) { return step.cancel(process); };
acc.steps[key] = step;
return acc;
}, {
steps: {},
sync: {},
cancelSync: {}
}), steps = _a.steps, sync = _a.sync, cancelSync = _a.cancelSync;
var processStep = function (stepId) { return steps[stepId].process(frame); };
var processFrame = function (timestamp) {
willRunNextFrame = false;
frame.delta = useDefaultElapsed
? defaultElapsed
: Math.max(Math.min(framestamp - currentFramestamp, MAX_ELAPSED), 1);
: Math.max(Math.min(timestamp - frame.timestamp, maxElapsed), 1);
if (!useDefaultElapsed)
defaultElapsed = elapsed;
currentFramestamp = framestamp;
frameStart.process();
frameUpdate.process();
frameRender.process();
frameEnd.process();
if (willRenderNextFrame)
defaultElapsed = frame.delta;
frame.timestamp = timestamp;
isProcessing = true;
stepsOrder.forEach(processStep);
isProcessing = false;
if (willRunNextFrame) {
useDefaultElapsed = false;
}
var onFrameStart = frameStart.schedule;
var onFrameUpdate = frameUpdate.schedule;
var onFrameRender = frameRender.schedule;
var onFrameEnd = frameEnd.schedule;
var cancelOnFrameStart = frameStart.cancel;
var cancelOnFrameUpdate = frameUpdate.cancel;
var cancelOnFrameRender = frameRender.cancel;
var cancelOnFrameEnd = frameEnd.cancel;
var timeSinceLastFrame = function () { return elapsed; };
var currentFrameTime = function () { return currentFramestamp; };
onNextFrame(processFrame);
}
};
var startLoop = function () {
willRunNextFrame = true;
useDefaultElapsed = true;
if (!isProcessing)
onNextFrame(processFrame);
};
var getFrameData = function () { return frame; };
export { currentTime, onFrameStart, onFrameUpdate, onFrameRender, onFrameEnd, cancelOnFrameStart, cancelOnFrameUpdate, cancelOnFrameRender, cancelOnFrameEnd, timeSinceLastFrame, currentFrameTime };
export default sync;
export { cancelSync, getFrameData };

@@ -7,108 +7,147 @@ (function (global, factory) {

var hasRAF = typeof window !== 'undefined' && window.requestAnimationFrame !== undefined;
var prevTime = 0;
var onNextFrame = hasRAF
var onNextFrame = typeof window !== 'undefined' && window.requestAnimationFrame !== undefined
? function (callback) { return window.requestAnimationFrame(callback); }
: function (callback) {
var currentTime = Date.now();
var timeToCall = Math.max(0, 16.7 - (currentTime - prevTime));
prevTime = currentTime + timeToCall;
var timestamp = Date.now();
var timeToCall = Math.max(0, 16.7 - (timestamp - prevTime));
prevTime = timestamp + timeToCall;
setTimeout(function () { return callback(prevTime); }, timeToCall);
};
function createRenderStep(startRenderLoop) {
var functionsToRun = [];
var functionsToRunNextFrame = [];
var HEY_LISTEN = 'Hey, listen! ';
var invariant = function () { };
if (process.env.NODE_ENV !== 'production') {
invariant = function (check, message) {
if (!check) {
throw new Error(HEY_LISTEN.toUpperCase() + message);
}
};
}
var createStep = (function (setRunNextFrame) {
var processToRun = [];
var processToRunNextFrame = [];
var numThisFrame = 0;
var isProcessing = false;
var i = 0;
return {
cancel: function (callback) {
var indexOfCallback = functionsToRunNextFrame.indexOf(callback);
var cancelled = new WeakSet();
var toKeepAlive = new WeakSet();
var renderStep = {
cancel: function (process) {
var indexOfCallback = processToRunNextFrame.indexOf(process);
cancelled.add(process);
if (indexOfCallback !== -1) {
functionsToRunNextFrame.splice(indexOfCallback, 1);
processToRunNextFrame.splice(indexOfCallback, 1);
}
},
process: function () {
process: function (frame) {
var _a;
isProcessing = true;
_a = [functionsToRunNextFrame, functionsToRun], functionsToRun = _a[0], functionsToRunNextFrame = _a[1];
functionsToRunNextFrame.length = 0;
numThisFrame = functionsToRun.length;
for (i = 0; i < numThisFrame; i++) {
functionsToRun[i]();
_a = [
processToRunNextFrame,
processToRun
], processToRun = _a[0], processToRunNextFrame = _a[1];
processToRunNextFrame.length = 0;
numThisFrame = processToRun.length;
if (numThisFrame) {
var process_1;
for (i = 0; i < numThisFrame; i++) {
process_1 = processToRun[i];
process_1(frame);
if (toKeepAlive.has(process_1) === true && !cancelled.has(process_1)) {
renderStep.schedule(process_1);
setRunNextFrame(true);
}
}
}
isProcessing = false;
var _a;
},
schedule: function (callback, immediate) {
if (immediate === void 0) { immediate = false; }
startRenderLoop();
schedule: function (process, keepAlive, immediate) {
invariant(typeof process === 'function', 'Argument must be a function');
var addToCurrentBuffer = immediate && isProcessing;
var buffer = addToCurrentBuffer ? functionsToRun : functionsToRunNextFrame;
if (buffer.indexOf(callback) === -1) {
buffer.push(callback);
if (addToCurrentBuffer) {
numThisFrame = functionsToRun.length;
}
var buffer = addToCurrentBuffer ? processToRun : processToRunNextFrame;
if (keepAlive)
toKeepAlive.add(process);
if (buffer.indexOf(process) === -1) {
buffer.push(process);
if (addToCurrentBuffer)
numThisFrame = processToRun.length;
}
},
}
};
}
return renderStep;
});
var HAS_PERFORMANCE_NOW = typeof performance !== 'undefined' && performance.now !== undefined;
var currentTime = HAS_PERFORMANCE_NOW ? function () { return performance.now(); } : function () { return Date.now(); };
var willRenderNextFrame = false;
var MAX_ELAPSED = 40;
var defaultElapsed = 16.7;
var StepId;
(function (StepId) {
StepId["Read"] = "read";
StepId["Update"] = "update";
StepId["Render"] = "render";
StepId["PostRender"] = "postRender";
StepId["FixedUpdate"] = "fixedUpdate";
})(StepId || (StepId = {}));
var maxElapsed = 40;
var defaultElapsed = (1 / 60) * 1000;
var useDefaultElapsed = true;
var currentFramestamp = 0;
var elapsed = 0;
function startRenderLoop() {
if (willRenderNextFrame)
return;
willRenderNextFrame = true;
useDefaultElapsed = true;
onNextFrame(processFrame);
}
var frameStart = createRenderStep(startRenderLoop);
var frameUpdate = createRenderStep(startRenderLoop);
var frameRender = createRenderStep(startRenderLoop);
var frameEnd = createRenderStep(startRenderLoop);
function processFrame(framestamp) {
willRenderNextFrame = false;
elapsed = useDefaultElapsed
var willRunNextFrame = false;
var isProcessing = false;
var frame = {
delta: 0,
timestamp: 0
};
var stepsOrder = [
StepId.Read,
StepId.Update,
StepId.Render,
StepId.PostRender
];
var setWillRunNextFrame = function (willRun) { return (willRunNextFrame = willRun); };
var _a = stepsOrder.reduce(function (acc, key) {
var step = createStep(setWillRunNextFrame);
acc.sync[key] = function (process, keepAlive, immediate) {
if (keepAlive === void 0) { keepAlive = false; }
if (immediate === void 0) { immediate = false; }
if (!willRunNextFrame)
startLoop();
step.schedule(process, keepAlive, immediate);
return process;
};
acc.cancelSync[key] = function (process) { return step.cancel(process); };
acc.steps[key] = step;
return acc;
}, {
steps: {},
sync: {},
cancelSync: {}
}), steps = _a.steps, sync = _a.sync, cancelSync = _a.cancelSync;
var processStep = function (stepId) { return steps[stepId].process(frame); };
var processFrame = function (timestamp) {
willRunNextFrame = false;
frame.delta = useDefaultElapsed
? defaultElapsed
: Math.max(Math.min(framestamp - currentFramestamp, MAX_ELAPSED), 1);
: Math.max(Math.min(timestamp - frame.timestamp, maxElapsed), 1);
if (!useDefaultElapsed)
defaultElapsed = elapsed;
currentFramestamp = framestamp;
frameStart.process();
frameUpdate.process();
frameRender.process();
frameEnd.process();
if (willRenderNextFrame)
defaultElapsed = frame.delta;
frame.timestamp = timestamp;
isProcessing = true;
stepsOrder.forEach(processStep);
isProcessing = false;
if (willRunNextFrame) {
useDefaultElapsed = false;
}
var onFrameStart = frameStart.schedule;
var onFrameUpdate = frameUpdate.schedule;
var onFrameRender = frameRender.schedule;
var onFrameEnd = frameEnd.schedule;
var cancelOnFrameStart = frameStart.cancel;
var cancelOnFrameUpdate = frameUpdate.cancel;
var cancelOnFrameRender = frameRender.cancel;
var cancelOnFrameEnd = frameEnd.cancel;
var timeSinceLastFrame = function () { return elapsed; };
var currentFrameTime = function () { return currentFramestamp; };
onNextFrame(processFrame);
}
};
var startLoop = function () {
willRunNextFrame = true;
useDefaultElapsed = true;
if (!isProcessing)
onNextFrame(processFrame);
};
var getFrameData = function () { return frame; };
exports.currentTime = currentTime;
exports.onFrameStart = onFrameStart;
exports.onFrameUpdate = onFrameUpdate;
exports.onFrameRender = onFrameRender;
exports.onFrameEnd = onFrameEnd;
exports.cancelOnFrameStart = cancelOnFrameStart;
exports.cancelOnFrameUpdate = cancelOnFrameUpdate;
exports.cancelOnFrameRender = cancelOnFrameRender;
exports.cancelOnFrameEnd = cancelOnFrameEnd;
exports.timeSinceLastFrame = timeSinceLastFrame;
exports.currentFrameTime = currentFrameTime;
exports.default = sync;
exports.cancelSync = cancelSync;
exports.getFrameData = getFrameData;

@@ -115,0 +154,0 @@ Object.defineProperty(exports, '__esModule', { value: true });

@@ -1,1 +0,1 @@

!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n(e.framesync={})}(this,function(e){"use strict";var n=0,r="undefined"!=typeof window&&void 0!==window.requestAnimationFrame?function(e){return window.requestAnimationFrame(e)}:function(e){var r=Date.now(),t=Math.max(0,16.7-(r-n));n=r+t,setTimeout(function(){return e(n)},t)};function t(e){var n=[],r=[],t=0,c=!1,o=0;return{cancel:function(e){var n=r.indexOf(e);-1!==n&&r.splice(n,1)},process:function(){for(c=!0,n=(e=[r,n])[0],(r=e[1]).length=0,t=n.length,o=0;o<t;o++)n[o]();var e;c=!1},schedule:function(o,a){void 0===a&&(a=!1),e();var i=a&&c,u=i?n:r;-1===u.indexOf(o)&&(u.push(o),i&&(t=n.length))}}}var c="undefined"!=typeof performance&&void 0!==performance.now?function(){return performance.now()}:function(){return Date.now()},o=!1,a=40,i=16.7,u=!0,f=0,d=0;function s(){o||(o=!0,u=!0,r(v))}var m=t(s),l=t(s),p=t(s),h=t(s);function v(e){o=!1,d=u?i:Math.max(Math.min(e-f,a),1),u||(i=d),f=e,m.process(),l.process(),p.process(),h.process(),o&&(u=!1)}var F=m.schedule,w=l.schedule,x=p.schedule,y=h.schedule,O=m.cancel,M=l.cancel,g=p.cancel,S=h.cancel;e.currentTime=c,e.onFrameStart=F,e.onFrameUpdate=w,e.onFrameRender=x,e.onFrameEnd=y,e.cancelOnFrameStart=O,e.cancelOnFrameUpdate=M,e.cancelOnFrameRender=g,e.cancelOnFrameEnd=S,e.timeSinceLastFrame=function(){return d},e.currentFrameTime=function(){return f},Object.defineProperty(e,"__esModule",{value:!0})});
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n(e.framesync={})}(this,function(e){"use strict";var n=0,t="undefined"!=typeof window&&void 0!==window.requestAnimationFrame?function(e){return window.requestAnimationFrame(e)}:function(e){var t=Date.now(),o=Math.max(0,16.7-(t-n));n=t+o,setTimeout(function(){return e(n)},o)},o=function(){};"production"!==process.env.NODE_ENV&&(o=function(e,n){if(!e)throw new Error("Hey, listen! ".toUpperCase()+n)});var r;!function(e){e.Read="read",e.Update="update",e.Render="render",e.PostRender="postRender",e.FixedUpdate="fixedUpdate"}(r||(r={}));var c=1/60*1e3,a=!0,i=!1,u=!1,d={delta:0,timestamp:0},f=[r.Read,r.Update,r.Render,r.PostRender],s=function(e){return i=e},p=f.reduce(function(e,n){var t,r,c,a,u,d,f,p,l,m=(t=s,r=[],c=[],a=0,u=!1,d=0,f=new WeakSet,p=new WeakSet,l={cancel:function(e){var n=c.indexOf(e);f.add(e),-1!==n&&c.splice(n,1)},process:function(e){var n,o;if(u=!0,r=(n=[c,r])[0],(c=n[1]).length=0,a=r.length)for(d=0;d<a;d++)(o=r[d])(e),!0!==p.has(o)||f.has(o)||(l.schedule(o),t(!0));u=!1},schedule:function(e,n,t){o("function"==typeof e,"Argument must be a function");var i=t&&u,d=i?r:c;n&&p.add(e),-1===d.indexOf(e)&&(d.push(e),i&&(a=r.length))}});return e.sync[n]=function(e,n,t){return void 0===n&&(n=!1),void 0===t&&(t=!1),i||w(),m.schedule(e,n,t),e},e.cancelSync[n]=function(e){return m.cancel(e)},e.steps[n]=m,e},{steps:{},sync:{},cancelSync:{}}),l=p.steps,m=p.sync,h=p.cancelSync,y=function(e){return l[e].process(d)},v=function(e){i=!1,d.delta=a?c:Math.max(Math.min(e-d.timestamp,40),1),a||(c=d.delta),d.timestamp=e,u=!0,f.forEach(y),u=!1,i&&(a=!1,t(v))},w=function(){i=!0,a=!0,u||t(v)};e.default=m,e.cancelSync=h,e.getFrameData=function(){return d},Object.defineProperty(e,"__esModule",{value:!0})});

@@ -1,6 +0,3 @@

export interface RenderStep {
readonly schedule: (callback: Function, immediate?: boolean) => void;
readonly cancel: (callback: Function) => void;
readonly process: Function;
}
export default function createRenderStep(startRenderLoop: Function): RenderStep;
import { Step } from './types';
declare const _default: (setRunNextFrame: (fillRun: boolean) => void) => Step;
export default _default;

@@ -1,11 +0,20 @@

export declare const currentTime: () => number;
export declare const onFrameStart: (callback: Function, immediate?: boolean) => void;
export declare const onFrameUpdate: (callback: Function, immediate?: boolean) => void;
export declare const onFrameRender: (callback: Function, immediate?: boolean) => void;
export declare const onFrameEnd: (callback: Function, immediate?: boolean) => void;
export declare const cancelOnFrameStart: (callback: Function) => void;
export declare const cancelOnFrameUpdate: (callback: Function) => void;
export declare const cancelOnFrameRender: (callback: Function) => void;
export declare const cancelOnFrameEnd: (callback: Function) => void;
export declare const timeSinceLastFrame: () => number;
export declare const currentFrameTime: () => number;
import { Process, FrameData } from './types';
declare const sync: {
read: (process: Process, keepAlive?: boolean, immediate?: boolean) => Process;
update: (process: Process, keepAlive?: boolean, immediate?: boolean) => Process;
render: (process: Process, keepAlive?: boolean, immediate?: boolean) => Process;
postRender: (process: Process, keepAlive?: boolean, immediate?: boolean) => Process;
fixedUpdate: (process: Process, keepAlive?: boolean, immediate?: boolean) => Process;
}, cancelSync: {
read: (process: Process) => void;
update: (process: Process) => void;
render: (process: Process) => void;
postRender: (process: Process) => void;
fixedUpdate: (process: Process) => void;
};
declare const getFrameData: () => {
delta: number;
timestamp: number;
};
export default sync;
export { cancelSync, getFrameData, FrameData, Process };

@@ -5,107 +5,138 @@ 'use strict';

var hasRAF = typeof window !== 'undefined' && window.requestAnimationFrame !== undefined;
var heyListen = require('hey-listen');
var prevTime = 0;
var onNextFrame = hasRAF
var onNextFrame = typeof window !== 'undefined' && window.requestAnimationFrame !== undefined
? function (callback) { return window.requestAnimationFrame(callback); }
: function (callback) {
var currentTime = Date.now();
var timeToCall = Math.max(0, 16.7 - (currentTime - prevTime));
prevTime = currentTime + timeToCall;
var timestamp = Date.now();
var timeToCall = Math.max(0, 16.7 - (timestamp - prevTime));
prevTime = timestamp + timeToCall;
setTimeout(function () { return callback(prevTime); }, timeToCall);
};
function createRenderStep(startRenderLoop) {
var functionsToRun = [];
var functionsToRunNextFrame = [];
var createStep = (function (setRunNextFrame) {
var processToRun = [];
var processToRunNextFrame = [];
var numThisFrame = 0;
var isProcessing = false;
var i = 0;
return {
cancel: function (callback) {
var indexOfCallback = functionsToRunNextFrame.indexOf(callback);
var cancelled = new WeakSet();
var toKeepAlive = new WeakSet();
var renderStep = {
cancel: function (process) {
var indexOfCallback = processToRunNextFrame.indexOf(process);
cancelled.add(process);
if (indexOfCallback !== -1) {
functionsToRunNextFrame.splice(indexOfCallback, 1);
processToRunNextFrame.splice(indexOfCallback, 1);
}
},
process: function () {
process: function (frame) {
var _a;
isProcessing = true;
_a = [functionsToRunNextFrame, functionsToRun], functionsToRun = _a[0], functionsToRunNextFrame = _a[1];
functionsToRunNextFrame.length = 0;
numThisFrame = functionsToRun.length;
for (i = 0; i < numThisFrame; i++) {
functionsToRun[i]();
_a = [
processToRunNextFrame,
processToRun
], processToRun = _a[0], processToRunNextFrame = _a[1];
processToRunNextFrame.length = 0;
numThisFrame = processToRun.length;
if (numThisFrame) {
var process_1;
for (i = 0; i < numThisFrame; i++) {
process_1 = processToRun[i];
process_1(frame);
if (toKeepAlive.has(process_1) === true && !cancelled.has(process_1)) {
renderStep.schedule(process_1);
setRunNextFrame(true);
}
}
}
isProcessing = false;
var _a;
},
schedule: function (callback, immediate) {
if (immediate === void 0) { immediate = false; }
startRenderLoop();
schedule: function (process, keepAlive, immediate) {
heyListen.invariant(typeof process === 'function', 'Argument must be a function');
var addToCurrentBuffer = immediate && isProcessing;
var buffer = addToCurrentBuffer ? functionsToRun : functionsToRunNextFrame;
if (buffer.indexOf(callback) === -1) {
buffer.push(callback);
if (addToCurrentBuffer) {
numThisFrame = functionsToRun.length;
}
var buffer = addToCurrentBuffer ? processToRun : processToRunNextFrame;
if (keepAlive)
toKeepAlive.add(process);
if (buffer.indexOf(process) === -1) {
buffer.push(process);
if (addToCurrentBuffer)
numThisFrame = processToRun.length;
}
},
}
};
}
return renderStep;
});
var HAS_PERFORMANCE_NOW = typeof performance !== 'undefined' && performance.now !== undefined;
var currentTime = HAS_PERFORMANCE_NOW ? function () { return performance.now(); } : function () { return Date.now(); };
var willRenderNextFrame = false;
var MAX_ELAPSED = 40;
var defaultElapsed = 16.7;
var StepId;
(function (StepId) {
StepId["Read"] = "read";
StepId["Update"] = "update";
StepId["Render"] = "render";
StepId["PostRender"] = "postRender";
StepId["FixedUpdate"] = "fixedUpdate";
})(StepId || (StepId = {}));
var maxElapsed = 40;
var defaultElapsed = (1 / 60) * 1000;
var useDefaultElapsed = true;
var currentFramestamp = 0;
var elapsed = 0;
function startRenderLoop() {
if (willRenderNextFrame)
return;
willRenderNextFrame = true;
useDefaultElapsed = true;
onNextFrame(processFrame);
}
var frameStart = createRenderStep(startRenderLoop);
var frameUpdate = createRenderStep(startRenderLoop);
var frameRender = createRenderStep(startRenderLoop);
var frameEnd = createRenderStep(startRenderLoop);
function processFrame(framestamp) {
willRenderNextFrame = false;
elapsed = useDefaultElapsed
var willRunNextFrame = false;
var isProcessing = false;
var frame = {
delta: 0,
timestamp: 0
};
var stepsOrder = [
StepId.Read,
StepId.Update,
StepId.Render,
StepId.PostRender
];
var setWillRunNextFrame = function (willRun) { return (willRunNextFrame = willRun); };
var _a = stepsOrder.reduce(function (acc, key) {
var step = createStep(setWillRunNextFrame);
acc.sync[key] = function (process, keepAlive, immediate) {
if (keepAlive === void 0) { keepAlive = false; }
if (immediate === void 0) { immediate = false; }
if (!willRunNextFrame)
startLoop();
step.schedule(process, keepAlive, immediate);
return process;
};
acc.cancelSync[key] = function (process) { return step.cancel(process); };
acc.steps[key] = step;
return acc;
}, {
steps: {},
sync: {},
cancelSync: {}
}), steps = _a.steps, sync = _a.sync, cancelSync = _a.cancelSync;
var processStep = function (stepId) { return steps[stepId].process(frame); };
var processFrame = function (timestamp) {
willRunNextFrame = false;
frame.delta = useDefaultElapsed
? defaultElapsed
: Math.max(Math.min(framestamp - currentFramestamp, MAX_ELAPSED), 1);
: Math.max(Math.min(timestamp - frame.timestamp, maxElapsed), 1);
if (!useDefaultElapsed)
defaultElapsed = elapsed;
currentFramestamp = framestamp;
frameStart.process();
frameUpdate.process();
frameRender.process();
frameEnd.process();
if (willRenderNextFrame)
defaultElapsed = frame.delta;
frame.timestamp = timestamp;
isProcessing = true;
stepsOrder.forEach(processStep);
isProcessing = false;
if (willRunNextFrame) {
useDefaultElapsed = false;
}
var onFrameStart = frameStart.schedule;
var onFrameUpdate = frameUpdate.schedule;
var onFrameRender = frameRender.schedule;
var onFrameEnd = frameEnd.schedule;
var cancelOnFrameStart = frameStart.cancel;
var cancelOnFrameUpdate = frameUpdate.cancel;
var cancelOnFrameRender = frameRender.cancel;
var cancelOnFrameEnd = frameEnd.cancel;
var timeSinceLastFrame = function () { return elapsed; };
var currentFrameTime = function () { return currentFramestamp; };
onNextFrame(processFrame);
}
};
var startLoop = function () {
willRunNextFrame = true;
useDefaultElapsed = true;
if (!isProcessing)
onNextFrame(processFrame);
};
var getFrameData = function () { return frame; };
exports.currentTime = currentTime;
exports.onFrameStart = onFrameStart;
exports.onFrameUpdate = onFrameUpdate;
exports.onFrameRender = onFrameRender;
exports.onFrameEnd = onFrameEnd;
exports.cancelOnFrameStart = cancelOnFrameStart;
exports.cancelOnFrameUpdate = cancelOnFrameUpdate;
exports.cancelOnFrameRender = cancelOnFrameRender;
exports.cancelOnFrameEnd = cancelOnFrameEnd;
exports.timeSinceLastFrame = timeSinceLastFrame;
exports.currentFrameTime = currentFrameTime;
exports.default = sync;
exports.cancelSync = cancelSync;
exports.getFrameData = getFrameData;
{
"name": "framesync",
"version": "3.1.9",
"version": "4.0.0",
"description": "A Unity-inspired render loop for JavaScript",

@@ -15,3 +15,3 @@ "main": "lib/index.js",

"measure": "gzip -c dist/framesync.min.js | wc -c",
"prepublishOnly": "npm run lint && npm run build"
"prepublishOnly": "npm run test && npm run build"
},

@@ -37,6 +37,9 @@ "files": [

"devDependencies": {
"jest": "^20.0.4",
"@types/jest": "^23.1.1",
"jest": "^23.1.0",
"jest-cli": "^23.1.0",
"rollup-plugin-node-resolve": "^3.4.0",
"rollup-plugin-typescript2": "^0.14.0",
"rollup-plugin-uglify": "^3.0.0",
"ts-jest": "^20.0.10",
"ts-jest": "^21.2.4",
"typescript": "^2.4.2"

@@ -47,9 +50,9 @@ },

"ts",
"tsx",
"js"
],
"transform": {
".(ts|tsx)$": "<rootDir>/node_modules/ts-jest/preprocessor.js"
"\\.(ts)$": "../../../node_modules/ts-jest/preprocessor.js"
},
"testRegex": "/_tests/.*\\.(ts|tsx|js)$"
"testRegex": "/_tests/.*\\.(ts|js)$",
"rootDir": "src"
},

@@ -60,3 +63,6 @@ "unpkg": "./dist/framesync.min.js",

"singleQuote": true
},
"dependencies": {
"hey-listen": "^1.0.5"
}
}

@@ -1,2 +0,2 @@

# <a href="https://popmotion.io/api/framesync"><img src="https://user-images.githubusercontent.com/7850794/38307669-5e7e3f88-380c-11e8-8c26-970c36801910.png" height="61" width="250" alt="Framesync" /></a>
# Framesync

@@ -7,2 +7,4 @@ A tiny frame scheduler for performantly batching reads and renders.

Popmotion batches updates on the `update` step, and Stylefire batches renders on the `render` step.
## Install

@@ -16,42 +18,93 @@

The Framesync render loop executes four sequential steps, once per frame.
### Render steps
- `frameStart`
- `frameUpdate`
- `frameRender`
- `frameEnd`
Once per frame, the functions scheduled with Framesync are executed in the following order:
Developers can set any function to run at any of these steps using the `on` and `cancel` callbacks:
- `read`
- `update`
- `render`
- `postRender`
- `onFrameStart`, `cancelOnFrameStart`
- `onFrameUpdate`, `cancelOnFrameUpdate`
- `onFrameRender`, `cancelOnFrameRender`
- `onFrameEnd`, `cancelOnFrameEnd`
### Scheduling functions
Framesync also exports some time-measurement methods:
- `currentTime`: The current time as measured by the host platform's most accurate `now` function.
- `currentFrameTime`: The time the current `requestAnimationFrame` was initiated.
- `timeSinceLastFrame`: The duration between the previous frame and the current `currentFrameTime`
Functions can be scheduled to different parts of the render loop with `sync`.
### Example
```javascript
import sync from 'framesync';
```
It contains four functions, one to schedule on each of the above steps:
```javascript
import {
timeSinceLastFrame,
onFrameStart,
cancelFrameStart
} from 'framesync';
sync[stepId](callback, keepAlive, immediate)
```
function logTimeSinceLastFrame() {
console.log(timeSinceLastFrame());
onFrameStart(logTimeSinceLastFrame);
}
```javascript
sync.update(() => console.log('update step'));
```
onFrameStart(logTimeSinceLastFrame);
### Frame data
function stopLogging() {
cancelOnFrameStart(logTimeSinceLastFrame);
}
Each function is provided data about the current frame:
setTimeout(stopLogging, 5000);
```javascript
sync.update(({ delta, timestamp }) => {});
```
- `delta`: Time since last frame (in milliseconds)
- `timestamp`: Timestamp of the current frame.
This object is recycled across frames to reduce garbage collection, so values should be destructured if intended to be used asynchronously.
### keepAlive
We can run a function (or set of functions) as an ongoing process by passing `keepAlive: true`:
```javascript
let count = 0;
sync(() => count++, true);
```
This will keep the process running until it's actively cancelled.
### immediate
The `immediate` option can be used to sync a function on the **current frame step**.
By default, Framesync will schedule functions to run the next time that frame step is fired:
```javascript
sync.update(({ timestamp }) => {
sync.update((frame) => {
// frame.timestamp !== timestamp
))
});
```
By setting `immediate` to `true`, we can add this at the end of the current step:
```javascript
sync.update(({ timestamp }) => {
sync.update((frame) => {
// frame.timestamp === timestamp
}, false, true)
});
```
### Cancelling
Synced processes can be cancelled with `cancelSync`:
```javascript
import sync, { cancelSync } from 'framesync';
let count = 0;
const process = sync.render(() => {
count++;
if (count >= 10) {
cancelSync.render(process);
}
}, true);
```
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc