added selection...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2023-07-20 21:42:17 +03:00
parent 802fe8193b
commit 03a79d3f22
3 changed files with 128 additions and 44 deletions

View File

@ -62,32 +62,54 @@ body {
/* XXX need to account for scrollbar popping in and out */
.gallery {
position: relative;
display: flex;
justify-content: flex-start;
align-content: flex-start;
flex-flow: row wrap;
margin-left: var(--gallery-scrollbar-width);
margin-right: 0;
color: var(--gallery-text-color);
background: var(--gallery-background-color);
}
.gallery img {
.gallery .images {
position: relative;
display: flex;
justify-content: flex-start;
align-content: flex-start;
flex-flow: row wrap;
}
.gallery .images img {
height: 300px;
width: auto;
image-rendering: crisp-edges;
box-sizing: border-box;
}
.gallery>img {
.gallery .images img {
cursor: hand;
}
.gallery img.current {
.gallery .images img.current {
border: solid 2px red;
}
/*************************************************** Image markers ***/
.gallery .images img+.mark {
position: relative;
}
/* marker: selected */
.gallery .images img+.mark.selected:after {
content: "";
position: absolute;
display: block;
width: 1em;
height: 1em;
right: 0.5em;
bottom: 0.5em;
border-radius: 50%;
background: blue;
}
/******************************************************* Lightbox ****/
.gallery .lightbox {

View File

@ -19,25 +19,25 @@
<body onload="setup()">
<div class="gallery">
<!-- 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">
<img src="images/500px/DSC08102.jpg">
<img src="images/500px/4.JPG">
<img src="images/500px/5.JPG">
<img src="images/500px/DSC08102.jpg">
<img src="images/500px/6.JPG">
<img src="images/500px/DSC08102.jpg">
<img src="images/500px/2.JPG">
<img src="images/500px/5.JPG">
</div>
<!-- lightbox -->
<div class="lightbox">
<img>
<div class="button close"></div>
</div>
<!-- gallery: content -->
<img src="images/500px/1.JPG" caption="Caption text">
<img src="images/500px/2.JPG">
<img src="images/500px/3.JPG">
<img src="images/500px/DSC08102.jpg">
<img src="images/500px/4.JPG">
<img src="images/500px/5.JPG">
<img src="images/500px/DSC08102.jpg">
<img src="images/500px/6.JPG">
<img src="images/500px/DSC08102.jpg">
<img src="images/500px/2.JPG">
<img src="images/500px/5.JPG">
</div>
</body>

View File

@ -110,6 +110,24 @@ var keyboard = {
Escape: function(){
gallery.lightbox.shown
&& gallery.lightbox.hide() },
// selection...
' ': function(evt){
gallery.current
&& evt.preventDefault()
gallery.toggleSelect() },
// XXX use key codes...
'a': function(evt){
evt.preventDefault()
if(evt.ctrlKey){
gallery.selectAll() } },
'd': function(evt){
evt.preventDefault()
if(evt.ctrlKey){
gallery.deselectAll() } },
'i': function(evt){
evt.preventDefault()
if(evt.ctrlKey){
gallery.selectInverse() } },
}
@ -131,9 +149,9 @@ var Gallery = {
return undefined },
get current(){
return this.dom.querySelector('img.current') },
return this.dom.querySelector('.images img.current') },
set current(img){
for(var i of this.dom.querySelectorAll('img.current')){
for(var i of this.dom.querySelectorAll('.images img.current')){
i.classList.remove('current') }
img.classList.add('current')
img.scrollIntoView({
@ -141,34 +159,41 @@ var Gallery = {
block: 'nearest',
}) },
// XXX should this be writable???
get images(){
return [...this.dom.querySelectorAll('.images img')] },
getRow: function(img, direction='current'){
if(['above', 'current', 'below'].includes(img)){
direction = img
img = null }
img = this.current }
// get above/below row...
// XXX these are wastefull...
if(direction == 'above'){
var row = this.getRow(img)
var e = row[0].previousSibling
var e = row[0].previousElementSibling
while(e && e.tagName != 'IMG'){
e = e.previousSibling }
e = e.previousElementSibling }
return e ?
this.getRow(e)
: this.getRow([...this.dom.querySelectorAll('img')].at(-1))
: this.getRow(this.images.at(-1))
} else if(direction == 'below'){
// special case: nothing selected...
if(img == null){
return this.getRow() }
var row = this.getRow(img)
var e = row.at(-1).nextSibling
var e = row.at(-1).nextElementSibling
while(e && e.tagName != 'IMG'){
e = e.nextSibling }
e = e.nextElementSibling }
return e ?
this.getRow(e)
: this.getRow([...this.dom.querySelectorAll('img')][1]) }
: this.getRow(this.images[0]) }
// get current row...
var cur = img
?? this.current
if(cur == null){
var scroll = getScrollParent(this.dom).scrollTop
var images = [...this.dom.querySelectorAll('img')].slice(1)
var images = this.images
for(cur of images){
if(cur.offsetTop >= scroll){
break } } }
@ -177,16 +202,16 @@ var Gallery = {
var e = cur
while(e && e.offsetTop == top){
row.push(e)
e = e.nextSibling
e = e.nextElementSibling
while(e && e.tagName != 'IMG'){
e = e.nextSibling } }
e = e.nextElementSibling } }
e = cur
while(e && e.offsetTop == top){
e === cur
|| row.unshift(e)
e = e.previousSibling
e = e.previousElementSibling
while(e && e.tagName != 'IMG'){
e = e.previousSibling } }
e = e.previousElementSibling } }
return row },
getImage: function(img, direction='current'){
if(['left', 'above', 'current', 'below', 'right'].includes(img)){
@ -196,7 +221,7 @@ var Gallery = {
if(direction == 'current'){
return img
?? this.current
?? this.getRow(img)
?? this.getRow(img)[0]
// above/below...
} else if(direction == 'above' || direction == 'below'){
var row = this.getRow(direction)
@ -232,7 +257,7 @@ var Gallery = {
// XXX cache image list???
prev: function(){
var images = [...this.dom.querySelectorAll('img')].slice(1)
var images = this.images
var i = this.current == null ?
images.length-1
: images.indexOf(this.current)-1
@ -242,7 +267,7 @@ var Gallery = {
this.current = images[i]
return this },
next: function(){
var images = [...this.dom.querySelectorAll('img')].slice(1)
var images = this.images
var i = this.current == null ?
0
: images.indexOf(this.current)+1
@ -276,9 +301,46 @@ var Gallery = {
this.current = this.getImage('below')
return this },
// XXX
// selection...
get selected(){
return this.dom.querySelectorAll('.images img.selected') },
updateMarkers: function(){
// select...
for(var img of this.dom.querySelectorAll('.images img.selected')){
var mark = img.nextElementSibling
while(mark && mark.tagName != 'IMG' && !mark.classList.contains('mark')){
mark = img.nextElementSibling }
if(!mark || !mark.classList.contains('mark')){
mark = document.createElement('div')
mark.classList.add('selected', 'mark')
img.after(mark) } }
// clear deselected...
for(var mark of this.dom.querySelectorAll('.images img:not(.selected)+.mark')){
mark.remove() }
return this },
select: function(){
},
this.current?.classList.add('selected')
return this.updateMarkers() },
deselect: function(){
this.current?.classList.remove('selected')
return this.updateMarkers() },
toggleSelect: function(){
this.current?.classList.toggle('selected')
this.updateMarkers()
return this },
selectAll: function(){
for(var img of this.images){
img.classList.add('selected') }
return this.updateMarkers() },
deselectAll: function(){
for(var img of this.images){
img.classList.remove('selected') }
return this.updateMarkers() },
selectInverse: function(){
for(var img of this.images){
img.classList.toggle('selected') }
return this.updateMarkers() },
show: function(){
this.lightbox.show()
@ -435,7 +497,7 @@ var setupGallery = function(gallery){
.setup(gallery) }
var setup = function(){
patchFlexRows([...document.querySelectorAll('.gallery>img')])
patchFlexRows([...document.querySelectorAll('.gallery .images img')])
var galleries = document.body.querySelectorAll('.gallery')
for(var gallery of galleries){
@ -447,7 +509,7 @@ var setup = function(){
if(key in keyboard){
keyboard[key](evt) } })
window.addEventListener('resize', function(){
patchFlexRows([...document.querySelectorAll('.gallery>img')]) })
patchFlexRows([...document.querySelectorAll('.gallery .images img')]) })
}