mirror of
https://github.com/GenderDysphoria/GenderDysphoria.fyi.git
synced 2025-11-25 20:42:40 +00:00
Burn it down and rise from the ashes
This commit is contained in:
202
gulp/content/asset.js
Normal file
202
gulp/content/asset.js
Normal file
@@ -0,0 +1,202 @@
|
||||
|
||||
const { pick } = require('lodash');
|
||||
const actions = require('./actions');
|
||||
|
||||
const path = require('path');
|
||||
const getImageDimensions = require('../lib/dimensions');
|
||||
const getVideoDimensions = require('get-video-dimensions');
|
||||
|
||||
const JPG = '.jpg';
|
||||
const JPEG = '.jpeg';
|
||||
const PNG = '.png';
|
||||
const GIF = '.gif';
|
||||
const MP4 = '.mp4';
|
||||
const M4V = '.m4v';
|
||||
|
||||
const FILETYPE = {
|
||||
[JPG]: 'jpeg',
|
||||
[JPEG]: 'jpeg',
|
||||
[PNG]: 'png',
|
||||
[GIF]: 'gif',
|
||||
[MP4]: 'mp4',
|
||||
[M4V]: 'mp4',
|
||||
};
|
||||
|
||||
const RESOLUTIONS = [ 2048, 1024, 768, 576, 300, 100 ];
|
||||
|
||||
module.exports = exports = class Asset {
|
||||
|
||||
constructor (filepath) {
|
||||
const file = path.parse(filepath);
|
||||
let { base: basename, name } = file;
|
||||
|
||||
this.preprocessed = false;
|
||||
if (name[0] === '_') {
|
||||
this.preprocessed = true;
|
||||
file.name = name = name.slice(1);
|
||||
file.basename = basename = basename.slice(1);
|
||||
}
|
||||
|
||||
this.type = FILETYPE[file.ext] || file.ext.slice(1);
|
||||
if ([ JPG, JPEG, PNG, GIF ].includes(file.ext)) {
|
||||
this.kind = 'image';
|
||||
} else if ([ MP4, M4V ].includes(file.ext)) {
|
||||
this.kind = 'video';
|
||||
} else {
|
||||
this.kind = 'raw';
|
||||
}
|
||||
|
||||
// remove the pages root and any _images segment from the dir
|
||||
const dir = file.dir.split('/');
|
||||
if (dir[0] === 'pages') dir.shift();
|
||||
const i = dir.indexOf('_images');
|
||||
if (i > -1) dir.splice(i, 1);
|
||||
|
||||
this.input = filepath; // pages/file.ext
|
||||
this.base = path.join(...dir); // '', 'folder', 'folder/subfolder'
|
||||
this.dir = path.join('/', ...dir); // /, /folder, /folder/subfolder
|
||||
this.name = name; // index, fileA, fileB
|
||||
this.basename = basename; // index.ext, fileA.ext, fileB.ext
|
||||
this.ext = file.ext;
|
||||
|
||||
this.out = path.join(this.base, `${this.name}${this.preprocessed ? this.ext : '.' + this.type}`);
|
||||
this.url = path.join(this.dir, `${this.name}${this.preprocessed ? this.ext : '.' + this.type}`);
|
||||
}
|
||||
|
||||
load () {
|
||||
switch (this.kind) {
|
||||
case 'video': return this.loadVideo();
|
||||
case 'image': return this.loadImage();
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
async loadImage () {
|
||||
|
||||
const { width, height } = await getImageDimensions(this.input);
|
||||
|
||||
const ratioH = Math.round((height / width) * 100);
|
||||
const ratioW = Math.round((width / height) * 100);
|
||||
let orientation = 'wide';
|
||||
if (ratioH > 100) {
|
||||
orientation = 'tall';
|
||||
} else if (ratioH === 100) {
|
||||
orientation = 'square';
|
||||
}
|
||||
|
||||
this.dimensions = {
|
||||
width,
|
||||
height,
|
||||
ratioH,
|
||||
ratioW,
|
||||
orientation,
|
||||
};
|
||||
|
||||
if (this.preprocessed) {
|
||||
this.sizes = [ {
|
||||
output: this.out,
|
||||
url: this.url,
|
||||
width,
|
||||
height,
|
||||
} ];
|
||||
} else {
|
||||
this.sizes = [
|
||||
{
|
||||
output: this.out,
|
||||
url: this.url,
|
||||
width,
|
||||
height,
|
||||
},
|
||||
];
|
||||
|
||||
for (const w of RESOLUTIONS) {
|
||||
if (w > width) continue;
|
||||
const name = `${this.name}.${w}w.${this.type}`;
|
||||
this.sizes.push({
|
||||
output: path.join(this.base, name),
|
||||
url: path.join(this.dir, name),
|
||||
width: w,
|
||||
height: Math.ceil((w / width) * height),
|
||||
});
|
||||
}
|
||||
|
||||
this.sizes.reverse();
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
async loadVideo () {
|
||||
const { width, height } = await getVideoDimensions(this.input);
|
||||
|
||||
const ratioH = Math.round((height / width) * 100);
|
||||
const ratioW = Math.round((width / height) * 100);
|
||||
let orientation = 'wide';
|
||||
if (ratioH > 100) {
|
||||
orientation = 'tall';
|
||||
} else if (ratioH === 100) {
|
||||
orientation = 'square';
|
||||
}
|
||||
|
||||
this.dimensions = {
|
||||
width,
|
||||
height,
|
||||
ratioH,
|
||||
ratioW,
|
||||
orientation,
|
||||
};
|
||||
|
||||
this.sizes = [ {
|
||||
output: path.join(this.base, this.basename),
|
||||
url: path.join(this.dir, this.basename),
|
||||
width,
|
||||
height,
|
||||
} ];
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
toJson () {
|
||||
return pick(this, [
|
||||
'preprocessed',
|
||||
'type',
|
||||
'kind',
|
||||
'input',
|
||||
'base',
|
||||
'dir',
|
||||
'name',
|
||||
'basename',
|
||||
'ext',
|
||||
'dimensions',
|
||||
]);
|
||||
}
|
||||
|
||||
webready () {
|
||||
const { kind, name } = this;
|
||||
return {
|
||||
kind,
|
||||
name,
|
||||
sizes: this.sizes.map((s) => pick(s, [ 'url', 'width', 'height' ])),
|
||||
};
|
||||
}
|
||||
|
||||
tasks () {
|
||||
return this.sizes.map(({ output, width }) => ({
|
||||
input: this.input,
|
||||
output,
|
||||
format: this.preprocessed ? undefined : this.type,
|
||||
width: this.preprocessed ? undefined : width,
|
||||
action: this.preprocessed ? actions.copy : actions.image,
|
||||
}));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
exports.JPG = JPG;
|
||||
exports.JPEG = JPEG;
|
||||
exports.PNG = PNG;
|
||||
exports.GIF = GIF;
|
||||
exports.MP4 = MP4;
|
||||
exports.M4V = M4V;
|
||||
exports.FILETYPE = FILETYPE;
|
||||
exports.RESOLUTIONS = RESOLUTIONS;
|
||||
Reference in New Issue
Block a user