Class: Mayu::Resources::Types::Image

Inherits:
Base
  • Object
show all
Extended by:
T::Sig
Defined in:
lib/mayu/resources/types/image.rb

Defined Under Namespace

Classes: ImageDescriptor

Constant Summary collapse

FORMATS =
T.let([:webp], T::Array[Symbol])
BREAKPOINTS =
T.let(
  [120, 240, 320, 640, 768, 960, 1024, 1366, 1600, 1920, 3840].freeze,
  T::Array[Integer]
)
MarshalFormat =
T.type_alias { [ImageDescriptor, T::Array[ImageDescriptor], String] }

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#name

Constructor Details

#initialize(resource) ⇒ Image

Returns a new instance of Image.



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/mayu/resources/types/image.rb', line 37

def initialize(resource)
  @resource = resource

  content_hash = Base64.urlsafe_encode64(resource.content_hash)
  image_size = ImageSize.path(resource.absolute_path)

  extname = File.extname(resource.path)
  filename = "#{content_hash}.#{image_size.format}"

  @original =
    T.let(
      ImageDescriptor.new(
        format: image_size.format,
        width: image_size.width,
        height: image_size.height,
        filename: filename
      ),
      ImageDescriptor
    )

  breakpoints =
    BREAKPOINTS.select { _1 < image_size.width }.sort.reverse
  aspect_ratio = image_size.height / image_size.width.to_f

  formats = [image_size.format, *FORMATS].uniq

  @blur =
    T.let(
      [
        "convert",
        resource.absolute_path,
        "-resize",
        "16x16>",
        "-strip",
        "png:-"
      ].then { Shellwords.shelljoin(_1) }
        .then { `#{_1}` }
        .then { Base64.strict_encode64(_1) }
        .prepend("data:image/png;base64,"),
      String
    )

  @versions =
    T.let(
      formats
        .map do |format|
          breakpoints.map do |width|
            ImageDescriptor.new(
              format: format,
              width:,
              height: (width * aspect_ratio).to_i,
              filename: "#{content_hash}#{width}w.#{format}"
            )
          end
        end
        .flatten,
      T::Array[ImageDescriptor]
    )
end

Instance Attribute Details

#blurObject (readonly)

Returns the value of attribute blur.



34
35
36
# File 'lib/mayu/resources/types/image.rb', line 34

def blur
  @blur
end

#originalObject (readonly)

Returns the value of attribute original.



30
31
32
# File 'lib/mayu/resources/types/image.rb', line 30

def original
  @original
end

#versionsObject (readonly)

Returns the value of attribute versions.



32
33
34
# File 'lib/mayu/resources/types/image.rb', line 32

def versions
  @versions
end

Instance Method Details

#aspect_ratioObject



145
146
147
# File 'lib/mayu/resources/types/image.rb', line 145

def aspect_ratio
  original.width / original.height.to_f
end

#assetsObject



98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/mayu/resources/types/image.rb', line 98

def assets
  [
    Asset.new(
      @original.filename,
      Generators::CopyFile.new(@resource.absolute_path)
    ),
    *@versions.map do |version|
      Asset.new(
        version.filename,
        Generators::Image.new(@resource.absolute_path, version)
      )
    end
  ]
end

#generate_assets(asset_dir) ⇒ Object



114
115
116
# File 'lib/mayu/resources/types/image.rb', line 114

def generate_assets(asset_dir)
  assets.each { |asset| asset.process(asset_dir) }
end

#inspectObject



163
164
165
# File 'lib/mayu/resources/types/image.rb', line 163

def inspect
  "#<Image src=#{src.inspect}>"
end

#marshal_dumpObject



153
154
155
# File 'lib/mayu/resources/types/image.rb', line 153

def marshal_dump
  [@original, @versions, @blur]
end

#marshal_load(args) ⇒ Object



158
159
160
# File 'lib/mayu/resources/types/image.rb', line 158

def marshal_load(args)
  @original, @versions, @blur = args
end

#sizesObject



133
134
135
136
137
138
139
140
141
142
# File 'lib/mayu/resources/types/image.rb', line 133

def sizes
  [
    "100vw",
    *@versions
      .filter { _1.format == :webp }
      .map do |version|
        "(max-width: #{version.width}px) #{version.width}px"
      end
  ].reverse.join(", ")
end

#srcObject



119
120
121
# File 'lib/mayu/resources/types/image.rb', line 119

def src
  "/__mayu/static/#{@original.filename}"
end

#srcsetObject



124
125
126
127
128
129
130
# File 'lib/mayu/resources/types/image.rb', line 124

def srcset
  [@original, *@versions.filter { _1.format == :webp }].map do |version|
      "/__mayu/static/#{version.filename} #{version.width}w"
    end
    .reverse
    .join(",")
end