Compare commits
129 Commits
master
...
grid-n-vie
| Author | SHA1 | Date | |
|---|---|---|---|
| 2470778d6f | |||
| f77016be92 | |||
| ac7179384c | |||
| 9dc0b8222c | |||
| 1978ceb854 | |||
| ad30c7e57f | |||
| a114775f58 | |||
| dd1565d1b8 | |||
| 1ad674e466 | |||
| 58f44fc983 | |||
| 4905c0bbbb | |||
| 6a4213d13c | |||
| 9b5f4daae8 | |||
| 517559c5af | |||
| 769b20600f | |||
| c63494d736 | |||
| 9034641745 | |||
| b4c6dc6107 | |||
| fbc7af8c05 | |||
| 3e8ce38d1f | |||
| 4e7018efd6 | |||
| 09811a5732 | |||
| 7845185212 | |||
| a0dab54f88 | |||
| e497337095 | |||
| 1bf66706c0 | |||
| 1489ba0c0a | |||
| f7ea76ec6e | |||
| e1881b85c6 | |||
| 751df786e5 | |||
| acf4d90790 | |||
| 22ced4ff71 | |||
| dfb452b39e | |||
| cad5e6ea58 | |||
| a5f42a2ff1 | |||
| cae5bed162 | |||
| ebfb04845a | |||
| 1f3adbbfb1 | |||
| a6d04eff3b | |||
| 55c2dc83ca | |||
| 2c243b4132 | |||
| 5de338af1b | |||
| 53eecfc17f | |||
| c4783101a0 | |||
| 8394c8e05f | |||
| 4f5717178b | |||
| d3c7b511eb | |||
| f3341d0d0e | |||
| 966e82f2fe | |||
| 40b67cc967 | |||
| 5db49a0585 | |||
| 18de12dc7e | |||
| 91dae0a326 | |||
| 363c08c41b | |||
| 90727814da | |||
| 5e4f69c88a | |||
| ffe88f99e8 | |||
| 45130ab8d2 | |||
| 383134a917 | |||
| 40a0934e85 | |||
| 693a75b8bc | |||
| d7fc670604 | |||
| 21f969a431 | |||
| 7d1c76cb71 | |||
| fcf1cb4d2d | |||
| d8d6a74273 | |||
| 804bceee46 | |||
| 5ffdaeb100 | |||
| 02ce4039ad | |||
| fd460e0920 | |||
| ef53686e0a | |||
| e061166600 | |||
| 9d91940be0 | |||
| 1061323d8b | |||
| 5c9116b9d1 | |||
| 0640c7da14 | |||
| 08a71c6244 | |||
| 3598df046c | |||
| 81f49f7e45 | |||
| ce6e5048fd | |||
| 8dfc1426a9 | |||
| 5a52210b18 | |||
| 087254328c | |||
| 41f89f07f0 | |||
| 375d80d719 | |||
| 277a78dc4f | |||
| ff90a6deee | |||
| 9b518a3b06 | |||
| 7436eb2ada | |||
| a4712a46ec | |||
| 8546deafbf | |||
| 18c32a3781 | |||
| 13cc609b5f | |||
| ac95265b64 | |||
| ad2d9455e7 | |||
| 1d8de8b1ba | |||
| ef81176ebd | |||
| cb2be74ed3 | |||
| ffb3fcdf20 | |||
| fd3d2d2e5e | |||
| cafb50054c | |||
| 0ff97ccb6f | |||
| fb2e88cfa0 | |||
| 3a38523432 | |||
| 02c468818e | |||
| e08abf0585 | |||
| d8655fcab4 | |||
| 04d8f9ea8d | |||
| 582f4380cc | |||
| e91646f771 | |||
| d19179851d | |||
| 07f3cb1e08 | |||
| 9470a9838b | |||
| e0de8a9a13 | |||
| 673912b219 | |||
| 3c7ed59b26 | |||
| f869066082 | |||
| b8a0146d63 | |||
| b156ba8e7b | |||
| 6a00c1e4df | |||
| 93b8f63057 | |||
| 209202945a | |||
| 03a79d3f22 | |||
| 802fe8193b | |||
| 849460de91 | |||
| 12bae73114 | |||
| 95a1ef8d66 | |||
| 929611d1ce | |||
| 1f5fd5cd33 |
7
.editorconfig
Normal file
7
.editorconfig
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
root = true
|
||||||
|
|
||||||
|
[**]
|
||||||
|
indent_style = tab
|
||||||
|
tab_width = 4
|
||||||
|
charset = utf-8
|
||||||
|
end_of_line = lf
|
||||||
15
.gitignore
vendored
Normal file
15
.gitignore
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
.gitignore
|
||||||
|
*.pem
|
||||||
|
*.sw[po]
|
||||||
|
*.py[co]
|
||||||
|
build
|
||||||
|
Session.vim
|
||||||
|
*.bak
|
||||||
|
*.dll
|
||||||
|
*.exe
|
||||||
|
*.pak
|
||||||
|
*.dat
|
||||||
|
*.zip
|
||||||
|
node_modules
|
||||||
|
targets
|
||||||
|
*.egg-info
|
||||||
88
README.md
Normal file
88
README.md
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
# Gallery prototype
|
||||||
|
|
||||||
|
## ToDo
|
||||||
|
|
||||||
|
- BUG?: for some reason toggling fullscreen on a mobile device changes
|
||||||
|
font size...
|
||||||
|
- toolbar: drag: broken for non-first relative toolbars...
|
||||||
|
- <b>Save current gallery (zip/json?)</b>
|
||||||
|
- Save current editor state (zip/json?)
|
||||||
|
- ~~Views: Gallery / Details / Lightbox~~
|
||||||
|
- Details: populate fields
|
||||||
|
- Details: edit
|
||||||
|
- toolbar: prevent form overlaping mutiple toolbars
|
||||||
|
- ~~toolbar: collapsed view icon...~~
|
||||||
|
- ~~toolbar: floating over gallery~~
|
||||||
|
- ~~info (current)~~ -- should this be floating over image??
|
||||||
|
- ~~select / deselect (current / all)~~
|
||||||
|
- ~~delete / clear deleted (current / all)~~
|
||||||
|
- ~~crop~~
|
||||||
|
- load
|
||||||
|
- ~~styling and icons...~~
|
||||||
|
- ~~draggable?~~
|
||||||
|
- ~~handle wrapping better (collapsed / expandend)~~
|
||||||
|
might still need to resize to content on multiline...
|
||||||
|
- Lightbox: hide cursor on timeout...
|
||||||
|
- <s>Gallery/Lightbox/Details: handle dragging image out of browser</s> -- not possible in brpwser
|
||||||
|
- Lightbox: hover indicators:
|
||||||
|
- start/end (a-la ImageGrid.Viewer??)
|
||||||
|
- next/prev
|
||||||
|
- ~~count~~
|
||||||
|
- ~~selection~~
|
||||||
|
- ~~Lightbox: unify buttons with toolbar...~~
|
||||||
|
- ~~Gallery: Adaptable image justification in grid~~
|
||||||
|
- ~~Gallery: Spacial navigation (up/down/left/right)~~
|
||||||
|
- **auto focus image iff the gallery is visible**
|
||||||
|
- handle focus / tabindex (???)
|
||||||
|
- ~~option: .loop_images~~
|
||||||
|
- ~~Up/Down: might be a good idea to select an image based on
|
||||||
|
longest border instead of closest center (current)...~~
|
||||||
|
- Gallery: PageUp/PageDown, home/end + allow page navigation
|
||||||
|
- **Gallery: focus visible...**
|
||||||
|
- ~~Gallery/Lightbox: Selection of images (space / ctrl-a / ctrl-d / ctrl-i)~~
|
||||||
|
- ~~Lightbox: show selection marker~~
|
||||||
|
- **Gallery: constructor...**
|
||||||
|
```
|
||||||
|
Gallery([options])
|
||||||
|
Gallery(urls[, options])
|
||||||
|
Gallery(dom[, options])
|
||||||
|
Gallery(dom, urls[, options])
|
||||||
|
```
|
||||||
|
- **Gallery: view crop**
|
||||||
|
- ~~crop stack (a-la ImageGrid.Viewer)~~
|
||||||
|
- ~~GUI: basic buttons~~
|
||||||
|
- ~~named crop~~
|
||||||
|
- GUI: level indicators (a-la ImageGrid.Viewer)
|
||||||
|
- GUI: named crop list
|
||||||
|
- ~~Gallery: drag-n-drop~~
|
||||||
|
- ~~drop files/images~~
|
||||||
|
- ~~drag to sort~~
|
||||||
|
- **drag marked**
|
||||||
|
- touch support
|
||||||
|
- ~~Gallery: remove image~~
|
||||||
|
- ~~basic delete~~
|
||||||
|
- ~~delete marked~~
|
||||||
|
- ~~mark images for deletion + delete marked~~
|
||||||
|
- ~~Gallery: serialize / deserialize~~
|
||||||
|
- ~~Lightbox: navigation (keyboard / mouse)~~
|
||||||
|
- ~~Lightbox: fullscreen mode~~
|
||||||
|
- ~~Would be nice to retain the scroll position on refresh...~~
|
||||||
|
- Gallery: web component (???)
|
||||||
|
- ...
|
||||||
|
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
Before testing this needs icon fonts to be available:
|
||||||
|
```
|
||||||
|
$ npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
XXX
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- vim:set ts=4 sw=4 : -->
|
||||||
859
css/grid-n-view.css
Normal file
859
css/grid-n-view.css
Normal file
@ -0,0 +1,859 @@
|
|||||||
|
/**********************************************************************
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
**********************************************************************/
|
||||||
|
|
||||||
|
@import '../node_modules/material-symbols/outlined.css';
|
||||||
|
|
||||||
|
|
||||||
|
/********************************************************* Config ****/
|
||||||
|
|
||||||
|
:root {
|
||||||
|
/* dimensions */
|
||||||
|
--gallery-image-base-height: 18rem;
|
||||||
|
--gallery-image-base-width: auto;
|
||||||
|
--gallery-image-spacing: 0rem;
|
||||||
|
--gallery-current-image-border: 0.7rem;
|
||||||
|
--gallery-padding: 3rem;
|
||||||
|
--gallery-scrollbar-width: 0.5rem;
|
||||||
|
|
||||||
|
--toolbar-button-size: 2rem;
|
||||||
|
|
||||||
|
--lightbox-frame: 5vmin;
|
||||||
|
--lightbox-image-margin-top: 0.75;
|
||||||
|
--lightbox-button-size: 2rem;
|
||||||
|
|
||||||
|
/* theme */
|
||||||
|
--gallery-text-color: black;
|
||||||
|
--gallery-secondary-color: silver;
|
||||||
|
--gallery-shade-color: whitesmoke;
|
||||||
|
--gallery-background-color: white;
|
||||||
|
--gallery-accent-color: white;
|
||||||
|
--gallery-secondary-accent-color: white;
|
||||||
|
|
||||||
|
--lightbox-text-color: black;
|
||||||
|
--lightbox-background-color: white;
|
||||||
|
/*--lightbox-background-color: rgba(0,0,0,0.8);*/
|
||||||
|
|
||||||
|
--color-transition: 1s;
|
||||||
|
|
||||||
|
|
||||||
|
/* base font size... */
|
||||||
|
/* XXX can we use this as the basis for sizing for different devices??? */
|
||||||
|
font-size: 5mm;
|
||||||
|
}
|
||||||
|
/* calculated values... */
|
||||||
|
/* NOTE: these need to be separeated from the :root values to recalculate... */
|
||||||
|
body {
|
||||||
|
--gallery-image-margin: calc(var(--gallery-image-spacing) / 2);
|
||||||
|
--gallery-padding-horizontal: var(--gallery-padding);
|
||||||
|
--gallery-padding-vertical: var(--gallery-current-image-border);
|
||||||
|
--gallery-padding-top: var(--gallery-padding-vertical);
|
||||||
|
--gallery-padding-bottom: var(--gallery-padding-vertical);
|
||||||
|
--gallery-padding-left: var(--gallery-padding-horizontal);
|
||||||
|
--gallery-padding-right: var(--gallery-padding-horizontal);
|
||||||
|
--gallery-image-scroll-margin: calc(2 * var(--gallery-current-image-border));
|
||||||
|
--gallery-empty-height: var(--gallery-image-base-height);
|
||||||
|
--scrollbar-color: var(--gallery-secondary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.gallery-dark {
|
||||||
|
--gallery-text-color: silver;
|
||||||
|
--gallery-secondary-color: gray;
|
||||||
|
--gallery-shade-color: rgb(50,50,50);
|
||||||
|
--gallery-background-color: rgb(10,10,10);
|
||||||
|
}
|
||||||
|
|
||||||
|
.lightbox-dark {
|
||||||
|
--lightbox-text-color: silver;
|
||||||
|
--lightbox-background-color: rgb(10,10,10);
|
||||||
|
}
|
||||||
|
/* XXX to make the lightbox scrolbar work correctly we need to set the
|
||||||
|
* body colors -- :has(..) does not yet work on FF .... */
|
||||||
|
.lightbox-dark.lightboxed,
|
||||||
|
.lightbox-dark:has(.lightboxed) {
|
||||||
|
--gallery-background-color: var(--lightbox-background-color);
|
||||||
|
--gallery-text-color: var(--lightbox-text-color);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************** Scrolling ****/
|
||||||
|
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: var(--gallery-scrollbar-width);
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
background-color: transparent;
|
||||||
|
border-radius: 100px;
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
background-color: var(--scrollbar-color);
|
||||||
|
border-radius: 100px;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
overflow-y: scroll;
|
||||||
|
/* XXX these for some reason do not work in FF... */
|
||||||
|
scrollbar-width: thin;
|
||||||
|
scrollbar-color: transparent var(--gallery-secondary-color);
|
||||||
|
|
||||||
|
color: var(--gallery-text-color);
|
||||||
|
background: var(--gallery-background-color);
|
||||||
|
|
||||||
|
transition:
|
||||||
|
text-shadow var(--color-transition) ease,
|
||||||
|
background var(--color-transition) ease,
|
||||||
|
color var(--color-transition) ease;
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
color: var(--gallery-text-color);
|
||||||
|
background: var(--gallery-background-color);
|
||||||
|
border: solid 1px var(--gallery-secondary-color);
|
||||||
|
|
||||||
|
transition:
|
||||||
|
text-shadow var(--color-transition) ease,
|
||||||
|
background var(--color-transition) ease,
|
||||||
|
color var(--color-transition) ease;
|
||||||
|
}
|
||||||
|
button:hover {
|
||||||
|
background: var(--gallery-shade-color);
|
||||||
|
border: solid 1px var(--gallery-text-color);
|
||||||
|
}
|
||||||
|
button:active {
|
||||||
|
background: var(--gallery-secondary-color);
|
||||||
|
border: solid 1px var(--gallery-text-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************** Gallery ****/
|
||||||
|
|
||||||
|
/* XXX need to account for scrollbar popping in and out */
|
||||||
|
.gallery {
|
||||||
|
--base-layer: 10;
|
||||||
|
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
padding-top: var(--gallery-padding-top);
|
||||||
|
padding-bottom: var(--gallery-padding-bottom);
|
||||||
|
padding-left: calc(
|
||||||
|
var(--gallery-scrollbar-width)
|
||||||
|
+ var(--gallery-padding-left) );
|
||||||
|
padding-right: var(--gallery-padding-right);
|
||||||
|
|
||||||
|
color: var(--gallery-text-color);
|
||||||
|
background: var(--gallery-background-color);
|
||||||
|
font-family: sans-serif;
|
||||||
|
|
||||||
|
overflow-x: clip;
|
||||||
|
|
||||||
|
transition:
|
||||||
|
text-shadow var(--color-transition) ease,
|
||||||
|
background var(--color-transition) ease,
|
||||||
|
color var(--color-transition) ease;
|
||||||
|
}
|
||||||
|
.gallery .images {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-content: flex-start;
|
||||||
|
flex-flow: row wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* empty... */
|
||||||
|
.gallery .images:empty {
|
||||||
|
height: var(--gallery-empty-height);
|
||||||
|
border: dashed 1px var(--gallery-secondary-color);
|
||||||
|
}
|
||||||
|
.gallery .images:empty:after,
|
||||||
|
.gallery .images:empty:before {
|
||||||
|
--font-size: 1.5rem;
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
line-height: var(--gallery-empty-height);
|
||||||
|
text-align: center;
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
.gallery .images:empty:before {
|
||||||
|
content: "Empty";
|
||||||
|
font-size: var(--font-size);
|
||||||
|
}
|
||||||
|
.gallery .images:empty:after {
|
||||||
|
content: "(drag new images here)";
|
||||||
|
font-size: small;
|
||||||
|
margin-top: calc(var(--font-size) / 1.3);
|
||||||
|
opacity: 0.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* empty otter... */
|
||||||
|
.gallery.otter .images:empty:before,
|
||||||
|
.gallery.otter .images:empty:after {
|
||||||
|
--font-size: 2em;
|
||||||
|
}
|
||||||
|
.gallery.otter .images:empty:before {
|
||||||
|
content: "🦦";
|
||||||
|
filter: saturate(0) contrast(200%);
|
||||||
|
}
|
||||||
|
.gallery.otter .images:empty:after {
|
||||||
|
margin-top: calc(var(--font-size) / 1.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* image... */
|
||||||
|
.gallery .images img {
|
||||||
|
height: var(--gallery-image-base-height);
|
||||||
|
width: var(--gallery-image-base-width);
|
||||||
|
|
||||||
|
object-fit: contain;
|
||||||
|
|
||||||
|
border: solid var(--gallery-image-margin) transparent;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
scroll-margin: var(--gallery-image-scroll-margin);
|
||||||
|
|
||||||
|
image-rendering: crisp-edges;
|
||||||
|
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.gallery:not(.lightboxed) .images img:not(.current):hover {
|
||||||
|
z-index: calc(var(--base-layer) + 1);
|
||||||
|
outline: solid calc(var(--gallery-current-image-border) / 5) var(--gallery-accent-color);
|
||||||
|
box-shadow: 0.2em 0.2em 1em 0em rgba(0,0,0,0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* current image... */
|
||||||
|
.gallery .images img.current {
|
||||||
|
z-index: 10;
|
||||||
|
outline: solid var(--gallery-current-image-border) var(--gallery-accent-color);
|
||||||
|
box-shadow: 0.4em 0.4em 2em 0em rgba(0,0,0,0.8);
|
||||||
|
}
|
||||||
|
.gallery:not(.lightboxed) .images img.current:hover {
|
||||||
|
z-index: calc(var(--base-layer) + 1);
|
||||||
|
outline: solid var(--gallery-current-image-border) var(--gallery-secondary-accent-color);
|
||||||
|
box-shadow: 0.6em 0.6em 3em 0em rgba(0,0,0,0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* dragged image... */
|
||||||
|
.gallery .images img.dragged {
|
||||||
|
}
|
||||||
|
.gallery .images:has(.dragged) img:not(.dragged) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/* image dragged over... */
|
||||||
|
.gallery.dragged-over .images img {
|
||||||
|
filter: saturate(0) brightness(0.4);
|
||||||
|
}
|
||||||
|
.gallery .images img.dragged-over {
|
||||||
|
z-index: calc(var(--base-layer) + 1);
|
||||||
|
border-left: none;
|
||||||
|
margin-left: var(--gallery-image-margin);
|
||||||
|
box-shadow:
|
||||||
|
calc(var(--gallery-current-image-border) * -1) 0px 0px 0px rgba(0,0,0,0.8),
|
||||||
|
/* XXX this does not work... */
|
||||||
|
inset var(--gallery-current-image-border) 0px 0px 0px rgba(0,0,0,0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* image marked for removal... */
|
||||||
|
.gallery .images img.to-remove {
|
||||||
|
opacity: 0.3;
|
||||||
|
filter: saturate(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************** Image markers ***/
|
||||||
|
|
||||||
|
.gallery .images img+.mark {
|
||||||
|
z-index: var(--base-layer);
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.gallery .images img:hover+.mark {
|
||||||
|
z-index: calc(var(--base-layer) + 1);
|
||||||
|
}
|
||||||
|
.gallery.lightboxed .images img:not(.current)+.mark {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.gallery.lightboxed .images img.current+.mark {
|
||||||
|
z-index: calc(var(--base-layer) + 1);
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* marker: marked */
|
||||||
|
.gallery .images img+.mark.marked:after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
display: block;
|
||||||
|
width: 1em;
|
||||||
|
height: 1em;
|
||||||
|
right: 0.5em;
|
||||||
|
bottom: 0.5em;
|
||||||
|
border-radius: 50%;
|
||||||
|
|
||||||
|
background: blue;
|
||||||
|
|
||||||
|
box-shadow: 0em 0em 0em 0.05em rgba(255,255,255,1);
|
||||||
|
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************** Toolbar ****/
|
||||||
|
|
||||||
|
/* NOTE: this is used as a reference element to place the toolbars
|
||||||
|
* relative to... */
|
||||||
|
.gallery .toolbar-anchor {
|
||||||
|
position: sticky;
|
||||||
|
|
||||||
|
top: 0;
|
||||||
|
height: 0;
|
||||||
|
margin: 0 calc(var(--gallery-padding-horizontal) * -1);
|
||||||
|
overflow: visible;
|
||||||
|
|
||||||
|
z-index: calc(var(--base-layer) + 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* XXX make the toolbar contextual... */
|
||||||
|
.gallery .toolbar {
|
||||||
|
--move-x: 0;
|
||||||
|
--move-y: 0;
|
||||||
|
|
||||||
|
--padding: 0.5rem;
|
||||||
|
--height: calc((var(--toolbar-button-size) + var(--padding) * 2));
|
||||||
|
|
||||||
|
/*position: absolute;*/
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
|
||||||
|
left: var(--move-x);
|
||||||
|
top: var(--move-y);
|
||||||
|
|
||||||
|
width: fit-content;
|
||||||
|
min-height: var(--toolbar-button-size);
|
||||||
|
|
||||||
|
margin: 0.1em 0px;
|
||||||
|
|
||||||
|
padding: var(--padding);
|
||||||
|
padding-right: var(--height);
|
||||||
|
padding-left: var(--height);
|
||||||
|
|
||||||
|
/*scroll-margin: var(--gallery-image-scroll-margin);*/
|
||||||
|
|
||||||
|
translate: 0 0;
|
||||||
|
|
||||||
|
border: solid 1px var(--gallery-secondary-color);
|
||||||
|
border-radius: calc(var(--height) / 8);
|
||||||
|
background: var(--gallery-background-color);
|
||||||
|
|
||||||
|
box-shadow: 0.2em 0.2em 0.5em -0.3em rgba(0,0,0,0.8);
|
||||||
|
|
||||||
|
transition:
|
||||||
|
left 0.2s,
|
||||||
|
padding-right 0.2s,
|
||||||
|
opacity 0.2s,
|
||||||
|
translate 0.2s,
|
||||||
|
text-shadow var(--color-transition) ease,
|
||||||
|
background var(--color-transition) ease,
|
||||||
|
color var(--color-transition) ease;
|
||||||
|
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
/* XXX need to hide parts of the toolbar and make it transparent... */
|
||||||
|
.gallery.lightboxed .toolbar,
|
||||||
|
.gallery.detailed .toolbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* moving toolbar... */
|
||||||
|
.gallery .toolbar.moving {
|
||||||
|
transition: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fixed toolbar... */
|
||||||
|
.gallery .toolbar.fixed {
|
||||||
|
padding-left: var(--padding);
|
||||||
|
}
|
||||||
|
.gallery .toolbar.fixed .drag-handle {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* sticky toolbar indicator... */
|
||||||
|
.gallery .toolbar.sticky:after {
|
||||||
|
content: "lock";
|
||||||
|
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
padding: calc(var(--toolbar-button-size) / 10);
|
||||||
|
|
||||||
|
font-family: "Material Symbols Outlined";
|
||||||
|
font-size: small;
|
||||||
|
font-weight: bold;
|
||||||
|
|
||||||
|
opacity: 0.3;
|
||||||
|
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* collapsed toolbar (default)... */
|
||||||
|
/* XXX shoud the toolbar be vertical??? */
|
||||||
|
.gallery .toolbar:not(.shown) {
|
||||||
|
translate: calc(-100% + var(--toolbar-button-size) + var(--padding) / 2) 0;
|
||||||
|
|
||||||
|
left: 0;
|
||||||
|
|
||||||
|
/*padding-right: calc(var(--padding) / 5);*/
|
||||||
|
padding-right: var(--height);
|
||||||
|
}
|
||||||
|
.gallery .toolbar:not(.shown):not(:hover) {
|
||||||
|
box-shadow: none;
|
||||||
|
|
||||||
|
z-index: var(--base-layer);
|
||||||
|
animation: 0.5s steps(1) tuck-to-backgroud;
|
||||||
|
}
|
||||||
|
@keyframes tuck-to-backgroud {
|
||||||
|
0% {
|
||||||
|
z-index: calc(var(--base-layer) + 2);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
z-index: var(--base-layer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* groups... */
|
||||||
|
.gallery .toolbar>* {
|
||||||
|
display: inline-block;
|
||||||
|
height: calc(100% - var(--padding) * 2);
|
||||||
|
}
|
||||||
|
.gallery .toolbar>*:not(:last-child):after {
|
||||||
|
content: "";
|
||||||
|
display: inline-block;
|
||||||
|
position: absolute;
|
||||||
|
top: var(--padding);
|
||||||
|
bottom: var(--padding);
|
||||||
|
margin-left: calc(var(--padding) / 4);
|
||||||
|
border-right: solid 1px var(--gallery-secondary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* state list (group)... */
|
||||||
|
.gallery .toolbar .states:empty {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.gallery .toolbar .states:empty:before {
|
||||||
|
content: "Empty...";
|
||||||
|
font-family: sans-serif;
|
||||||
|
line-height: var(--toolbar-button-size);
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: bottom;
|
||||||
|
padding: 0 0.5em;
|
||||||
|
opacity: 0.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* buttons... */
|
||||||
|
.gallery .button,
|
||||||
|
.gallery .toolbar button {
|
||||||
|
min-width: var(--toolbar-button-size);
|
||||||
|
|
||||||
|
border: solid 1px transparent;
|
||||||
|
background: transparent;
|
||||||
|
|
||||||
|
font-family: "Material Symbols Outlined";
|
||||||
|
font-size: var(--toolbar-button-size);
|
||||||
|
line-height: var(--toolbar-button-size);
|
||||||
|
font-weight: 300;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
text-rendering: optimizeLegibility;
|
||||||
|
font-feature-settings: "liga";
|
||||||
|
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
color: var(--gallery-text-color);
|
||||||
|
|
||||||
|
transition:
|
||||||
|
text-shadow var(--color-transition) ease,
|
||||||
|
background var(--color-transition) ease,
|
||||||
|
color var(--color-transition) ease;
|
||||||
|
}
|
||||||
|
.gallery .toolbar button.collapse:after,
|
||||||
|
.gallery .toolbar button sec {
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
left: 0;
|
||||||
|
bottom: calc(var(--toolbar-button-size) / -6);
|
||||||
|
margin-left: calc(var(--toolbar-button-size) / -1.5625);
|
||||||
|
margin-right: -0.15em;
|
||||||
|
|
||||||
|
font-size: calc(var(--toolbar-button-size) / 1.15);
|
||||||
|
|
||||||
|
/* XXX HACK: might be better to use SVG for this... */
|
||||||
|
text-shadow:
|
||||||
|
0em 0.05em 0px var(--gallery-background-color),
|
||||||
|
0.05em 0em 0px var(--gallery-background-color),
|
||||||
|
-0.05em 0em 0px var(--gallery-background-color),
|
||||||
|
0em -0.05em 0px var(--gallery-background-color),
|
||||||
|
0.05em 0.05em 0px var(--gallery-background-color),
|
||||||
|
-0.05em -0.05em 0px var(--gallery-background-color),
|
||||||
|
-0.05em 0.05em 0px var(--gallery-background-color),
|
||||||
|
0.05em -0.05em 0px var(--gallery-background-color);
|
||||||
|
|
||||||
|
transition:
|
||||||
|
text-shadow var(--color-transition) ease,
|
||||||
|
background var(--color-transition) ease,
|
||||||
|
color var(--color-transition) ease;
|
||||||
|
}
|
||||||
|
/* collapse indicator... */
|
||||||
|
.gallery .toolbar button.collapse:after {
|
||||||
|
content: "keyboard_double_arrow_left";
|
||||||
|
}
|
||||||
|
.gallery .toolbar button.collapse:after {
|
||||||
|
transition:
|
||||||
|
rotate 0.2s,
|
||||||
|
text-shadow var(--color-transition) ease,
|
||||||
|
background var(--color-transition) ease,
|
||||||
|
color var(--color-transition) ease;
|
||||||
|
}
|
||||||
|
.gallery .toolbar:not(.shown) button.collapse:after {
|
||||||
|
rotate: 180deg;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gallery .toolbar button:hover {
|
||||||
|
border-radius: calc(var(--toolbar-button-size) / 5);
|
||||||
|
border-color: var(--gallery-secondary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.gallery .toolbar .states button {
|
||||||
|
font-family: sans-serif;
|
||||||
|
line-height: var(--toolbar-button-size);
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* button: collapse... */
|
||||||
|
.gallery .toolbar button.collapse {
|
||||||
|
position: absolute;
|
||||||
|
height: 100%;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
|
||||||
|
opacity: 0.4;
|
||||||
|
|
||||||
|
}
|
||||||
|
.gallery .toolbar button.collapse:hover {
|
||||||
|
opacity: 1;
|
||||||
|
border-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gallery .toolbar button.drag-handle {
|
||||||
|
position: absolute;
|
||||||
|
height: calc(100% - var(--padding) * 2);
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
margin-top: var(--padding);
|
||||||
|
margin-bottom: var(--padding);
|
||||||
|
|
||||||
|
font-family: "Material Symbols Outlined";
|
||||||
|
font-size: var(--toolbar-button-size);
|
||||||
|
line-height: var(--toolbar-button-size);
|
||||||
|
font-weight: 300;
|
||||||
|
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
color: var(--gallery-secondary-color);
|
||||||
|
}
|
||||||
|
.gallery .toolbar .drag-handle:hover {
|
||||||
|
border-top-color: transparent;
|
||||||
|
border-left-color: transparent;
|
||||||
|
border-bottom-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************* Overlays ****/
|
||||||
|
|
||||||
|
.gallery.lightboxed,
|
||||||
|
.gallery.detailed {
|
||||||
|
--base-layer: 100;
|
||||||
|
}
|
||||||
|
.gallery.lightboxed .lightbox,
|
||||||
|
.gallery.detailed .details {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gallery .lightbox,
|
||||||
|
.gallery .details {
|
||||||
|
display: none;
|
||||||
|
position: fixed;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
top: 0px;
|
||||||
|
left: 0px;
|
||||||
|
z-index: var(--base-layer);
|
||||||
|
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
color: var(--gallery-text-color);
|
||||||
|
background: var(--gallery-background-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*------------------------------------------------------ Lightbox ---*/
|
||||||
|
|
||||||
|
.gallery .lightbox {
|
||||||
|
color: var(--lightbox-text-color);
|
||||||
|
background: var(--lightbox-background-color);
|
||||||
|
}
|
||||||
|
.gallery .lightbox.show-caption:before {
|
||||||
|
content: attr(caption);
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0.5em;
|
||||||
|
left: 0.5em;
|
||||||
|
}
|
||||||
|
.gallery .lightbox.clickable {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
/* XXX add metadata display... */
|
||||||
|
.gallery .lightbox img {
|
||||||
|
object-fit: contain;
|
||||||
|
width: calc(
|
||||||
|
100vw
|
||||||
|
- var(--lightbox-frame) * 2);
|
||||||
|
height: calc(
|
||||||
|
100vh
|
||||||
|
- var(--lightbox-frame) * 2);
|
||||||
|
margin-top: calc(
|
||||||
|
var(--lightbox-frame)
|
||||||
|
* var(--lightbox-image-margin-top));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*------------------------------------------------------- Details ---*/
|
||||||
|
|
||||||
|
.gallery .details img {
|
||||||
|
width: 20em;
|
||||||
|
height: 20em;
|
||||||
|
padding: 0.5em;
|
||||||
|
object-fit: contain;
|
||||||
|
border: solid 1px black;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************* Controls ****/
|
||||||
|
/* XXX these are only used in the lightbox... */
|
||||||
|
|
||||||
|
.gallery .buttons {
|
||||||
|
display: flex;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
.gallery .button {
|
||||||
|
disbplay: inline-block;
|
||||||
|
cursor: pointer;
|
||||||
|
width: var(--lightbox-button-size);
|
||||||
|
height: var(--lightbox-button-size);
|
||||||
|
margin: 0.2em;
|
||||||
|
|
||||||
|
font-size: var(--lightbox-button-size);
|
||||||
|
line-height: var(--lightbox-button-size);
|
||||||
|
|
||||||
|
color: var(--lightbox-text-color);
|
||||||
|
filter: saturate(0);
|
||||||
|
|
||||||
|
opacity: 0.1;
|
||||||
|
}
|
||||||
|
.gallery .button:hover {
|
||||||
|
opacity: 1;
|
||||||
|
filter: saturate(1);
|
||||||
|
color: var(--lightbox-text-color);
|
||||||
|
transition: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* specific controls */
|
||||||
|
.gallery .button.close:after {
|
||||||
|
content: "close";
|
||||||
|
}
|
||||||
|
.gallery .button.fullscreen:after {
|
||||||
|
content: "fullscreen";
|
||||||
|
}
|
||||||
|
.gallery .button.info:after {
|
||||||
|
content: "info";
|
||||||
|
}
|
||||||
|
.gallery .button.prev:after {
|
||||||
|
content: "navigate_before";
|
||||||
|
}
|
||||||
|
.gallery .button.next:after {
|
||||||
|
content: "navigate_next";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/********************************************************* Splash ****/
|
||||||
|
|
||||||
|
.gallery .loading {
|
||||||
|
position: absolute;
|
||||||
|
display: block;
|
||||||
|
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height:100%;
|
||||||
|
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
z-index: calc(var(--base-layer) * 2);
|
||||||
|
|
||||||
|
background: var(--gallery-background-color);
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
.gallery.ready .loading {
|
||||||
|
animation: fadeOutAnimation ease 2s;
|
||||||
|
animation-iteration-count: 1;
|
||||||
|
animation-fill-mode: forwards;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
@keyframes fadeOutAnimation {
|
||||||
|
0% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.gallery.ready .loading * {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* loading bar animation... */
|
||||||
|
.gallery .loading>div {
|
||||||
|
--bar-size: 0.2rem;
|
||||||
|
|
||||||
|
position: sticky;
|
||||||
|
top: var(--bar-size);
|
||||||
|
height: var(--bar-size);
|
||||||
|
|
||||||
|
background: rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
.gallery .loading>div:before,
|
||||||
|
.gallery .loading>div:after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: var(--bar-size);
|
||||||
|
background: var(--gallery-text-color);
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
.gallery .loading>div:after {
|
||||||
|
animation: loadingBarAnimation ease infinite alternate 2s;
|
||||||
|
}
|
||||||
|
.gallery .loading>div:before {
|
||||||
|
width: 50%;
|
||||||
|
animation: loadingBarAnimation ease infinite alternate 1.5s;
|
||||||
|
}
|
||||||
|
@keyframes loadingBarAnimation {
|
||||||
|
0% {
|
||||||
|
translate: -100%;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
translate: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* loading images animation... */
|
||||||
|
.gallery:not(.ready) .images .mark {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.gallery:not(.ready) .images img {
|
||||||
|
--duration: 3s;
|
||||||
|
|
||||||
|
--delay: 0s;
|
||||||
|
--extend: 1;
|
||||||
|
|
||||||
|
box-shadow: none;
|
||||||
|
|
||||||
|
animation:
|
||||||
|
loadingImagesAnimation
|
||||||
|
ease
|
||||||
|
infinite
|
||||||
|
alternate
|
||||||
|
calc(var(--duration) * var(--extend))
|
||||||
|
var(--delay);
|
||||||
|
}
|
||||||
|
/* variations... */
|
||||||
|
.gallery .images img:nth-child(2n) {
|
||||||
|
--delay: 0.2s;
|
||||||
|
--extend: 0.9;
|
||||||
|
}
|
||||||
|
.gallery .images img:nth-child(3n) {
|
||||||
|
--delay: 0.5s;
|
||||||
|
--extend: 1.3;
|
||||||
|
}
|
||||||
|
.gallery .images img:nth-child(5n) {
|
||||||
|
--delay: 0.4s;
|
||||||
|
--extend: 1.6;
|
||||||
|
}
|
||||||
|
.gallery .images img:nth-child(7n) {
|
||||||
|
--delay: 0.1s;
|
||||||
|
--extend: 0.6;
|
||||||
|
}
|
||||||
|
@keyframes loadingImagesAnimation {
|
||||||
|
0% {
|
||||||
|
filter: contrast(0);
|
||||||
|
opacity: 0.2;
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
filter: contrast(0);
|
||||||
|
opacity: 0.3;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
filter: contrast(0);
|
||||||
|
opacity: 0.1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/********************************************************** Utils ****/
|
||||||
|
|
||||||
|
.gallery:not(.lightboxed):not(.detailed) .hide-in-gallery,
|
||||||
|
.gallery.lightboxed .hide-in-lightbox,
|
||||||
|
.gallery.detailed .hide-in-details {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
icon {
|
||||||
|
font-family: "Material Symbols Outlined";
|
||||||
|
font-weight: 300;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
text-rendering: optimizeLegibility;
|
||||||
|
font-feature-settings: "liga";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* vim:set ts=4 sw=4 : */
|
||||||
214
grid-n-view.html
Normal file
214
grid-n-view.html
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
|
||||||
|
<title>Grid n' View</title>
|
||||||
|
|
||||||
|
<link href="css/grid-n-view.css" rel="stylesheet"/>
|
||||||
|
|
||||||
|
<script src="grid-n-view.js"></script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body.splash {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* demo: image spacing... */
|
||||||
|
.image-spacing {
|
||||||
|
--gallery-image-spacing: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* demo: tiny images... */
|
||||||
|
.tiny-images {
|
||||||
|
--gallery-image-base-height: 10rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* demo: square image blocks... */
|
||||||
|
.image-squares {
|
||||||
|
--gallery-image-spacing: 0.5em;
|
||||||
|
}
|
||||||
|
.image-squares .images img {
|
||||||
|
--gallery-image-base-width: var(--gallery-image-base-height);
|
||||||
|
|
||||||
|
background: var(--gallery-secondary-color);
|
||||||
|
outline: solid 1px var(--gallery-background-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
var SCROLL_TIMEOUT = 100
|
||||||
|
|
||||||
|
// save/restore scroll position...
|
||||||
|
// XXX might also be nice to restory current image and selection...
|
||||||
|
window.addEventListener('beforeunload', function(){
|
||||||
|
window.scrollX > 0 ?
|
||||||
|
(sessionStorage.windowScrollX = window.scrollX)
|
||||||
|
: (delete sessionStorage.windowScrollX)
|
||||||
|
sessionStorage.windowScrollY = window.scrollY })
|
||||||
|
var restoreScroll = function(){
|
||||||
|
setTimeout(function(){
|
||||||
|
sessionStorage.windowScrollY
|
||||||
|
&& window.scroll(
|
||||||
|
(sessionStorage.windowScrollX ?? 0)*1,
|
||||||
|
sessionStorage.windowScrollY*1) }, SCROLL_TIMEOUT ?? 100) }
|
||||||
|
|
||||||
|
var pageSetup = function(){
|
||||||
|
setup()
|
||||||
|
restoreScroll()
|
||||||
|
document.body.classList.remove('splash') }
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body onload="pageSetup()" class="splash">
|
||||||
|
|
||||||
|
|
||||||
|
<h3>Keyboard controls</h3>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
Left / Reight - Previos / next image
|
||||||
|
Up / Down - Image above / below
|
||||||
|
Space - Mark image (also shift-click)
|
||||||
|
Ctrl-A - Mark all images
|
||||||
|
Ctrl-D - Unmark all images
|
||||||
|
Ctrl-I - Reverse image marks
|
||||||
|
Enter - Toggle lightbox
|
||||||
|
Esc - Close image info or lightbox
|
||||||
|
Delete - Toggle image / marked for deletion (toggle)
|
||||||
|
Shift-Delete - Delete marked image(s) or current if none are marked
|
||||||
|
|
||||||
|
NOTE: if the grid behaves in an odd way on resize tweak PATCH_MARGIN value,
|
||||||
|
though this sould not be necessary.
|
||||||
|
(optimal range >1 and <3)
|
||||||
|
NOTE: the "basic actions" below are to be moved to the toolbar...
|
||||||
|
|
||||||
|
For more info see: <a href="./README.md">README.md</a>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<h3>Settings and debug controls</h3>
|
||||||
|
|
||||||
|
<button onclick="document.body.classList.toggle('gallery-dark')">gallery: ◐</button>
|
||||||
|
<button onclick="document.body.classList.toggle('lightbox-dark')">lightbox: ◐</button>
|
||||||
|
<button onclick="document.body.classList.toggle('image-spacing'); gallery.update()">gallery: spacing</button>
|
||||||
|
<button onclick="document.body.classList.toggle('image-squares'); gallery.update()">gallery: squares</button>
|
||||||
|
<button onclick="document.body.classList.toggle('tiny-images'); gallery.update()">gallery: tiny</button>
|
||||||
|
<br>
|
||||||
|
<button onclick="gallery.toolbars.map(function(t){ t.movable() })">toolbar: drag</button>
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
<button onclick="gallery.toggleLoading()">gallery: loading</button>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<div class="gallery otter">
|
||||||
|
<!-- toolbar -->
|
||||||
|
<div class="toolbar-anchor">
|
||||||
|
<!-- toolbar: general... -->
|
||||||
|
<div class="toolbar fixed">
|
||||||
|
<button class="drag-handle" title="Drag">drag_indicator</button>
|
||||||
|
<div>
|
||||||
|
<button onclick="gallery" title="Upload">cloud_upload</button>
|
||||||
|
<button onclick="gallery" title="Save">save</button>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button onclick="gallery.details.show()" title="Edit">imagesmode<sec>edit</sec></button>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button onclick="gallery.toggleMark()" title="Toggle mark current (space)">select</button>
|
||||||
|
<button onclick="gallery.markAll()" title="Mark all (ctrl-a)">select<sec>select</sec></button>
|
||||||
|
<button onclick="gallery.unmarkAll()" title="Unmark all (ctrl-d)">square<sec>square</sec></button>
|
||||||
|
<button onclick="gallery.markInverse()" title="Reverse mark (ctrl-i)">select<sec>square</sec></button>
|
||||||
|
<button onclick="gallery.remove('marked')" title="Remove marked">select<sec>close</sec></button>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button onclick="gallery.crop('marked')" title="Crop marked">select<sec>crossword</sec></button>
|
||||||
|
<button onclick="gallery.uncrop()" title="Uncrop">select<sec>grid_on</sec></button>
|
||||||
|
<button onclick="gallery" title="Save crop">crossword<sec>add</sec></button>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button onclick="gallery.toggleQueueRemoval()" title="Queue removal (del)">delete</button>
|
||||||
|
<button onclick="gallery.toggleQueueRemoval('marked')" title="Toggle marked removal">delete<sec>select</sec></button>
|
||||||
|
<button onclick="gallery.removeQueued()" title="Remove queued (shift-del)">delete<sec>close</sec></button>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button onclick="gallery.clear()" title="clear">grid_on<sec>close</sec></button>
|
||||||
|
</div>
|
||||||
|
<button class="collapse" title="Edit (hold to make sticky)">edit_square</button>
|
||||||
|
</div>
|
||||||
|
<!-- toolbar: states... -->
|
||||||
|
<div class="toolbar fixed">
|
||||||
|
<button class="drag-handle" title="Drag">drag_indicator</button>
|
||||||
|
<div>
|
||||||
|
<button onclick="gallery" title="Save">crossword<sec>add</sec></button>
|
||||||
|
</div>
|
||||||
|
<div class="states"></div>
|
||||||
|
<!--div class="states">
|
||||||
|
<button onclick="gallery" title="Load 1">1</button>
|
||||||
|
<button onclick="gallery" title="Load 1">2</button>
|
||||||
|
<button onclick="gallery" title="Load 1">3</button>
|
||||||
|
</div-->
|
||||||
|
<button class="collapse" title="Saved (hold to make sticky)">crossword</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- gallery: content -->
|
||||||
|
<div class="images">
|
||||||
|
<img src="images/500px/1.JPG" caption="Caption text">
|
||||||
|
<img src="images/500px/2.JPG">
|
||||||
|
<img src="images/500px/3.JPG" class="marked">
|
||||||
|
<img src="images/500px/DSC08102.jpg">
|
||||||
|
<img src="images/500px/4.JPG">
|
||||||
|
<img src="images/500px/5.JPG">
|
||||||
|
<img src="images/500px/DSC08102.jpg" class="marked">
|
||||||
|
<img src="images/500px/6.JPG">
|
||||||
|
<img src="images/500px/DSC08102.jpg">
|
||||||
|
<img src="images/500px/2.JPG" class="marked">
|
||||||
|
<img src="images/500px/5.JPG">
|
||||||
|
</div>
|
||||||
|
<!-- lightbox -->
|
||||||
|
<div class="lightbox">
|
||||||
|
<!-- XXX not sure about draggable=.. here... -->
|
||||||
|
<img draggable="false">
|
||||||
|
<div class="buttons">
|
||||||
|
<div class="button prev"></div>
|
||||||
|
<div class="button next"></div>
|
||||||
|
<div class="button info"></div>
|
||||||
|
<div class="button fullscreen"></div>
|
||||||
|
<div class="button close"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- details -->
|
||||||
|
<div class="details">
|
||||||
|
<!-- XXX not sure about draggable=.. here... -->
|
||||||
|
<img draggable="false">
|
||||||
|
<div class="caption">
|
||||||
|
CAPTION
|
||||||
|
</div>
|
||||||
|
<div class="tags">
|
||||||
|
TAGS
|
||||||
|
</div>
|
||||||
|
<div class="metadata">
|
||||||
|
METADATA
|
||||||
|
</div>
|
||||||
|
<div class="buttons">
|
||||||
|
<div class="button prev"></div>
|
||||||
|
<div class="button next"></div>
|
||||||
|
<div class="button close"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- loading screen -->
|
||||||
|
<div class="loading">
|
||||||
|
<div></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
<!-- vim:set ts=4 sw=4 : -->
|
||||||
1842
grid-n-view.js
Normal file
1842
grid-n-view.js
Normal file
File diff suppressed because it is too large
Load Diff
5
package.json
Normal file
5
package.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"dependencies": {
|
||||||
|
"material-symbols": "^0.10.4"
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user