-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGalleryEngine.ts
More file actions
232 lines (187 loc) · 6.8 KB
/
Copy pathGalleryEngine.ts
File metadata and controls
232 lines (187 loc) · 6.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
interface GalleryImage {
src: string
alt?: boolean
}
interface ImageCollection {
portrait: HTMLElement[]
landscape: HTMLElement[]
square: HTMLElement[]
}
class Gallery {
container: HTMLElement
rootSrcString = ""
galleryImages: GalleryImage[]
constructor(container: HTMLElement, rootSrc: string, galleryImages: GalleryImage[]) {
this.container = container
this.galleryImages = galleryImages
this.rootSrcString = rootSrc
this.container.innerHTML = `
<div class="span-v-4 loading"></div>
<div class="span-v-2 loading"></div>
<div class="span-v-2 loading"></div>
<div class="span-v-4 loading"></div>
`
this.loadImage(0)
}
images: ImageCollection = {
portrait: [],
landscape: [],
square: []
}
imagesUsed = {
portrait: 0,
landscape: 0,
square: 0
}
loadImage(position: number) {
if(position >= this.galleryImages.length) return
let img = new Image()
img.src = this.rootSrcString + this.galleryImages[position].src
img.onload = () => {
this.classifyGalleryImage(img, this.galleryImages[position])
this.generateGallery()
this.loadImage(position + 1)
img.onload = () => {}
}
}
classifyGalleryImage(img: HTMLImageElement, imageData: GalleryImage) {
let div = document.createElement("div")
if (imageData.alt == true) {//alternate is provided for that image - add toggle eye icon
const swap = document.createElement("div")
swap.dataset.filename = imageData.src
swap.dataset.mode = "0"
swap.className = "swap"
swap.title = "click to see before/after"
swap.innerHTML = `<i class="fa-solid fa-eye"></i>`
// Use the bound method here
swap.addEventListener("mousedown", (e) => this.changeImage(swap))
div.appendChild(swap)
}
div.appendChild(img)
if (img.height > img.width * 1.1) { //portrait
div.classList.add("span-v-2")
this.images.portrait.push(div)
} else if (img.width > img.height * 1.1) { //landscape
div.classList.add("span-v-4")
this.images.landscape.push(div)
} else { // "square"
div.classList.add("span-v-3")
this.images.square.push(div)
}
}
generateGallery() {
console.log("generate galery")
let html: HTMLElement[] = []
this.images.landscape = this.sortBySrc(this.images.landscape)
this.images.portrait = this.sortBySrc(this.images.portrait)
this.images.square = this.sortBySrc(this.images.square)
this.imagesUsed = {
portrait: 0,
landscape: 0,
square: 0
}
let nextSelect = 0 //counter from 0 to 3 - used to push images in the order 0110011001100
for (let i = 0; i < this.images.portrait.length + this.images.square.length + this.images.landscape.length; i++) {
let image
let nextup: "portrait" | "landscape" = "portrait"
if ([2, 1].includes(nextSelect)) {
nextup = "portrait"
} else if ([0, 3].includes(nextSelect)) {
nextup = "landscape"
}
nextSelect = (nextSelect + 1) % 4
if (!this.images[nextup][this.imagesUsed[nextup]]) { //array of selected images (landscape, portrait) is used up (pos is undefined)
nextup = nextup == "portrait" ? "landscape" : "portrait" //switch to the other image type
}
if (this.imagesUsed.portrait > 0 && !this.images.portrait[this.imagesUsed.portrait - 1]) {//imageUsedcount is positiv(first check could be -1) && no portraits are left - add square class
}
if (!this.images.portrait[this.imagesUsed.portrait]) {
if (!this.images.portrait[this.imagesUsed.portrait - 1]) { //no more portrait images left
this.images.landscape[this.imagesUsed.landscape]?.classList.add("endpiece") //add endpiece classes to following landscape imgs(not have a portrait to partner with)
if (!this.images.landscape[this.imagesUsed.landscape + 1] && !this.images.square[this.imagesUsed.square]) {
this.images.landscape[this.imagesUsed.landscape]?.classList.add("last")
}
}
if (
this.images.portrait[this.imagesUsed.portrait - 1] && //since imagesUse[0] is also ++d if its undefined you have to check for the one before as well
html.length % 2 == 0 //the count has to be even (otherwise the last two were portraits anyway so everything looks fine)
) { //cant even explain, hav fun re learing //stupid fuck I understand now :)
this.images.landscape[this.imagesUsed.landscape]?.classList.add("krueppel", "endpiece")
}
this.imagesUsed.portrait = 99999
}
//actually selects and adds next image
image = this.images[nextup][this.imagesUsed[nextup]]
if (image) {
html.push(image)
}
this.imagesUsed[nextup]++
//every thrid one has the option to display squares
if ((i + 2) % 3 == 0 && this.images.square[this.imagesUsed.square] && this.images.square[this.imagesUsed.square + 1]) {
for (let i = 0; i < 2; i++) {
html.push(this.images.square[this.imagesUsed.square])
this.imagesUsed.square++
}
}
}
//adds all remaining squares
while (this.images.square[this.imagesUsed.square]) {
html.push(this.images.square[this.imagesUsed.square])
this.imagesUsed.square++
}
if(this.images.portrait.length + this.images.square.length + this.images.landscape.length < this.galleryImages.length) {
do {
let div = document.createElement("div")
div.classList.add(...["span-v-2", "loading"])
html.push(div)
} while (html.length < 4)
}
this.container!.innerHTML = ""
this.container!.append(...html)
}
sortBySrc(sortMe: HTMLElement[]) {
sortMe.sort(function (a, b) {
let aImage = a.querySelector("img") as HTMLImageElement
let bImage = b.querySelector("img") as HTMLImageElement
if(!aImage) return 1
if(!bImage) return -1
if(!aImage && !bImage) return 0
if (aImage.src < bImage.src) {
return -1
}
if (aImage.src > bImage.src) {
return 1
}
return 0
})
return sortMe
}
timeOnClick = Date.now();
changeImage(elem: HTMLElement, forcePhone = false) {
let filename = elem.getAttribute("data-filename")
if (window.innerWidth > 800 && forcePhone === false) { //pc behaviour
this.timeOnClick = Date.now()
elem.addEventListener("mouseup", () => {
if (Date.now() - this.timeOnClick > 300) {
elem.parentNode.querySelector("img").src = this.rootSrcString + filename
} else {
setTimeout(() => {
elem.parentNode.querySelector("img")!.src = this.rootSrcString + filename
}, 300 - (Date.now() - this.timeOnClick))
}
elem.removeEventListener("mouseup", () => {
})
})
elem.parentNode.querySelector("img").src = this.rootSrcString + "alt/" + filename;
}
else { //phone behaviour
if (elem.parentNode.querySelector("img").getAttribute("data-mode") == "0") {
elem.parentNode.querySelector("img").setAttribute("data-mode", "1")
elem.parentNode.querySelector("img").src = this.rootSrcString + filename
} else {
elem.parentNode.querySelector("img").setAttribute("data-mode", "0")
elem.parentNode.querySelector("img").src = this.rootSrcString + "alt/" + filename;
}
}
}
}