100 lines
3.0 KiB
Swift
100 lines
3.0 KiB
Swift
import Foundation
|
|
|
|
/**
|
|
An element showing a selection of images one by one using navigation buttons.
|
|
*/
|
|
struct ImageGallery: HtmlProducer {
|
|
|
|
/// The unique id to distinguish different galleries in HTML and JavaScript
|
|
let id: String
|
|
|
|
/// The images to display
|
|
let images: [ImageSet]
|
|
|
|
let standalone: Bool
|
|
|
|
/// A version of the id that is safe to use in HTML and JavaScript
|
|
private var htmlSafeId: String {
|
|
ImageGallery.htmlSafe(id)
|
|
}
|
|
|
|
init(id: String, images: [ImageSet], standalone: Bool = false) {
|
|
self.id = id
|
|
self.images = images
|
|
self.standalone = standalone
|
|
}
|
|
|
|
func populate(_ result: inout String) {
|
|
guard !images.isEmpty else {
|
|
return
|
|
}
|
|
|
|
result += "<div id='\(htmlSafeId)' class='swiper\(standalone ? " swiper-standalone" : "")'><div class='swiper-wrapper'>"
|
|
|
|
let needsPagination = images.count > 1
|
|
|
|
for image in images {
|
|
let sizeText = image.image.getImageDimensions().map { " style='aspect-ratio: \(Int($0.width)) / \(Int($0.height))'"}
|
|
result += "<div class='swiper-slide'\(sizeText ?? "")>"
|
|
result += image.content
|
|
if needsPagination {
|
|
result += "<div class='swiper-lazy-preloader swiper-lazy-preloader-white'></div>"
|
|
}
|
|
result += "</div>" // Close swiper-slide
|
|
}
|
|
|
|
result += "</div>" // Close swiper-wrapper
|
|
if needsPagination {
|
|
result += "<div class='swiper-button-next'></div>"
|
|
result += "<div class='swiper-button-prev'></div>"
|
|
result += "<div class='swiper-pagination'></div>"
|
|
}
|
|
result += "</div>" // Close swiper
|
|
}
|
|
|
|
private static func htmlSafe(_ id: String) -> String {
|
|
id.replacingOccurrences(of: "-", with: "_")
|
|
}
|
|
|
|
var javascriptInit: String {
|
|
ImageGallery.swiperInit(id: id)
|
|
}
|
|
|
|
var standaloneFooter: String {
|
|
"<script> window.onload = () => {\n\(javascriptInit)\n}; </script>"
|
|
}
|
|
|
|
static func combinedFootor(ids: [String]) -> String {
|
|
var result = ["<script> window.onload = () => { "]
|
|
for id in ids {
|
|
result.append(swiperInit(id: id))
|
|
}
|
|
result.append("}; </script>")
|
|
return result.joined(separator: "\n")
|
|
}
|
|
|
|
private static func swiperInit(id: String) -> String {
|
|
let id = htmlSafe(id)
|
|
return """
|
|
var swiper_\(id) = new Swiper("#\(id)", {
|
|
loop: true,
|
|
lazy: {
|
|
loadPrevNext: false,
|
|
},
|
|
slidesPerView: 1,
|
|
spaceBetween: 30,
|
|
centeredSlides: true,
|
|
keyboard: { enabled: true },
|
|
pagination: {
|
|
el: "#\(id) .swiper-pagination",
|
|
clickable: true
|
|
},
|
|
navigation: {
|
|
nextEl: "#\(id) .swiper-button-next",
|
|
prevEl: "#\(id) .swiper-button-prev"
|
|
}
|
|
});
|
|
"""
|
|
}
|
|
}
|