Skip to content

Duder-onomy/ember-cli-imgix

 
 

Repository files navigation

ember-cli-imgix

Build Status

An Ember addon for easily adding responsive imagery via imgix to your application. This addons supports FastBoot.

Note: Front-end imgix libraries and framework integrations will not work with imgix Web Proxy Sources. They will only work with imgix Web Folder or S3 Sources.

Overview / Resources

Before you get started with ember-cli-imgix, it's highly recommended that you read Eric Portis' seminal article on srcset and sizes. This article explains the history of responsive images in responsive design, why they're necessary, and how all these technologies work together to save bandwidth and provide a better experience for users. The primary goal of ember-cli-imgix is to make these tools easier for developers to implement, so having an understanding of how they work will significantly improve your ember-cli-imgix experience.

Below are some other articles that help explain responsive imagery, and how it can work alongside imgix:

Installation

From within an existing ember-cli project:

$ ember install ember-cli-imgix

Next, set up some configuration flags:

// config/environment.js

module.exports = function(environment) {
  var ENV = {
    // snip
    APP: {
      imgix: {
        source: 'my-social-network.imgix.net',
        debug: true // Prints out diagnostic information on the image itself. Turn off in production.
      }
    }
    // snip
  };
};

Usage

NOTE: These docs are for the latest version of ember-cli-imgix (version 1). For the old docs, please go here

imgix-image

ember-cli-imgix exposes a img element with expanded functionality. It simply renders an img, but has some extra parameters

{{imgix-image path='/users/1.png' sizes='100vw'}}

Which will generate some HTML similar to this:

<img
  class="imgix-image"
  src="https://my-social-network.com/users/1.png"
  sizes="100vw"
  srcset="https://my-social-network.com/users/1.png?w=100 100w, https://my-social-network.com/users/1.png?w=200 200w, ..."
/>

The src attribute will have imgix URL API parameters added to it to perform the resize.

Please note: 100vw is an appropriate sizes value for a full-bleed image. If your image is not full-bleed, you should use a different value for sizes. Eric Portis' "Srcset and sizes" article goes into depth on how to use the sizes attribute.

Since imgix can generate as many derivative resolutions as needed, ember-cli-imgix calculates them programmatically, using the dimensions you specify. All of this information has been placed into the srcset and sizes attributes.

Width and height known: If the width and height are known beforehand, it is recommended that they are set explicitly:

{{imgix-image path='/users/1.png' width=100 height=100}}

NB: Since this library sets fit to crop by default, when just a width or height is set, the image will resize and maintain aspect ratio. When both are set, the image will be cropped to that size, maintaining pixel aspect ratio (i.e. edges are clipped in order to not stretch the photo). If this isn't desired, set fit to be another value (e.g. clip)

Lazy Loading

If you'd like to lazy load images, we recommend using lazysizes. In order to use ember-cli-imgix with lazysizes, you can simply tell it to generate lazysizes-compatible attributes instead of the standard src, srcset, and sizes by changing some configuration settings:

// config/environment.js

module.exports = function(environment) {
  var ENV = {
    // snip
    APP: {
      imgix: {
        attributeNameMap: {
          src: 'data-src',
          srcset: 'data-srcset'
        }
      }
    }
    // snip
  };
};

Otherwise, you can use the component as normal.

NB: It is recommended to use the attribute change plugin in order to capture changes in the data-* attributes. Without this, changing the attributes to this library will have no effect on the rendered image.

Low Quality Image Placeholder Technique (LQIP)

If you'd like to use LQIP images we recommend using lazysizes. In order to use ember-cli-imgix with lazysizes, you can simply tell it to generate lazysizes-compatible attributes instead of the standard src, srcset by changing some configuration settings, and providing a fallback image to placeholderPath.

// config/environment.js

module.exports = function(environment) {
  var ENV = {
    // snip
    APP: {
      imgix: {
        attributeNameMap: {
          src: 'data-src',
          srcset: 'data-srcset'
        }
      }
    }
    // snip
  };
};
// usage

{{imgix-image path='/abc.png' placeholderPath='/abc.png?w=80&h=50' }}

NB: If the props of the image are changed after the first load, the low quality image will replace the high quality image. In this case, the src attribute may have to be set by modifying the DOM directly, or the lazysizes API may have to be called manually after the props are changed. In any case, this behaviour is not supported by the maintainers of ember-cli-imgix, so use at your own risk.

Parameters

You can pass through most of the params that imgix urls accept.

Some of the defaults are:

path: null, // The path to your image
crop: null,
fit: 'crop',
onLoad: null,
onError: null,
crossorigin: 'anonymous', // img element crossorigin attr
alt: '', // img element alt attr
draggable: true, // img element draggable attr
disableSrcSet: false, // disable srcSet generation
options: {}, // arbitrary imgix options

width: null, // override if you want to hardcode a width into the image
height: null, // override if you want to hardcode a height into the image

Other imgix options

If you want to pass in any other arbitrary imgix options, use the hash helper

{{imgix-image
  path='/users/1.png'
  options=(hash
    invert=true
  )
}}

Aspect Ratio

This component can also accept an ar parameter to constrain the aspect ratio of the returned image. The aspect ratio is specified in the format width:height. Either dimension can be an integer or a float. All of the following are valid: 16:9, 5:1, 1.92:1, 1:1.67.

{{imgix-image path="/users/1.png" crossorigin="anonymous" options=(hash ar="1.33:1"}}

Lifecycle hooks

This element also exposes onLoad and onError actions which you can hook into to know when the image has loaded or failed to load:

{{imgix-image
  path='/users/1.png'
  onLoad=(action 'handleImageLoad')
  onError=(action 'handleImageError')
}}

This will maintain the same aspect ratio as the image is resized.

Please see the dummy app for insight into setting this up and configuring this.

ixlib param

This library adds an ixlib parameter to generated image urls for two reasons: a) it helps Imgix support see what versions of libraries that customers are using, and b) it help Imgix to see how many people overall are using the ember library, and the specific versions.

If this behaviour is not desired, it can be turned off in two ways:

  1. Environment config
// config/environment.js

module.exports = function(environment) {
  var ENV = {
    // snip
    APP: {
      imgix: {
        // snip
        disableLibraryParam: true
      }
    }
    // snip
  };
};
  1. Component parameter
{{imgix-image path="/test.png" disableLibraryParam={true} }}

imgix-bg

This component will render a div whose background-image is set to the given image path. Content can be added within the imgix-bg tags and the component will automatically resize to fit around it.

{{#imgix-bg path='/users/1.png' }}
  Some content here
{{/imgix-bg}}

This will generate html similar to the following:

<div style="background-image: url('https://my-social-network.com/users/1.png?fit=crop&w=1246&h=15&dpr=2&ixlib=ember-2.0.0');background-size: cover" class="imgix-bg">    
  Some content here
</div>

Note: imgix-bg will respect any global default parameters unless explicitly overriden.

imgix-image-wrapped - DEPRECATED

This component is included to help migration from version 0.x. This component will be deprecated in version 2. Please use imgix-image instead.

ember-cli-imgix exposes a image container that works well for creating responsive images. It is a <div> element with a single <img> child element. Adding them to your templates is quite easy:

{{imgix-image-wrapped path="/users/1.png"}}

The HTML generated by this might look like the following:

<div>
  <img src="https://my-social-network.com/users/1.png?w=400&h=300&dpr=1" />
</div>

The src attribute will have imgix URL API parameters added to it to perform the resize.

Global Configuration

The global configuration for this library should be located in APP.imgix, and has the following schema:

imgix: {
  source: string,
  debug?: boolean,
  attributeNameMap?: {
    src: string
    srcset: string
    sizes: string
  }
}

It should look like this in config/environment.js.

// config/environment.js

module.exports = function(environment) {
  var ENV = {
    // snip
    APP: {
      imgix: {
        source: 'my-social-network.imgix.net',
        debug: true, // Prints out diagnostic information on the image itself. Turn off in production.
        classNames: 'imgix-image', // default class used on the img element
        defaultParams: {}, // optional params that will be used in all generated paths
      }
    }
    // snip
  };
};

attributeNameMap

attributeNameMap should be used if it is required to remap the HTML attribute to be used to set the src of the image. For example, if data-src should be used rather than src, attributeNameMap helps with this.

In the global config, attributeNameMap allows the following to be remapped: src, srcset, and sizes.

For example, to remap srcset to data-srcset:

attributeNameMap: {
  srcset: `data-srcset`
}

The equivalent works for src and sizes.

Imgix Core JS

Imgix core js is available to you shimmed as:

import ImgixCoreJs from 'imgix-core-js';

Upgrade Guide

version 0.x to version 1

imgix-image has been replaced by a new implementation of imgix-image-element. All usage of imgix-image-element can be replaced with imgix-image. No parameter changes are necessary.

imgix-image has been renamed to imgix-image-wrapped and has been deprecated. All usage of imgix-image can be replaced with imgix-image-wrapped for the duration of version 2. No parameter changes are necessary. After version 2, imgix-image-wrapped will not exist.

version 1.x to version 2.x

The largest change in this major version bump is the move to width-based srcSet and sizes for responsiveness. This has a host of benefits, including better server rendering, better responsiveness, less potential for bugs, and perfomance improvements.

  • A sizes prop should be added to all usages of ember-cli-imgix, unless the width or height of the image are known beforehand (see above). If sizes is new to you (or even if it's not), Eric's seminal article on srcset and sizes is highly recommended.
  • aspectRatio has been moved to options.ar. Thus, aspectRatio has been deprecated. It will be supported until the v3 release. The format of the new options.ar attribute is w:h.

Browser Support

  • By default, browsers that don't support srcset, sizes, or picture will gracefully fall back to the default img src when appropriate. If you want to provide a fully-responsive experience for these browsers, ember-cli-imgix works great alongside Picturefill!
  • We support the latest version of Google Chrome (which automatically updates whenever it detects that a new version of the browser is available). We also support the current and previous major releases of desktop Firefox, Internet Explorer, and Safari on a rolling basis. Mobile support is tested on the most recent minor version of the current and previous major release for the default browser on iOS and Android (e.g., iOS 9.2 and 8.4). Each time a new version is released, we begin supporting that version and stop supporting the third most recent version.

Running a test app

To see this in action with some stock photos, clone this repo and then run ember serve

git clone git@github.com:imgix/ember-cli-imgix.git
cd ember-cli-imgix
ember serve

Now visit http://localhost:4200.

Running Tests

Pretty simple:

ember test

About

Easily add imgix functionality to your Ember app

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • JavaScript 89.5%
  • HTML 7.1%
  • CSS 3.4%