Skip to content

Commit

Permalink
Merge branch 'master' into core
Browse files Browse the repository at this point in the history
Conflicts:
	README.md
	cli.js
	package-lock.json
	package.json
  • Loading branch information
tungs committed Apr 3, 2022
2 parents 97473d1 + 737a17a commit 3c9885f
Show file tree
Hide file tree
Showing 12 changed files with 469 additions and 650 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
BSD 3-Clause License

Copyright (c) 2018-2021, Steve Tung
Copyright (c) 2018-2022, Steve Tung
All rights reserved.

Redistribution and use in source and binary forms, with or without
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ timesnap({
left: 20, top: 40, // further crops the left by 20px, and the top by 40px
right: 6, bottom: 30, // and the right by 6px, and the bottom by 30px
fps: 30, // saves 30 frames for each virtual second
duration: 20, // for 20 virtual seconds
duration: 20, // for 20 virtual seconds
outputDirectory: 'frames' // to frames/001.png... frames/600.png
// of the current working directory
}).then(function () {
Expand Down
12 changes: 7 additions & 5 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* BSD 3-Clause License
*
* Copyright (c) 2018-2021, Steve Tung
* Copyright (c) 2018-2022, Steve Tung
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -34,7 +34,7 @@ const path = require('path');
const defaultDuration = 5;
const defaultFPS = 60;
const { overwriteRandom } = require('./lib/overwrite-random');
const { getBrowserFrames, stringArrayFind, getPageViewportSize, setPageViewportSize } = require('./lib/utils');
const { stringArrayFind, getPageViewportSize, setPageViewportSize } = require('./lib/utils');

module.exports = async function (config) {
config = Object.assign({}, config || {});
Expand Down Expand Up @@ -170,6 +170,9 @@ module.exports = async function (config) {
await page.goto(url, { waitUntil: 'networkidle0' });
}
log('Page loaded');
if (timeHandler.preparePage) {
await timeHandler.preparePage({ page, url, log });
}
if ('preparePage' in config) {
log('Preparing page before screenshots...');
await Promise.resolve(config.preparePage(page));
Expand All @@ -180,7 +183,6 @@ module.exports = async function (config) {
setTimeout(resolve, startWaitMs);
});
}
var browserFrames = getBrowserFrames(page.mainFrame());
var captureTimes = [];
if (capturer.beforeCapture) {
// run beforeCapture right before any capture frames
Expand Down Expand Up @@ -243,7 +245,7 @@ module.exports = async function (config) {
var marker = markers[markerIndex];
markerIndex++;
if (marker.type === 'Capture') {
await timeHandler.goToTimeAndAnimateForCapture(browserFrames, marker.time);
await timeHandler.goToTimeAndAnimateForCapture(page, marker.time);
var skipCurrentFrame;
if (config.shouldSkipFrame) {
skipCurrentFrame = await config.shouldSkipFrame({
Expand All @@ -265,7 +267,7 @@ module.exports = async function (config) {
}
}
} else if (marker.type === 'Only Animate') {
await timeHandler.goToTimeAndAnimate(browserFrames, marker.time);
await timeHandler.goToTimeAndAnimate(page, marker.time);
} else if (marker.type === 'Run Function') {
await marker.data.fn(marker);
}
Expand Down
2 changes: 1 addition & 1 deletion lib/capture-canvas.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* BSD 3-Clause License
*
* Copyright (c) 2018-2021, Steve Tung
* Copyright (c) 2018-2022, Steve Tung
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
Expand Down
2 changes: 1 addition & 1 deletion lib/capture-screenshot.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* BSD 3-Clause License
*
* Copyright (c) 2018-2021, Steve Tung
* Copyright (c) 2018-2022, Steve Tung
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
Expand Down
71 changes: 30 additions & 41 deletions lib/immediate-canvas-handler.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* BSD 3-Clause License
*
* Copyright (c) 2018-2021, Steve Tung
* Copyright (c) 2018-2022, Steve Tung
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -32,9 +32,7 @@

const timeHandler = require('./overwrite-time');
const makeCanvasCapturer = require('./make-canvas-capturer');

var overwriteTime = timeHandler.overwriteTime;
var oldGoToTime = timeHandler.goToTime;

const canvasCapturer = makeCanvasCapturer(async (page) => {
var dataUrl = await page.evaluate(() => window._timesnap_canvasData);
Expand All @@ -47,53 +45,44 @@ module.exports = function (config) {
var canvasCaptureMode = capturer.canvasCaptureMode;
var canvasSelector = capturer.canvasSelector;
var quality = capturer.quality;
var page = config.page;
var goToTime;
if (config.alwaysSaveCanvasData) {
goToTime = async function (browserFrames, time) {
// Goes to a certain time. Can't go backwards
return page.evaluate(({ ms, canvasSelector, type, quality }) => {
window.timeweb.processUntilTime(ms);
var canvasElement = document.querySelector(canvasSelector);
window._timesnap_canvasData = canvasElement.toDataURL(type, quality);
}, { ms: time, canvasSelector, type: canvasCaptureMode, quality });
};
} else {
goToTime = oldGoToTime;
}

const goToTimeAndAnimateForCapture = async function (browserFrames, time) {
// Goes to a certain time. Can't go backwards
return page.evaluate(({ ms, canvasSelector, type, quality }) => {
window.timeweb.processUntilTime(ms);
return window.timeweb.runFramePreparers(ms, function () {
window.timeweb.runAnimationFrames();
var preparePage = async function ({ page }) {
await page.evaluate(function ({ canvasSelector, type, quality }) {
window._timesnap_saveCanvasData = function () {
var canvasElement = document.querySelector(canvasSelector);
window._timesnap_canvasData = canvasElement.toDataURL(type, quality);
};
}, { canvasSelector, type: canvasCaptureMode, quality });
if (config.alwaysSaveCanvasData) {
// the event detail filtering should be aligned with those found in overwrite-time.js
await page.evaluate(function () {
window.timeweb.on('postseek', (e) => {
if (e.detail === 'only seek') {
window._timesnap_saveCanvasData();
}
});
window.timeweb.on('postanimate', () => {
window._timesnap_saveCanvasData();
});
});
}, { ms: time, canvasSelector, type: canvasCaptureMode, quality });
} else {
await page.evaluate(function () {
window.timeweb.on('postanimate', (e) => {
if (e.detail !== 'no capture') {
window._timesnap_saveCanvasData();
}
});
});
}
};

var goToTimeAndAnimate;
if (config.alwaysSaveCanvasData) {
goToTimeAndAnimate = goToTimeAndAnimateForCapture;
} else {
goToTimeAndAnimate = async function (browserFrames, time) {
// Goes to a certain time. Can't go backwards
return page.evaluate(function (ms) {
window.timeweb.processUntilTime(ms);
return window.timeweb.runFramePreparers(ms, window.timeweb.runAnimationFrames);
}, time);
};
}

return {
capturer: capturer,
timeHandler: {
overwriteTime,
goToTime,
goToTimeAndAnimate,
goToTimeAndAnimateForCapture
preparePage,
goToTime: timeHandler.goToTime,
goToTimeAndAnimate: timeHandler.goToTimeAndAnimate,
goToTimeAndAnimateForCapture: timeHandler.goToTimeAndAnimateForCapture
}
};
};
2 changes: 1 addition & 1 deletion lib/make-canvas-capturer.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* BSD 3-Clause License
*
* Copyright (c) 2018-2021, Steve Tung
* Copyright (c) 2018-2022, Steve Tung
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
Expand Down
98 changes: 15 additions & 83 deletions lib/overwrite-random.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* BSD 3-Clause License
*
* Copyright (c) 2018-2021, Steve Tung
* Copyright (c) 2018-2022, Steve Tung
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -31,13 +31,11 @@
*/

const { evaluateOnNewDocument } = require('./utils.js');
const fs = require('fs');
const path = require('path');

// unrandomizer seed constants
// default seed values are only used if all of the seed values end up being 0
const defaultSeed1 = 10;
const defaultSeed2 = 20;
const defaultSeed3 = 0;
const defaultSeed4 = 0;
const seedIterations = 10;
const randomSeedLimit = 1000000000;

Expand All @@ -62,88 +60,22 @@ const overwriteRandom = function (page, unrandom, log) {
return overwritePageRandom(page, ...args);
};

const overwritePageRandom = function (page, seed1 = 0, seed2 = 0, seed3 = 0, seed4 = 0) {
return evaluateOnNewDocument(page, function (config) {
const overwritePageRandom = async function (page, seed1 = 0, seed2 = 0, seed3 = 0, seed4 = 0) {
const unrandomizeLib = fs.readFileSync(
path.join(require.resolve('unrandomize/dist/unrandomize.js')),
{ encoding: 'utf8' }
);
await evaluateOnNewDocument(page, unrandomizeLib);
await evaluateOnNewDocument(page, function ({ seed1, seed2, seed3, seed4, seedIterations }){
(function (exports) {
let shift1 = 23;
let shift2 = 17;
let shift3 = 26;

let state0 = new ArrayBuffer(8);
let state1 = new ArrayBuffer(8);

let state0SInts = new Int32Array(state0);
let state1SInts = new Int32Array(state1);

let state0UInt = new Uint32Array(state0);
let state1UInt = new Uint32Array(state1);

state0UInt[0] = config.seed1;
state0UInt[1] = config.seed3;
state1UInt[0] = config.seed2;
state1UInt[1] = config.seed4;

if (!state0SInts[0] && !state0SInts[1] && !state1SInts[0] && !state1SInts[1]) {
// if the states are all zero, it does not advance to a new state
// in this case, set the states to the default seeds
state0UInt[0] = config.defaultSeed1;
state0UInt[1] = config.defaultSeed3;
state1UInt[0] = config.defaultSeed2;
state1UInt[1] = config.defaultSeed4;
}

let _xorshift128 = function () {
let xA = state1SInts[0];
let xB = state1SInts[1];
let yA = state0SInts[0];
let yB = state0SInts[1];

yA = yA ^ ((yA << shift1) | (yB >>> (32 - shift1)));
yB = yB ^ (yB << shift1);

yB = yB ^ ((yA << (32 - shift2)) | (yB >>> shift2));
yA = yA ^ (yA >>> shift2);

yA = yA ^ xA;
yB = yB ^ xB;

yB = yB ^ ((xA << (32 - shift3)) | (xB >>> shift3));
yA = yA ^ (xA >>> shift3);

state0SInts[0] = xA;
state0SInts[1] = xB;
state1SInts[0] = yA;
state1SInts[1] = yB;
};

let byteLimit = Math.pow(2, 32);
let mantissaLimit = Math.pow(2, 53);

let _statesToDouble = function () {
let aSum = state0UInt[0] + state1UInt[0];
let bSum = state0UInt[1] + state1UInt[1];
if (bSum >= byteLimit) {
aSum = aSum + 1;
bSum -= byteLimit;
}
aSum = aSum & 0x001FFFFF;
return (aSum * byteLimit + bSum) / mantissaLimit;
};

for (let i = 0; i < config.seedIterations; i++) {
_xorshift128();
var i;
exports.unrandomize.setState([ seed1, seed2, seed3, seed4 ]);
for (i = 0; i < seedIterations; i++) {
Math.random();
}

// overwriting built-in functions...
exports.Math.random = function () {
_xorshift128();
return _statesToDouble();
};
})(this);
}, {
seed1, seed2, seed3, seed4,
defaultSeed1, defaultSeed2, defaultSeed3, defaultSeed4,
seedIterations
seed1, seed2, seed3, seed4, seedIterations
});
};

Expand Down
33 changes: 17 additions & 16 deletions lib/overwrite-time.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* BSD 3-Clause License
*
* Copyright (c) 2018-2021, Steve Tung
* Copyright (c) 2018-2022, Steve Tung
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -31,7 +31,7 @@
*/
const fs = require('fs');
const path = require('path');
const { evaluateOnNewDocument } = require('./utils.js');
const { evaluateOnNewDocument, runInAllFrames } = require('./utils.js');

const timewebLib = fs.readFileSync(
path.join(require.resolve('timeweb/dist/timeweb.js')),
Expand All @@ -41,26 +41,27 @@ const overwriteTime = async function (page) {
return evaluateOnNewDocument(page, timewebLib);
};

const goToTime = async function (browserFrames, time) {
const goToTime = async function (page, time) {
// Goes to a certain time. Can't go backwards
return Promise.all(browserFrames.map(function (frame) {
return frame.evaluate(function (ms) {
window.timeweb.processUntilTime(ms);
}, time);
}));
return runInAllFrames(page, function (ms) {
window.timeweb.goTo(ms, { skipAnimate: true, detail: 'only seek' });
}, time);
};

const goToTimeAndAnimate = async function (browserFrames, time) {

const goToTimeAndAnimate = async function (page, time) {
// Goes to a certain time. Can't go backwards
return Promise.all(browserFrames.map(function (frame) {
return frame.evaluate(function (ms) {
window.timeweb.processUntilTime(ms);
return window.timeweb.runFramePreparers(ms, window.timeweb.runAnimationFrames);
}, time);
}));
return runInAllFrames(page, function (ms) {
window.timeweb.goTo(ms, { detail: 'no capture' });
}, time);
};

const goToTimeAndAnimateForCapture = goToTimeAndAnimate;
const goToTimeAndAnimateForCapture = async function (page, time) {
// Goes to a certain time. Can't go backwards
return runInAllFrames(page, function (ms) {
window.timeweb.goTo(ms);
}, time);
};

module.exports = {
overwriteTime,
Expand Down
Loading

0 comments on commit 3c9885f

Please sign in to comment.