Module: CarrierWave::Cloudflare::ActionView::ResponsiveImagesHelper

Defined in:
lib/carrierwave/cloudflare/action_view/responsive_images_helper.rb

Constant Summary collapse

CDN_TRANSFORM_KEYS =
CarrierWave::Cloudflare::URL::ALLOWED_OPTIONS.map(&:to_sym)

Instance Method Summary collapse

Instance Method Details

#cdn_transformed(url, **options) ⇒ Object

Returns an image URL with CDN transformations applied. Can process already transformed URLs, in that case the options will be merged together.

Examples

cdn_transformed('/img.jpg', width: 400)
# => '/cdn-cgi/image/width=400/img.jpg'

cdn_transformed('/cdn-cgi/image/width=100,fit=pad/img.jpg', width: 333)
# => '/cdn-cgi/image/width=333,fit=pad/img.jpg'


21
22
23
24
25
26
27
28
29
# File 'lib/carrierwave/cloudflare/action_view/responsive_images_helper.rb', line 21

def cdn_transformed(url, **options)
  base_options = BaseUploader.default_cdn_options

  CarrierWave::Cloudflare::URL.transform(
    url,
    **base_options,
    **options
  )
end

#hidpi_image_srcset(url, dprs: nil, **options) ⇒ Object

Like #hidpi_image_tag, but returns an scrset attribute value.



57
58
59
60
61
62
63
64
65
# File 'lib/carrierwave/cloudflare/action_view/responsive_images_helper.rb', line 57

def hidpi_image_srcset(url, dprs: nil, **options)
  return nil unless url.present?

  url = url.url if url.is_a?(CarrierWave::Uploader)

  (dprs || [1, 2]).map do |dpr|
    [cdn_transformed(url, dpr: dpr, **options), "#{dpr}x"].join(" ")
  end.join(", ")
end

#hidpi_image_tag(url, dprs: nil, **options) ⇒ Object

Returns an image tag with with scaled variations (via srcset) attribute for devices with different DPR values.

The transformation of the original image should be specified via options.

Examples

hidpi_image_tag('/bird.jpg', width: 400, height: 100, alt: 'A bird')

hidpi_image_tag('/bird.jpg', width: 400, drps: [1, 2])


43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/carrierwave/cloudflare/action_view/responsive_images_helper.rb', line 43

def hidpi_image_tag(url, dprs: nil, **options)
  url = url.url if url.is_a?(CarrierWave::Uploader)
  transform, rest = split_cdn_transform_options(options)

  image_tag(
    cdn_transformed(url, **transform),
    srcset: hidpi_image_srcset(url, dprs: dprs, **transform),
    width: transform[:width],
    height: transform[:height],
    **rest
  )
end

#responsive_image_tag(url, width:, sizes: nil, dprs: [1, 2], **options) ⇒ Object

Returns a reponsive image tag with variations.

Examples

responsive_image_tag('/bird.jpg', width: 1200, sizes:
                   { phone: 600, tablet: 800 })


74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/carrierwave/cloudflare/action_view/responsive_images_helper.rb', line 74

def responsive_image_tag(url, width:, sizes: nil, dprs: [1, 2], **options)
  url = url.url if url.is_a?(CarrierWave::Uploader)

  if sizes.nil?
    return hidpi_image_tag(url, width: width, **options)
  end

  sizes[:default] = width

  breakpoints = {
    phone: "(max-width: 767px)",
    mobile: "(max-width: 767px)", # an alias for :phone
    tablet: "(max-width: 1023px)",
    laptop: "(max-width: 1279px)",
    desktop: "(min-width: 1280px)",
    default: nil
  }

  sizes_attr = breakpoints.map do |device, media|
    next nil unless sizes[device]

    [media, "#{sizes[device]}px"].compact.join(" ")
  end.compact.join(", ")

  transform, rest = split_cdn_transform_options(options)
  base_version = cdn_transformed(url, width: width, **transform)

  # construct the array of available variation sizes in `srcset`
  variations = scrset_variations_from_breakpoints(sizes, dprs: dprs)

  srcset = variations.map do |size|
    scale = (size.to_f / width).round(2)
    [cdn_transformed(url, width: width, **transform, dpr: scale), "#{size}w"]
  end

  image_tag(
    base_version,
    srcset: srcset,
    sizes: sizes_attr,
    width: width,
    height: transform[:height],
    **rest
  )
end

#scrset_variations_from_breakpoints(breakpoints, dprs:, granularity: 180) ⇒ Object



119
120
121
122
123
124
125
# File 'lib/carrierwave/cloudflare/action_view/responsive_images_helper.rb', line 119

def scrset_variations_from_breakpoints(breakpoints, dprs:, granularity: 180)
  # [300, 900] => [300, 600, 900, 1800]
  doubled = breakpoints.values.product(dprs).map { |s, d| (s * d).round }

  # [100, 101, 150, 250, 320] => [100, 250, 320]
  doubled.uniq { |s| s / granularity }
end

#split_cdn_transform_options(options) ⇒ Object

returns a pair of transformation options and other options



128
129
130
131
132
133
# File 'lib/carrierwave/cloudflare/action_view/responsive_images_helper.rb', line 128

def split_cdn_transform_options(options)
  [
    options.slice(*CDN_TRANSFORM_KEYS),
    options.except(*CDN_TRANSFORM_KEYS)
  ]
end