Last active
March 27, 2023 23:56
-
-
Save tkroo/02960e4212f62489f521f070e35e6c9b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const fs = require("fs"); | |
const path = require("path"); | |
const sharp = require("sharp"); | |
const formats = ['avif', 'webp','jpg']; | |
const formatsQuality = [40, 50, 50]; | |
const myroot = process.env.ELEVENTY_ROOT; | |
// USE | |
// this: | |
// {%- imageOptimize item.img, item.title, "394, 564", "(max-width:600px) 100vw, 394px", true -%} | |
// will generate: | |
// <picture> | |
// <source type="image/avif" srcset="/images/work/wwf1-394w.avif 394w, /images/work/wwf1-564w.avif 564w" sizes="(max-width:600px) 100vw, 394px"> | |
// <source type="image/webp" srcset="/images/work/wwf1-394w.webp 394w, /images/work/wwf1-564w.webp 564w" sizes="(max-width:600px) 100vw, 394px"> | |
// <img class="img--full" alt="Winter Water Factory" loading="eager" decoding="async" srcset="/images/work/wwf1-394w.jpg 394w, /images/work/wwf1-564w.jpg 564w" src="/images/work/wwf1-394w.jpg" sizes="(max-width:600px) 100vw, 394px" width="564" height="564"> | |
// </picture> | |
function processImage (fullInPath, outputFile, mywidth, f) { | |
const image = sharp(fullInPath) | |
.resize({ | |
fit: sharp.fit.contain, | |
width: mywidth | |
}) | |
.toFormat(formats[f], {quality: formatsQuality[f]}) | |
.toFile(outputFile) | |
} | |
function createPictureElement(src, mywidths, sizes, alt, nolazy) { | |
const po = path.parse(src); | |
const srcsetsArr = []; | |
formats.forEach(format => { | |
srcsetsArr.push(mywidths.map(width => `${path.join(po.dir, po.name+"-"+width+"w."+format)} ${width}w`).join(', ')); | |
}) | |
const lastFormatSuffix = `w.${formats[formats.length-1]}`; | |
const minWidth = Math.min(...mywidths); | |
const maxWidth = Math.max(...mywidths); | |
let output = `<picture>`; | |
for (let i = 0; i < formats.length; i++) { | |
if(i < formats.length-1) { | |
output += `<source type="image/${formats[i]}" srcset="${srcsetsArr[i]}" sizes="${sizes}">` | |
} else { | |
let mysrc = `${src.replace(po.ext, "-" + minWidth + lastFormatSuffix)}`; | |
output += `<img class="img--full" alt="${alt}" loading="${nolazy ? 'eager' : 'lazy'}" decoding="async" | |
srcset="${srcsetsArr[i]}" | |
src="${mysrc}" width="${maxWidth}" height="${maxWidth}" | |
sizes="${sizes}" | |
> | |
</picture>` | |
} | |
} | |
return output; | |
} | |
module.exports = { | |
imageOptimize: function(src, alt, widths, sizes, nolazy) { | |
const mywidths = widths.split(',').map(s => parseInt(s)); | |
const outputDir = path.join(myroot,'_site', path.parse(src).dir); | |
if (!fs.existsSync(outputDir)) { | |
fs.mkdirSync(outputDir, { recursive: true }) | |
} | |
for (let f=0; f < formats.length; f++) { | |
for (let i=0; i < mywidths.length; i++) { | |
const fullInPath = path.join(myroot,"src/_assets", src); | |
const outputFile = path.join(outputDir, path.parse(src).name+"-"+mywidths[i]+"w."+formats[f] ); | |
fs.access(outputFile, error => { | |
if(error) { | |
console.log("Optimizing", src, "to", outputFile); | |
processImage(fullInPath, outputFile, mywidths[i], f) | |
} else { | |
// console.log('file already exists. nothing to be done.'); | |
} | |
}) | |
} | |
} | |
return createPictureElement(src, mywidths, sizes, alt, nolazy); | |
}, | |
getYear: () => `${new Date().getFullYear()}` | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment