Browse Source

Use CSS grids instead of JS Gridify.

master
Syfaro 2 weeks ago
parent
commit
393c0495de
4 changed files with 49 additions and 139 deletions
  1. 2
    2
      layouts/char/list.html
  2. 33
    27
      layouts/partials/char/grid.html
  3. 0
    110
      themes/fox/assets/js/app.js
  4. 14
    0
      themes/fox/static/css/fox.css

+ 2
- 2
layouts/char/list.html View File

@@ -13,13 +13,13 @@
13 13
         <section class="artwork">
14 14
             <h3>Artwork</h3>
15 15
 
16
-            <div class="grid" id="art">
16
+            <div id="art">
17 17
                 {{ partial "char/grid.html" (dict "ctx" . "type" "artwork") }}
18 18
             </div>
19 19
 
20 20
             <h3>Icons</h3>
21 21
 
22
-            <div class="grid" id="icons">
22
+            <div id="icons">
23 23
                 {{ partial "char/grid.html" (dict "ctx" . "type" "icon") }}
24 24
             </div>
25 25
         </section>

+ 33
- 27
layouts/partials/char/grid.html View File

@@ -1,41 +1,47 @@
1 1
 {{ $size := "200x" }}
2 2
 {{ $retSize := "400x" }}
3
+{{ $gridClass := "grid-200" }}
3 4
 {{ if eq .type "artwork" }}
4 5
     {{ $size = "400x" }}
5 6
     {{ $retSize = "800x" }}
7
+    {{ $gridClass = "grid-400" }}
6 8
 {{ end }}
7 9
 
8
-{{ range .ctx.Pages }}
9
-    {{ $page := . }}
10
-    {{ range .Resources.ByType "image" }}
11
-        {{ $shouldDisplay := false }}
10
+<div class="artwork-grid {{ $gridClass }}">
11
+    {{ range .ctx.Pages }}
12
+        {{ $page := . }}
13
+        {{ range .Resources.ByType "image" }}
14
+            {{ $shouldDisplay := false }}
12 15
 
13
-        {{ if and .Params.icon (eq $.type "icon") }}
14
-            {{ $shouldDisplay = true }}
15
-        {{ end }}
16
+            {{ if and .Params.icon (eq $.type "icon") }}
17
+                {{ $shouldDisplay = true }}
18
+            {{ end }}
16 19
 
17
-        {{ if and (not .Params.icon) (eq $.type "artwork") }}
18
-            {{ $shouldDisplay = true }}
19
-        {{ end }}
20
+            {{ if and (not .Params.icon) (eq $.type "artwork") }}
21
+                {{ $shouldDisplay = true }}
22
+            {{ end }}
20 23
 
21
-        {{ if $shouldDisplay }}
22
-            {{ $reg := .Resize $size }}
23
-            {{ $ret := .Resize $retSize }}
24
+            {{ if $shouldDisplay }}
25
+                {{ $reg := .Resize $size }}
26
+                {{ $ret := .Resize $retSize }}
24 27
 
25
-            {{ $link := .Params.source }}
26
-            {{ if not $link }}
27
-                {{ $link = $page.Params.link }}
28
-            {{ end }}
28
+                {{ $link := .Params.source }}
29
+                {{ if not $link }}
30
+                    {{ $link = $page.Params.link }}
31
+                {{ end }}
29 32
 
30
-            <a
31
-                href="{{ $link }}"
32
-                {{ if .Params.message }} data-message="{{ .Params.message }}" {{ end }}
33
-                {{ if .Params.nsfw }} class="nsfw" {{ end }}
34
-            >
35
-                <img
36
-                    src="{{ $reg.RelPermalink }}"
37
-                    srcset="{{ $reg.RelPermalink }} 1x, {{ $ret.RelPermalink }} 2x">
38
-            </a>
33
+                <div class="grid-item">
34
+                    <a
35
+                        href="{{ $link }}"
36
+                        {{ if .Params.message }} data-message="{{ .Params.message }}" {{ end }}
37
+                        {{ if .Params.nsfw }} class="nsfw" {{ end }}
38
+                    >
39
+                        <img
40
+                            src="{{ $reg.RelPermalink }}"
41
+                            srcset="{{ $reg.RelPermalink }} 1x, {{ $ret.RelPermalink }} 2x">
42
+                    </a>
43
+                </div>
44
+            {{ end }}
39 45
         {{ end }}
40 46
     {{ end }}
41
-{{ end }}
47
+</div>

+ 0
- 110
themes/fox/assets/js/app.js View File

@@ -1,124 +1,14 @@
1
-class Gridify {
2
-    constructor(node, opts = {}) {
3
-        this.node = node;
4
-        this.opts = opts;
5
-        this.node.style.position = 'relative';
6
-        window.addEventListener('resize', this.render.bind(this));
7
-        this.imagesLoaded().then(this.render.bind(this));
8
-    }
9
-    imagesLoaded() {
10
-        return new Promise((resolve, reject) => {
11
-            const images = this.node.querySelectorAll('img');
12
-            let count = images.length;
13
-            if (count === 0)
14
-                resolve();
15
-            let loaded = ev => {
16
-                count--;
17
-                if (count === 0)
18
-                    resolve();
19
-            };
20
-            images.forEach(image => {
21
-                const img = new Image();
22
-                img.addEventListener('load', loaded);
23
-                img.addEventListener('error', loaded);
24
-                img.src = image.src;
25
-            });
26
-        });
27
-    }
28
-    render() {
29
-        const items = Array.from(this.node.querySelectorAll(this.opts['srcNode'])).filter(item => !item.parentNode.classList.contains('nsfw'));
30
-        const transition = (this.opts['transition'] || 'all 0.5s ease') + ', height 0s, width 0s';
31
-        const width = this.node.clientWidth;
32
-        const itemMargin = parseInt(this.opts['margin'], 10) || 0;
33
-        const itemWidth = parseInt(this.opts['width'] || 200, 10);
34
-        const columnCount = Math.max(Math.floor(width / (itemWidth + itemMargin)), 1);
35
-        const left = columnCount === 1 ? itemMargin / 2 : (width % (itemWidth + itemMargin)) / 2;
36
-        let columns = [];
37
-        for (let i = 0; i < columnCount; i++) {
38
-            columns.push(0);
39
-        }
40
-        items.forEach(item => {
41
-            const idx = Gridify.indexOfSmallest(columns);
42
-            const style = item.style;
43
-            style.position = 'absolute';
44
-            style.width = itemWidth + 'px';
45
-            style.margin = (itemMargin / 2) + 'px';
46
-            style.top = (columns[idx] + itemMargin / 2) + 'px';
47
-            style.left = ((itemWidth + itemMargin) * idx + left) + 'px';
48
-            style.transition = transition;
49
-            columns[idx] += item.clientHeight + itemMargin;
50
-        });
51
-        this.node.style.height = Gridify.highestColumn(columns) + 'px';
52
-        if (this.opts['onRender']) {
53
-            this.opts['onRender']();
54
-        }
55
-    }
56
-    static indexOfSmallest(a) {
57
-        let lowest = 0;
58
-        for (let i = 1, length = a.length; i < length; i++) {
59
-            if (a[i] < a[lowest])
60
-                lowest = i;
61
-        }
62
-        return lowest;
63
-    }
64
-    static highestColumn(cols) {
65
-        let highest = 0;
66
-        for (let i = 0, length = cols.length; i < length; i++) {
67
-            if (cols[i] > highest)
68
-                highest = cols[i];
69
-        }
70
-        return highest;
71
-    }
72
-}
73
-;
74
-const gridArt = document.querySelector('#art');
75 1
 const show = document.querySelector('.reveal');
76 2
 const hidden = document.querySelectorAll('.nsfw');
77
-let screenWidth = 0;
78 3
 const urlParams = window.location.hash.slice(1).toLowerCase().split(',');
79
-const needsToScroll = urlParams.includes('art');
80
-let hasScrolled = false;
81
-function updateWidth() {
82
-    const element = document.documentElement;
83
-    screenWidth = Math.max(element.clientWidth, element.offsetWidth, element.scrollWidth);
84
-    window.requestAnimationFrame(() => updateGrid());
85
-}
86
-updateWidth();
87
-function getItemWidth(big) {
88
-    return big ? 400 : 200;
89
-}
90
-function updateGrid() {
91
-    if (screenWidth <= 450) {
92
-        return;
93
-    }
94
-    new Gridify(gridArt, {
95
-        srcNode: 'img',
96
-        margin: '16px',
97
-        width: getItemWidth(true).toString() + 'px',
98
-        onRender: () => {
99
-            if (needsToScroll && !hasScrolled) {
100
-                gridArt.scrollIntoView();
101
-                hasScrolled = true;
102
-            }
103
-        }
104
-    });
105
-    new Gridify(document.querySelector('#icons'), {
106
-        srcNode: 'img',
107
-        margin: '8px',
108
-        width: getItemWidth(false).toString() + 'px'
109
-    });
110
-}
111 4
 function revealNSFW(ev) {
112 5
     if (ev) {
113 6
         ev.preventDefault();
114 7
     }
115 8
     hidden.forEach(item => item.classList.remove('nsfw'));
116
-    updateGrid();
117 9
     show.classList.add('nsfw');
118 10
 }
119 11
 show.addEventListener('click', revealNSFW);
120
-window.addEventListener('load', updateGrid);
121
-window.addEventListener('resize', updateWidth);
122 12
 if (urlParams.includes('nsfw')) {
123 13
     revealNSFW(null);
124 14
 }

+ 14
- 0
themes/fox/static/css/fox.css View File

@@ -292,6 +292,20 @@ section.char-desc li:not(:first-child) {
292 292
     padding-top: 8px;
293 293
 }
294 294
 
295
+.artwork-grid {
296
+    column-gap: 2px;
297
+}
298
+
299
+.artwork-grid.grid-200 {
300
+    columns: 12 200px;
301
+    grid-auto-columns: 200px;
302
+}
303
+
304
+.artwork-grid.grid-400 {
305
+    columns: 6 400px;
306
+    grid-auto-columns: 400px;
307
+}
308
+
295 309
 .peppershrike {
296 310
     width: 100%;
297 311
     background-color: #eadef6;

Loading…
Cancel
Save