157 lines
3.1 KiB
JavaScript
Raw Normal View History

2020-02-25 19:37:10 -08:00
2020-02-27 18:57:39 -08:00
const path = require('path');
2021-03-22 18:26:13 -07:00
const { pick } = require('lodash');
2020-02-25 19:37:10 -08:00
const actions = require('./actions');
2020-02-27 18:57:39 -08:00
const File = require('./file');
const { TYPE } = require('./resolve');
2020-02-28 10:31:13 -08:00
const getImageDimensions = require('./lib/dimensions');
const getVideoDimensions = require('get-video-dimensions');
const WIDTHS = [ 2048, 1024, 768, 576, 300, 100 ];
2020-02-21 20:05:52 -08:00
2020-02-27 18:57:39 -08:00
module.exports = exports = class Asset extends File {
2020-02-21 20:05:52 -08:00
constructor (filepath) {
2020-02-27 18:57:39 -08:00
super(filepath);
2020-02-21 20:05:52 -08:00
2020-02-27 18:57:39 -08:00
this.serializable.push(
'dimensions',
'sizes'
2020-02-27 18:57:39 -08:00
);
}
load () {
2020-02-27 18:57:39 -08:00
switch (this.type) {
case TYPE.VIDEO: return this.loadVideo();
case TYPE.IMAGE: return this.loadImage();
default:
return this.loadOther();
}
}
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,
};
this.sizes = [ {
url: this.url,
width,
height,
} ];
2021-03-22 18:26:13 -07:00
if (this.preprocessed || this.ext === '.svg') {
this._tasks = [ {
2020-02-25 19:37:10 -08:00
output: this.out,
input: this.input,
action: actions.copy,
nocache: true,
} ];
return;
}
this._tasks = [
{
output: this.out,
input: this.input,
width,
height,
format: 'jpeg',
action: actions.image,
},
];
for (const w of WIDTHS) {
if (w > width) continue;
const name = `${this.name}.${w}w${this.ext}`;
this.sizes.push({
url: path.join(this.dir, name),
width: w,
height: Math.ceil((w / width) * height),
});
this._tasks.push({
output: path.join(this.base, name),
input: this.input,
width: w,
format: 'jpeg',
fill: 'contain',
quality: 85,
action: actions.image,
});
}
2020-02-21 20:05:52 -08:00
this.sizes.reverse();
return this;
}
2020-02-21 20:05:52 -08:00
async loadVideo () {
const { width, height } = await getVideoDimensions(this.input);
2020-02-21 20:05:52 -08:00
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 = [ {
2020-02-25 19:37:10 -08:00
url: path.join(this.dir, this.basename),
width,
height,
} ];
this._tasks = [
{
output: this.out,
input: this.input,
action: actions.copy,
nocache: true,
},
];
return this;
}
2020-04-07 09:53:33 -07:00
get webready () {
const { type, name, url, sizes } = this;
2020-02-21 20:05:52 -08:00
return {
2020-02-27 18:57:39 -08:00
type,
name,
2020-04-07 09:53:33 -07:00
url,
2020-02-27 18:57:39 -08:00
sizes: sizes.map((s) => pick(s, [ 'url', 'width', 'height' ])),
2020-02-21 20:05:52 -08:00
};
}
tasks () {
return this._tasks;
}
2020-02-25 19:37:10 -08:00
};