first commit

This commit is contained in:
becarta
2025-05-16 00:17:42 +02:00
parent ea5c866137
commit bacf566ec9
6020 changed files with 1715262 additions and 0 deletions

1
node_modules/lottie-web/test/animations/adrock.json generated vendored Normal file

File diff suppressed because one or more lines are too long

1
node_modules/lottie-web/test/animations/bacon.json generated vendored Normal file

File diff suppressed because one or more lines are too long

1
node_modules/lottie-web/test/animations/banner.json generated vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1
node_modules/lottie-web/test/animations/dalek.json generated vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
{"lat":33.4418,"lon":-94.0377,"timezone":"America/Chicago","timezone_offset":-18000,"current":{"dt":1616783932,"sunrise":1616760679,"sunset":1616805115,"temp":294.73,"feels_like":291.14,"pressure":1017,"humidity":43,"dew_point":281.63,"uvi":7.02,"clouds":1,"visibility":10000,"wind_speed":4.63,"wind_deg":120,"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01d"}]},"minutely":[{"dt":1616783940,"precipitation":0},{"dt":1616784000,"precipitation":0},{"dt":1616784060,"precipitation":0},{"dt":1616784120,"precipitation":0},{"dt":1616784180,"precipitation":0},{"dt":1616784240,"precipitation":0},{"dt":1616784300,"precipitation":0},{"dt":1616784360,"precipitation":0},{"dt":1616784420,"precipitation":0},{"dt":1616784480,"precipitation":0},{"dt":1616784540,"precipitation":0},{"dt":1616784600,"precipitation":0},{"dt":1616784660,"precipitation":0},{"dt":1616784720,"precipitation":0},{"dt":1616784780,"precipitation":0},{"dt":1616784840,"precipitation":0},{"dt":1616784900,"precipitation":0},{"dt":1616784960,"precipitation":0},{"dt":1616785020,"precipitation":0},{"dt":1616785080,"precipitation":0},{"dt":1616785140,"precipitation":0},{"dt":1616785200,"precipitation":0},{"dt":1616785260,"precipitation":0},{"dt":1616785320,"precipitation":0},{"dt":1616785380,"precipitation":0},{"dt":1616785440,"precipitation":0},{"dt":1616785500,"precipitation":0},{"dt":1616785560,"precipitation":0},{"dt":1616785620,"precipitation":0},{"dt":1616785680,"precipitation":0},{"dt":1616785740,"precipitation":0},{"dt":1616785800,"precipitation":0},{"dt":1616785860,"precipitation":0},{"dt":1616785920,"precipitation":0},{"dt":1616785980,"precipitation":0},{"dt":1616786040,"precipitation":0},{"dt":1616786100,"precipitation":0},{"dt":1616786160,"precipitation":0},{"dt":1616786220,"precipitation":0},{"dt":1616786280,"precipitation":0},{"dt":1616786340,"precipitation":0},{"dt":1616786400,"precipitation":0},{"dt":1616786460,"precipitation":0},{"dt":1616786520,"precipitation":0},{"dt":1616786580,"precipitation":0},{"dt":1616786640,"precipitation":0},{"dt":1616786700,"precipitation":0},{"dt":1616786760,"precipitation":0},{"dt":1616786820,"precipitation":0},{"dt":1616786880,"precipitation":0},{"dt":1616786940,"precipitation":0},{"dt":1616787000,"precipitation":0},{"dt":1616787060,"precipitation":0},{"dt":1616787120,"precipitation":0},{"dt":1616787180,"precipitation":0},{"dt":1616787240,"precipitation":0},{"dt":1616787300,"precipitation":0},{"dt":1616787360,"precipitation":0},{"dt":1616787420,"precipitation":0},{"dt":1616787480,"precipitation":0},{"dt":1616787540,"precipitation":0}]}

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

1
node_modules/lottie-web/test/animations/lights.json generated vendored Normal file

File diff suppressed because one or more lines are too long

1
node_modules/lottie-web/test/animations/monster.json generated vendored Normal file

File diff suppressed because one or more lines are too long

1
node_modules/lottie-web/test/animations/navidad.json generated vendored Normal file

File diff suppressed because one or more lines are too long

1
node_modules/lottie-web/test/animations/ripple.json generated vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

100
node_modules/lottie-web/test/index.html generated vendored Normal file
View File

@@ -0,0 +1,100 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<style>
body, html{
background-color:#fff;
margin: 0px;
overflow-x: hidden;
overflow-y: auto;
width: 100%;
height: 100%;
}
#lottie{
background-color:#fff;
width:100%;
height:100%;
display:block;
overflow: hidden;
transform: translate3d(0,0,0);
pointer-events: none;
/*display:none;*/
}
</style>
<script src="/lottie.min.js" ></script>
</head>
<body>
<div id="lottie"></div>
<script>
const buildRenderSettings = (searchParams) => {
const defaultValues = {
path: '/test/animations/adrock.json',
renderer: 'svg',
};
searchParams.forEach((value, key) => {
defaultValues[key] = value;
});
return defaultValues;
};
</script>
<script>
const submitAndWaitForResponse = (currentFrame, isLast) => (
new Promise((resolve) => {
window.onMessageReceivedEvent({
currentFrame,
isLast,
});
resolve();
})
);
</script>
<script>
const waitContinueCommand = () => {
return new Promise((resolve) => {
window.continueExecution = resolve;
})
}
</script>
<script>
window.startProcess = () => {
const url = new URL(window.location);
const settings = buildRenderSettings(url.searchParams)
const animation = lottie.loadAnimation({
container: document.getElementById('lottie'),
path: settings.path,
autoplay: false,
loop: false,
renderer: settings.renderer,
})
animation.addEventListener('DOMLoaded', async () => {
window.onAnimationLoaded();
try {
let totalFrames = animation.totalFrames;
let currentFrame = 0;
while (currentFrame <= totalFrames) {
await waitContinueCommand();
animation.goToAndStop(currentFrame, true);
await submitAndWaitForResponse(
currentFrame,
currentFrame === totalFrames,
);
currentFrame += 1;
}
} catch (error) {
console.log('ERROR', error.message);
}
})
}
// window.startProcess();
</script>
</body>
</html>

350
node_modules/lottie-web/test/index.js generated vendored Normal file
View File

@@ -0,0 +1,350 @@
/**
* This traverses all json files located on the examples folder, then iterates
* over each file and opens a puppeteer page to a screenshot of all frames
* combined in a single page.
*/
const puppeteer = require('puppeteer');
const express = require('express');
const fs = require('fs');
const { promises: { readFile } } = require('fs');
const commandLineArgs = require('command-line-args');
const PNG = require('pngjs').PNG;
const pixelmatch = require('pixelmatch');
const examplesDirectory = '/test/animations/';
const createDirectory = 'screenshots/create';
const compareDirectory = 'screenshots/compare';
function createDirectoryPath(path) {
const directories = path.split('/');
directories.reduce((acc, current) => {
let dir = acc + '/' + current
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir);
}
return dir
}, '.')
}
const animations = [
{
fileName: 'pigeon.json',
renderer: 'svg',
},
{
fileName: 'banner.json',
renderer: 'svg',
},
{
fileName: 'adrock.json',
renderer: 'canvas',
},
{
fileName: 'bm_ronda.json',
renderer: 'svg',
},
{
fileName: 'bodymovin.json',
renderer: 'svg',
},
{
fileName: 'bodymovin.json',
renderer: 'canvas',
},
{
fileName: 'dalek.json',
renderer: 'svg',
},
{
fileName: 'navidad.json',
renderer: 'svg',
},
{
fileName: 'monster.json',
renderer: 'svg',
},
{
fileName: 'bacon.json',
renderer: 'svg',
},
{
fileName: 'lights.json',
renderer: 'svg',
},
{
fileName: 'ripple.json',
renderer: 'svg',
},
{
fileName: 'starfish.json',
renderer: 'svg',
},
{
directory: 'footage',
fileName: 'data.json',
renderer: 'svg',
},
]
const getSettings = async () => {
const defaultValues = {
step: 'create',
}
const opts = [
{
name: 'step',
alias: 's',
type: (val) => {
return val === 'compare' ? 'compare' : 'create';
},
description: 'Whether it is the create or the compare step',
}
];
const settings = {
...defaultValues,
...commandLineArgs(opts),
};
return settings;
};
const wait = (time) => new Promise((resolve) => setTimeout(resolve, time));
const filesData = [
{
path: '/test/index.html',
filePath: './test/index.html',
type: 'html',
},
{
path: '/lottie.min.js',
filePath: './build/player/lottie.min.js',
type: 'js',
},
];
const getEncoding = (() => {
const encodingMap = {
js: 'utf8',
json: 'utf8',
html: 'utf8',
};
return (fileType) => encodingMap[fileType];
})();
const getContentTypeHeader = (() => {
const contentTypeMap = {
js: { 'Content-Type': 'application/javascript' },
json: { 'Content-Type': 'application/json' },
html: { 'Content-Type': 'text/html; charset=utf-8' },
wasm: { 'Content-Type': 'application/wasm' },
};
return (fileType) => contentTypeMap[fileType];
})();
const startServer = async () => {
const app = express();
await Promise.all(filesData.map(async (file) => {
const fileData = await readFile(file.filePath, getEncoding(file.type));
app.get(file.path, async (req, res) => {
res.writeHead(200, getContentTypeHeader(file.type));
// TODO: comment line. Only for live updates.
const fileData = await readFile(file.filePath, getEncoding(file.type));
res.end(fileData);
});
return file;
}));
app.get('/*', async (req, res) => {
try {
if (req.originalUrl.indexOf('.json') !== -1) {
const file = await readFile(`.${req.originalUrl}`, 'utf8');
res.send(file);
} else {
const data = await readFile(`.${req.originalUrl}`);
res.writeHead(200, { 'Content-Type': 'image/jpeg' });
res.end(data);
}
} catch (err) {
res.send('');
}
});
app.listen('9999');
};
const getBrowser = async () => puppeteer.launch({ defaultViewport: null });
const startPage = async (browser, path, renderer) => {
const targetURL = `http://localhost:9999/test/index.html\
?path=${encodeURIComponent(path)}&renderer=${renderer}`;
const page = await browser.newPage();
page.on('console', (msg) => console.log('PAGE LOG:', msg.text())); // eslint-disable-line no-console
await page.setViewport({
width: 1024,
height: 768,
});
await page.goto(targetURL);
return page;
};
const createBridgeHelper = async (page) => {
let resolveScoped;
let animationLoadedPromise;
const messageHandler = (event) => {
resolveScoped(event);
};
const onAnimationLoaded = () => {
if (animationLoadedPromise) {
animationLoadedPromise()
}
}
await page.exposeFunction('onAnimationLoaded', onAnimationLoaded);
await page.exposeFunction('onMessageReceivedEvent', messageHandler);
const waitForMessage = () => new Promise((resolve) => {
resolveScoped = resolve;
});
const waitForAnimationLoaded = () => new Promise((resolve) => {
animationLoadedPromise = resolve;
});
const continueExecution = async () => {
page.evaluate(() => {
window.continueExecution();
});
};
return {
waitForAnimationLoaded,
waitForMessage,
continueExecution,
};
};
const compareFiles = (folderName, fileName) => {
const createPath = `${createDirectory}/${folderName}/${fileName}`;
const comparePath = `${compareDirectory}/${folderName}/${fileName}`;
const img1 = PNG.sync.read(fs.readFileSync(createPath));
const img2 = PNG.sync.read(fs.readFileSync(comparePath));
const {width, height} = img1;
const diff = new PNG({width, height});
const result = pixelmatch(img1.data, img2.data, diff.data, width, height, {threshold: 0.1});
// Using 50 as threshold because it should be an acceptable difference
// that doesn't raise false positives
if (result > 200) {
console.log('RESULT NOT ZERO: ', result);
throw new Error(`Animation failed: ${folderName} at frame: ${fileName}`)
}
}
const createIndividualAssets = async (page, folderName, settings) => {
const filePath = `${settings.step === 'create' ? createDirectory : compareDirectory}/${folderName}`;
createDirectoryPath(filePath);
let isLastFrame = false;
const bridgeHelper = await (createBridgeHelper(page));
page.evaluate(() => {
window.startProcess();
});
await bridgeHelper.waitForAnimationLoaded();
while (!isLastFrame) {
// Disabling rule because execution can't be parallelized
/* eslint-disable no-await-in-loop */
await wait(1);
page.evaluate(() => {
window.continueExecution();
});
const message = await bridgeHelper.waitForMessage();
const fileNumber = message.currentFrame.toString().padStart(5, '0');
const fileName = `image_${fileNumber}.png`;
const localDestinationPath = `${filePath}/${fileName}`;
await page.screenshot({
path: localDestinationPath,
fullPage: false,
});
if (settings.step === 'compare') {
try {
compareFiles(folderName, fileName);
} catch (err) {
console.log('FAILED AT FRAME: ', message.currentFrame);
throw err;
}
}
isLastFrame = message.isLast;
}
};
const getDirFiles = async (directory) => (
new Promise((resolve, reject) => {
fs.readdir(directory, (err, files) => {
if (err) {
reject(err);
} else {
resolve(files);
}
});
})
);
async function processPage(browser, settings, directory, animation) {
let fullDirectory = `${directory}`;
if (animation.directory) {
fullDirectory += `${animation.directory}/`;
}
const fileName = animation.fileName;
const page = await startPage(browser, fullDirectory + fileName, animation.renderer);
const fileNameWithoutExtension = fileName.replace(/\.[^/.]+$/, '');
let fullName = `${fileNameWithoutExtension}_${animation.renderer}`
if (animation.directory) {
fullName = `${animation.directory}_` + fullName;
}
await createIndividualAssets(page, fullName, settings);
}
const iteratePages = async (browser, settings) => {
const failedAnimations = [];
for (let i = 0; i < animations.length; i += 1) {
const animation = animations[i];
let fileName = `${animation.renderer}_${animation.fileName}`;
if (animation.directory) {
fileName = `${animation.directory}_` + fileName;
}
try {
// eslint-disable-next-line no-await-in-loop
await processPage(browser, settings, examplesDirectory, animation);
if (settings.step === 'create') {
console.log(`Creating animation: ${fileName}`);
}
if (settings.step === 'compare') {
console.log(`Animation passed: ${fileName}`);
}
} catch (error) {
if (settings.step === 'compare') {
failedAnimations.push({
fileName: fileName
})
}
}
}
if (failedAnimations.length) {
failedAnimations.forEach(animation => {
console.log(`Animation failed: ${animation.fileName}`);
})
throw new Error('Animations failed');
}
};
const takeImageStrip = async () => {
try {
await startServer();
const settings = await getSettings();
await wait(1);
const browser = await getBrowser();
await iteratePages(browser, settings);
process.exit(0);
} catch (error) {
console.log(error); // eslint-disable-line no-console
process.exit(1);
}
};
takeImageStrip();