65 lines
2.4 KiB
Swift
65 lines
2.4 KiB
Swift
import Foundation
|
|
|
|
struct ImageSet: HtmlProducer {
|
|
|
|
let image: FileResource
|
|
|
|
let maxWidth: Int
|
|
|
|
let maxHeight: Int
|
|
|
|
let quality: CGFloat
|
|
|
|
let description: String?
|
|
|
|
let extraAttributes: String
|
|
|
|
init(image: FileResource, maxWidth: Int, maxHeight: Int, description: String?, quality: CGFloat = 0.7, extraAttributes: String? = nil) {
|
|
self.image = image
|
|
self.maxWidth = maxWidth
|
|
self.maxHeight = maxHeight
|
|
self.description = description
|
|
self.quality = quality
|
|
self.extraAttributes = extraAttributes ?? ""
|
|
}
|
|
|
|
var jobs: [ImageVersion] {
|
|
let type = image.type
|
|
|
|
let width2x = maxWidth * 2
|
|
let height2x = maxHeight * 2
|
|
|
|
return [
|
|
.init(image: image, type: .avif, maximumWidth: maxWidth, maximumHeight: maxHeight, quality: quality),
|
|
.init(image: image, type: .avif, maximumWidth: width2x, maximumHeight: height2x, quality: quality),
|
|
.init(image: image, type: .webp, maximumWidth: maxWidth, maximumHeight: maxHeight, quality: quality),
|
|
.init(image: image, type: .webp, maximumWidth: width2x, maximumHeight: height2x, quality: quality),
|
|
.init(image: image, type: type, maximumWidth: maxWidth, maximumHeight: maxHeight, quality: quality),
|
|
.init(image: image, type: type, maximumWidth: width2x, maximumHeight: height2x, quality: quality)
|
|
]
|
|
}
|
|
|
|
private var imageAltText: String {
|
|
guard let description else {
|
|
return ""
|
|
}
|
|
return " alt='\(description.htmlEscaped())'"
|
|
}
|
|
|
|
func populate(_ result: inout String) {
|
|
let fileExtension = image.type.fileExtension.map { "." + $0 } ?? ""
|
|
|
|
let prefix1x = "/\(image.outputImageFolder)/\(maxWidth)x\(maxHeight)"
|
|
let prefix2x = "/\(image.outputImageFolder)/\(maxWidth*2)x\(maxHeight*2)"
|
|
|
|
let aspectRatio = (image.getImageDimensions()?.scaledToFit(in: .init(width: maxWidth, height: maxHeight)))
|
|
.map { " aspect-ratio='\(Int($0.width)) / \(Int($0.height))'" }
|
|
|
|
result += "<picture>"
|
|
result += "<source type='image/avif' srcset='\(prefix1x).avif 1x, \(prefix2x).avif 2x'/>"
|
|
result += "<source type='image/webp' srcset='\(prefix1x).webp 1x, \(prefix1x).webp 2x'/>"
|
|
result += "<img srcset='\(prefix2x)\(fileExtension) 2x' src='\(prefix1x)\(fileExtension)'\(aspectRatio ?? "") loading='lazy'\(imageAltText)\(extraAttributes)/>"
|
|
result += "</picture>"
|
|
}
|
|
}
|