Skip to content

Instantly share code, notes, and snippets.

@brettburwell
Last active June 26, 2018 09:05
Show Gist options
  • Star 21 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save brettburwell/8d4b58a8cd8a34b847f668389f1b540a to your computer and use it in GitHub Desktop.
Save brettburwell/8d4b58a8cd8a34b847f668389f1b540a to your computer and use it in GitHub Desktop.
Craft macro to centralize the markup and config for responsive images
{# ================================================================== #}
{# Responsive Image Macro
{# ================================================================== #}
{#
Macro to centralize the markup and config for responsive images.
Based on an article by Marion Newlevant (@marionnewlevant) and
adapted for the Lazysizes plugin. Read more:
https://straightupcraft.com/articles/responsive-images-with-twig-macros
Relies on the following Craft plugins:
Imager: https://github.com/aelvan/Imager-Craft
FocusPoint: https://github.com/smcyr/Craft-FocusPoint
Relies on the following front-end plugin:
LazySizes: https://github.com/aFarkas/lazysizes
#}
{# ================================================================== #}
{# Srcset
{# ================================================================== #}
{#
{% set options = {
alt: alt | default(''),
class: class | default(''),
img: img,
imgType: imgType | default(null)
} %}
{{ macroImg.srcset(options) }}
Available options:
@param alt (string) - [optional] Text for alt tag
@param class (string) - [optional] Classes to apply to img
@param dataExpand (string) - [optional] Sets custom Lazysizes data-expand attribute
@param effectType (string) - [optional] Determines if Imager should add effects to the transforms. String should match case in switch statement below. See Imager docs for more info on what's possible.
@param img (asset) - [required] Craft image asset
@param imgType (string) - [required] Determines which transform settings should be used to generate srcset markup. String should match case in switch statement below.
{# ------------------------------------------------------------------ #}
{% macro srcset(options) %}
{# Set some defaults #}
{% set defaults = {
alt: null,
class: '',
dataExpand: '400-800',
effectType: null,
imgType: null,
sizes: 'auto'
} %}
{# Merge options with defaults #}
{% set options = defaults|merge(options) %}
{# If necessary, define transform effects #}
{% switch options.effectType %}
{% case 'greyscale' %}
{% set effectsArray = { grayscale: true, contrast: 0 } %}
{% default %}
{% set effectsArray = { } %}
{% endswitch %}
{# Define transform settings based on image type #}
{% switch options.imgType %}
{% case '1x1' %}
{% set imageRatioWidth = 1 %}
{% set imageRatioHeight = 1 %}
{% set mode = 'crop' %}
{% set imageSizes = [
{ width: 1200 },
{ width: 900 },
{ width: 600 },
{ width: 300 }
] %}
{% case 'carousel' %}
{% set imageRatioWidth = 2 %}
{% set imageRatioHeight = 1.25 %}
{% set mode = 'crop' %}
{% set imageSizes = [
{ width: 2000, ratio: 2/1.25 },
{ width: 1600, ratio: 2/1.25 },
{ width: 1000, ratio: 1/1.25 },
{ width: 600, ratio: 4/3 }
] %}
{% default %}
{% set imageRatioWidth = 1 %}
{% set imageRatioHeight = 0.76 %}
{% set mode = 'fit' %}
{% set imageSizes = [
{ width: 1600 },
{ width: 1200 },
{ width: 800 },
{ width: 500 }
] %}
{% endswitch %}
{# Set Srcset Transform #}
{% set transformedImages = craft.imager.transformImage(options.img, imageSizes, { mode: mode, effects: effectsArray, position: (options.img.focusPctX ?? '50') ~ '% ' ~ (options.img.focusPctY ?? '50') ~ '%', jpegQuality: 80, interlace: true }) %}
{# Output lazysizes srcset markup #}
<img class="{{ options.class }} lazysizes"
alt="{{ options.alt ?? options.img.title }}"
src="{{ craft.imager.base64Pixel(imageRatioWidth, imageRatioHeight) }}"
data-sizes="{{ options.sizes }}"
data-srcset="{{ craft.imager.srcset(transformedImages) }}"
data-expand="{{ options.dataExpand }}"
>
{% endmacro %}
@nternetinspired
Copy link

Epic! This is exactly what I needed. Thank you @brettburwell 🙇

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment