Skip to content
This repository has been archived by the owner on May 22, 2024. It is now read-only.

Commit

Permalink
feat(pipeline): Add SVG Placeholders (potrace)
Browse files Browse the repository at this point in the history
Exports can now have a traced SVG accompanying image that serves as as beautiful placeholder,
instead of a low resolution thumbnail. Other bugfixing and formatting
  • Loading branch information
MarcusCemes committed Apr 26, 2019
1 parent e7a0774 commit 58f0471
Show file tree
Hide file tree
Showing 14 changed files with 1,451 additions and 356 deletions.
15 changes: 13 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,17 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [3.1.0] - 2019-04-26

### Added

- SVG Tracing with *potrace*
- Better modularization of the pipeline for easier extensibility with newer features

### Fixed

- Image converting (`convert` option would do nothing)
- Small formatting errors, typos

## [3.0.1] - 2019-04-02

Expand Down Expand Up @@ -197,8 +207,9 @@ not fork the project and submit a Pull Request?

First release

[unreleased]: https://github.com/marcuscemes/responsive-image-builder/compare/v3.0.1...HEAD
[3.0.0]: https://github.com/marcuscemes/responsive-image-builder/compare/v3.0.0...v3.0.1
[unreleased]: https://github.com/marcuscemes/responsive-image-builder/compare/v3.1.0...HEAD
[3.1.0]: https://github.com/marcuscemes/responsive-image-builder/compare/v3.0.1...v3.1.0
[3.0.1]: https://github.com/marcuscemes/responsive-image-builder/compare/v3.0.0...v3.0.1
[3.0.0]: https://github.com/marcuscemes/responsive-image-builder/compare/v2.1.2...v3.0.0
[2.1.2]: https://github.com/marcuscemes/responsive-image-builder/compare/v2.1.1...v2.1.2
[2.1.1]: https://github.com/marcuscemes/responsive-image-builder/compare/v2.1.0...v2.1.1
Expand Down
51 changes: 44 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,13 @@

## Features

-**Fast** - Uses the lightning-quick [libvips image processing library](https://github.com/jcupitt/libvips/wiki/Speed-and-memory-use)
-**Fast** - Uses the lightning-quick [libvips image processing library][link-libvips-speed]
- 🔥 **Multithreaded** - Scales to all available CPU cores
- 📦 **Zero configuration** - Change nothing, change everything. You choose.
- 🌍 **Universal** - a flexible image build process that doesn't enforce any principles
- ✂️ **Cross-platform** - Tested on Windows, macOS and Linux
- 😊 **Friendly experience** - telling you what's going on, from start to finish
-**SVG Tracing** - for [really fancy placeholders][link-traced-svg]

<div align="center">

Expand All @@ -46,7 +47,10 @@

## Why

Webpack... Angular... React... PHP... Cloudflare... So many solutions for serving images, some terrible, some paid. What if you just want to serve modern [WebP][link-webp-speed] images with [srcset][link-srcset] optimization, [lazy-loading][link-lazy-sizes] (with low-quality placeholder), fingerprint cache-busting, aggressive compression, while also exporting the original codec for [browsers that are late to the party][link-caniuse] (ahem Safari, Firefox, Edge, ...)?
A lighter web is now more important than ever, with cloud computing taking off and their [ridiculous bandwidth costs][link-bandwidth-costs]! Next to video, images are the largest payload for videos to provide, incurring significant costs if not done correctly, not to mention extra charges and wait times for the user.

Webpack... Angular... React... PHP... Cloudflare... So many solutions for serving images, some terrible, some paid. What if you just want to serve modern [WebP][link-webp-speed] images with [srcset][link-srcset] optimization, [lazy-loading][link-lazy-sizes] (with low-quality placeholder OR amazing traced-SVGs), fingerprint cache-busting, aggressive compression, while also exporting the original codec for [browsers that are late to the party][link-caniuse] (ahem Safari, Firefox, Edge, ...)?


<p align="center">
Is that really too much to ask?
Expand All @@ -58,6 +62,8 @@ That's just all that you <i>can</i> do, RIB can help you with any combination of

### What this does

*Chuck any high-quality originals in a folder, and RIB will non-destructively create a set of web-optimized responsive images for each original image in another folder. No more manual resizing, compressing, "where did I put the original?".*

In it's most basic form. with no additional configuration, RIB will scan a given directory for image files, and export them to a folder of your choosing. The export process consists of creating four different sized images from the source, converting a WebP copy of each size, optimizing them for web use before saving them using unique and predictable files names.

Finally, a [manifest](#manifest) file in [JSON][link-json] format is saved along with the images, containing information about every image's exported sizes, format, accompanying WebP file, final URL, etc...
Expand All @@ -68,9 +74,9 @@ The resulting manifest file is a few KB of data that lets you easily resolve an

It follows the [KISS principle][link-kiss]. We tend to over-complicate everything when it comes to website development when usually most things can be done really simply...

Of course, more elaborate websites require complicated design principles to scale better, but they should have a custom build pipeline anyway, such as a script that suits their needs perfectly (which, incidentally, is how this project came to be).
Of course, more elaborate websites require complicated design principles to scale better, but they should have a custom build pipeline that suits their needs perfectly (which, incidentally, is how this project came to be).

RIB makes it easy to take a set of high-quality source images and just make them work on the web. Optimized, with several different responsive breakpoints, the assurance of no duplicate files meaning no wasted space or bandwidth. See the [example](example/) to see what it does.
RIB makes it easy to take a set of high-quality source images and just make them work on the web. Optimized, with several different responsive breakpoints, the assurance of no duplicate sizes or files meaning no wasted space or bandwidth. See the [example](example/) to see what it does.

<p align="center">
<a href="https://i.ibb.co/GP0NW93/Responsive-Image-Builder.png">
Expand Down Expand Up @@ -517,6 +523,31 @@ This will enable fingerprinting, adding a new property to the `original` group o
"fingerprint": "5ae7554b" # When using --short-hash
```

## SVG Placeholders

RIB supports [potrace][link-potrace] to create a beautiful SVG placeholder. It can be used like [this][link-traced-svg] as a tiny (2-6KB) placeholder until you have downloaded the full high quality image. In some ways it provides a more pleasing experience than a blurred 8x8 thumbnail.

SVGs are vector graphics that scale to any resolution, it only contains primitive shapes that represents strong edges/contrasts in the source image.

By default, RIB will create a traced image for every non-SVG export. You can customize the name of this traced image using the `traceTemplate` config option.

The `traceOptions` configuration property will pass down all options to [potrace][link-potrace], this lets you change the colour and complexity of the image.

**Example**

```javascript
rib({
traceOptions: {
color: 'lightgray',
optTolerance: 0.4,
turdSize: 100,
turnPolicy: potrace.Potrace.TURNPOLICY_MAJORITY
}
})
```

<p align="center"><sub>You may need to import the potrace library, or used hard-coded constant values</sub></p>

## Typescript

Since v2.0.0, the entire project has been rewritten in Typescript. This not only provides more robust compilation with less chance of stupid errors but also provides strong typings for practically all function parameters and returns.
Expand Down Expand Up @@ -566,7 +597,9 @@ And of course, at the end of the pipeline are beautifully compressed images.

## Converting

Converting is used to change the format of the fallback image, and can be done using the `convert` option. This can be used, for example, to convert high-quality TIFF image files into JPEG and WebP images optimized for the web. It allows for slightly more compatibility and automation during the build process.
Converting is used to change the format of the image before entering the pipeline. This is done using the `convert` option.

Converting allows you to, for example, convert high-quality TIFF image files into JPEG (and the accompanying WebP image), which is far more compatible, without the need to convert the original yourself.

## Troubleshooting

Expand Down Expand Up @@ -607,7 +640,6 @@ See [changelog][link-changelog].

Stretch goals for the next feature release. Completed goals are removed after the following feature release.

- [ ] Add support for pre-load [traced SVGs](https://github.com/tooolbox/node-potrace) ([demo](https://using-gatsby-image.gatsbyjs.org/traced-svg/))
- [ ] If not cleaning, merge *manifest.json* with existing
- [ ] Support "synchronize" mode where only missing images are exported
- [ ] Add filename reservation for consistent incrementation
Expand All @@ -621,6 +653,7 @@ Stretch goals for the next feature release. Completed goals are removed after th
- [x] Add codec conversion support (e.g. TIFF -> JPEG) (`convert` option)
- [x] Add checksum to manifest for better image searching (`fingerprint` option)
- [x] Add example with new WebP optimizer and better optimizer settings
- [x] Add support for pre-load traced SVGs

### Quirks

Expand Down Expand Up @@ -656,10 +689,13 @@ Stretch goals for the next feature release. Completed goals are removed after th
[link-marcuscemes]:https://github.com/MarcusCemes
[link-wiki]:https://github.com/MarcusCemes/responsive-image-builder/wiki/

[link-libvips-speed]:https://github.com/jcupitt/libvips/wiki/Speed-and-memory-use
[link-traced-svg]:https://using-gatsby-image.gatsbyjs.org/traced-svg/
[link-webp-speed]:https://developers.google.com/speed/webp/
[link-srcset]:https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images
[link-lazy-sizes]:https://github.com/aFarkas/lazysizes
[link-caniuse]:https://caniuse.com/#feat=webp
[link-bandwidth-costs]:https://news.ycombinator.com/item?id=11301085
[link-json]:https://en.wikipedia.org/wiki/JSON
[link-kiss]:https://en.wikipedia.org/wiki/KISS_principle
[link-win-nvm]:https://github.com/coreybutler/nvm-windows
Expand All @@ -672,4 +708,5 @@ Stretch goals for the next feature release. Completed goals are removed after th
[link-mozjpeg]:https://www.npmjs.com/package/imagemin-mozjpeg
[link-svgo]:https://www.npmjs.com/package/imagemin-svgo
[link-gifsicle]:https://www.npmjs.com/package/imagemin-gifsicle
[link-semantic-release]:https://github.com/semantic-release/semantic-release
[link-semantic-release]:https://github.com/semantic-release/semantic-release
[link-potrace]:https://github.com/tooolbox/node-potrace
9 changes: 7 additions & 2 deletions bin/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,15 @@ program
.option("-f, --fingerprint", "Enable original file fingerprinting (manifest entry)")
.option("-a, --hash-algorithm [algorithm]", "The fingerprint algorithm to use, such as 'md5'")
.option("-s, --short-hash", "Trim hashes in the manifest file to only a few characters")
.option("--no-trace", "Disable placeholder SVG tracing")
.option("--no-fallback", "Disable fallback format exports")
.option("--no-webp", "Disable WebP format exports")
.option("--no-resize", "Disable image resizing (based on export presets)")
.option("--no-optimize", "Disable image optimization")
.option("-c, --convert [format]", "Convert the fallback format to the specified format")
.option("--single-template [template]", "The template to use for file-naming single exports")
.option("--multiple-template [template]", "The template to sue fo file-naming multiple export")
.option("--multiple-template [template]", "The template to sue for file-naming multiple export")
.option("--trace-template [template]", "The template to sue for SVG traces")

.parse(process.argv);

Expand All @@ -72,6 +74,7 @@ explorer.search()
config = config || {}; // read config
const CLIConfig = {}; // config from flags

/** Map the CLI option names to config keys */
const configMappings = {
in: null,
out: null,
Expand All @@ -91,7 +94,9 @@ explorer.search()
convert: null,
singleTemplate: "singleExportTemplate",
multipleTemplate: "multipleExportTemplate",
fingerprint: null
fingerprint: null,
trace: null,
traceTemplate: null
}

for (const prop of Object.keys(configMappings)) {
Expand Down
1 change: 1 addition & 0 deletions example/export/a-pretty-background_traced.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 58f0471

Please sign in to comment.