PageSourceSearch

https://victoriaspb.ru/js/galery.js

js victoriaspb.ru collected 2026-10-06 13:17:37 UTC 3,983 bytes, 164 lines download raw bytes

1class HeroGallery {
2
3    constructor(selector) {
4
5        this.container = document.querySelector(selector);
6        this.images = JSON.parse(this.container.dataset.gallery);
7        this.thumbs = this.container.querySelectorAll("img");
8
9        this.index = 0;
10
11        this.startX = 0;
12        this.deltaX = 0;
13
14        this.createViewer();
15        this.bind();
16    }
17
18    createViewer() {
19
20        this.viewer = document.createElement("div");
21        this.viewer.className = "gallery-viewer hidden";
22
23        this.track = document.createElement("div");
24        this.track.className = "gallery-track";
25
26        this.images.forEach(img => {
27
28            const slide = document.createElement("div");
29            slide.className = "gallery-slide";
30
31            const clone = new Image();
32            clone.src = "./galery/" + img;
33
34            slide.append(clone);
35            this.track.append(slide);
36
37        });
38
39        this.prev = document.createElement("button");
40        this.prev.className = "gallery-nav gallery-prev";
41        this.prev.innerHTML = "‹";
42
43        this.next = document.createElement("button");
44        this.next.className = "gallery-nav gallery-next";
45        this.next.innerHTML = "›";
46
47        this.closeBtn = document.createElement("button");
48        this.closeBtn.className = "gallery-close";
49        this.closeBtn.innerHTML = "×";
50
51        this.viewer.append(this.track, this.prev, this.next, this.closeBtn);
52
53        document.body.append(this.viewer);
54    }
55
56    bind() {
57
58        this.thumbs.forEach((img, i) => {
59            img.addEventListener("click", () => this.open(i));
60        });
61
62        this.prev.addEventListener("click", () => this.move(-1));
63        this.next.addEventListener("click", () => this.move(1));
64
65        this.viewer.addEventListener("click", e => {
66            if (e.target === this.viewer) this.close();
67        });
68
69        document.addEventListener("keydown", e => {
70
71            if (this.viewer.classList.contains("hidden")) return;
72
73            if (e.key === "Escape") this.close();
74            if (e.key === "ArrowRight") this.move(1);
75            if (e.key === "ArrowLeft") this.move(-1);
76
77        });
78
79        /* pointer swipe */
80
81        this.viewer.addEventListener("pointerdown", e => {
82
83            this.startX = e.clientX;
84            this.track.style.transition = "none";
85
86        });
87
88        this.viewer.addEventListener("pointermove", e => {
89
90            if (!this.startX) return;
91
92            this.deltaX = e.clientX - this.startX;
93
94            const w = this.viewer.clientWidth;
95
96            this.track.style.transform =
97                `translateX(${ -this.index * w + this.deltaX }px)`;
98
99        });
100
101        this.viewer.addEventListener("pointerup", () => {
102
103            this.track.style.transition = "";
104
105            if (Math.abs(this.deltaX) > 80) {
106
107                if (this.deltaX < 0) this.move(1);
108                else this.move(-1);
109
110            } else {
111                this.update();
112            }
113
114            this.startX = 0;
115            this.deltaX = 0;
116
117        });
118
119        this.viewer.addEventListener("pointercancel", () => {
120            this.startX = 0;
121            this.deltaX = 0;
122        });
123
124        this.closeBtn.addEventListener("click", () => this.close());
125
126    }
127
128    open(i) {
129
130        this.index = i;
131
132        this.viewer.classList.remove("hidden");
133
134        this.update();
135
136    }
137
138    close() {
139
140        this.viewer.classList.add("hidden");
141
142    }
143
144    move(dir) {
145
146        this.index += dir;
147
148        if (this.index < 0) this.index = this.images.length - 1;
149        if (this.index >= this.images.length) this.index = 0;
150
151        this.update();
152
153    }
154
155    update() {
156
157        const w = this.viewer.clientWidth;
158
159        this.track.style.transform =
160            `translateX(-${this.index * w}px)`;
161
162    }
163
164}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.