experimenting with draggable toolbar (disabled)
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
4f5717178b
commit
8394c8e05f
@ -242,26 +242,36 @@ body {
|
|||||||
|
|
||||||
/******************************************************** Toolbar ****/
|
/******************************************************** Toolbar ****/
|
||||||
|
|
||||||
/* XXX make the toolbar swirchable and contextual... */
|
.gallery .toolbar-anchor {
|
||||||
|
position: sticky;
|
||||||
|
|
||||||
|
top: 0;
|
||||||
|
margin: 0 calc(var(--gallery-padding-horizontal) * -1);
|
||||||
|
|
||||||
|
z-index: calc(var(--base-layer) + 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* XXX make the toolbar contextual... */
|
||||||
.gallery .toolbar {
|
.gallery .toolbar {
|
||||||
|
--move-x: 0;
|
||||||
|
--move-y: 0;
|
||||||
|
|
||||||
--padding: 0.5rem;
|
--padding: 0.5rem;
|
||||||
--top: 1rem;
|
|
||||||
--height: calc((var(--toolbar-button-size) + var(--padding) * 2));
|
--height: calc((var(--toolbar-button-size) + var(--padding) * 2));
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
position: sticky;
|
|
||||||
|
left: var(--move-x);
|
||||||
|
top: var(--move-y);
|
||||||
|
|
||||||
width: fit-content;
|
width: fit-content;
|
||||||
top: calc(var(--height) * -1 + var(--top));
|
|
||||||
padding: var(--padding);
|
padding: var(--padding);
|
||||||
padding-right: var(--height);
|
padding-right: var(--height);
|
||||||
padding-left: var(--height);
|
padding-left: var(--height);
|
||||||
margin-left: calc(var(--gallery-padding-horizontal) * -1);
|
|
||||||
/* takeup no space... */
|
|
||||||
margin-top: calc(var(--height) * -1);
|
|
||||||
|
|
||||||
translate: 0 100%;
|
translate: 0 0;
|
||||||
|
|
||||||
z-index: calc(var(--base-layer) + 2);
|
|
||||||
|
|
||||||
border: solid 1px var(--gallery-secondary-color);
|
border: solid 1px var(--gallery-secondary-color);
|
||||||
border-radius: calc(var(--height) / 8);
|
border-radius: calc(var(--height) / 8);
|
||||||
@ -270,6 +280,7 @@ body {
|
|||||||
box-shadow: 0.2em 0.2em 0.5em -0.3em rgba(0,0,0,0.8);
|
box-shadow: 0.2em 0.2em 0.5em -0.3em rgba(0,0,0,0.8);
|
||||||
|
|
||||||
transition:
|
transition:
|
||||||
|
left 0.2s,
|
||||||
padding-right 0.2s,
|
padding-right 0.2s,
|
||||||
opacity 0.2s,
|
opacity 0.2s,
|
||||||
translate 0.2s;
|
translate 0.2s;
|
||||||
@ -282,6 +293,10 @@ body {
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.gallery .toolbar.moving {
|
||||||
|
transition: none;
|
||||||
|
}
|
||||||
|
|
||||||
/* sticky toolbar indicator... */
|
/* sticky toolbar indicator... */
|
||||||
.gallery .toolbar.sticky:after {
|
.gallery .toolbar.sticky:after {
|
||||||
content: "lock";
|
content: "lock";
|
||||||
@ -305,7 +320,10 @@ body {
|
|||||||
/* collapsed toolbar (default)... */
|
/* collapsed toolbar (default)... */
|
||||||
/* XXX shoud the toolbar be vertical??? */
|
/* XXX shoud the toolbar be vertical??? */
|
||||||
.gallery .toolbar:not(.shown) {
|
.gallery .toolbar:not(.shown) {
|
||||||
translate: calc(-100% + var(--toolbar-button-size) + var(--padding)) 100%;
|
translate: calc(-100% + var(--toolbar-button-size) + var(--padding)) 0;
|
||||||
|
|
||||||
|
left: 0;
|
||||||
|
|
||||||
/*padding-right: calc(var(--padding) / 5);*/
|
/*padding-right: calc(var(--padding) / 5);*/
|
||||||
padding-right: var(--height);
|
padding-right: var(--height);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -78,39 +78,41 @@ For more info see: <a href="./README.md">README.md</a>
|
|||||||
|
|
||||||
<div class="gallery otter">
|
<div class="gallery otter">
|
||||||
<!-- toolbar -->
|
<!-- toolbar -->
|
||||||
<div class="toolbar">
|
<div class="toolbar-anchor">
|
||||||
<button class="drag-handle" title="drag">drag_indicator</button>
|
<div class="toolbar">
|
||||||
<div>
|
<button class="drag-handle" title="drag">drag_indicator</button>
|
||||||
<button onclick="gallery" title="upload">cloud_upload</button>
|
<div>
|
||||||
<button onclick="gallery" title="save">save</button>
|
<button onclick="gallery" title="upload">cloud_upload</button>
|
||||||
|
<button onclick="gallery" title="save">save</button>
|
||||||
|
</div>
|
||||||
|
<!--div>
|
||||||
|
<button onclick="gallery" title="save">contrast</button>
|
||||||
|
</div-->
|
||||||
|
<div>
|
||||||
|
<!--button onclick="gallery.details.show()" title="info">imagesmode<sec>label</sec></button-->
|
||||||
|
<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" title="crop marked">select<sec>crossword</sec></button>
|
||||||
|
<button onclick="gallery" title="uncrop">select<sec>grid_on</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">close</button>
|
||||||
|
</div>
|
||||||
|
<button class="collapse" title="toggle toolbar (hold to make sticky)">keyboard_double_arrow_left</button>
|
||||||
</div>
|
</div>
|
||||||
<!--div>
|
|
||||||
<button onclick="gallery" title="save">contrast</button>
|
|
||||||
</div-->
|
|
||||||
<div>
|
|
||||||
<!--button onclick="gallery.details.show()" title="info">imagesmode<sec>label</sec></button-->
|
|
||||||
<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" title="crop marked">select<sec>crossword</sec></button>
|
|
||||||
<button onclick="gallery" title="uncrop">select<sec>grid_on</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">close</button>
|
|
||||||
</div>
|
|
||||||
<button class="collapse" title="toggle toolbar (hold to make sticky)">keyboard_double_arrow_left</button>
|
|
||||||
</div>
|
</div>
|
||||||
<!-- gallery: content -->
|
<!-- gallery: content -->
|
||||||
<div class="images">
|
<div class="images">
|
||||||
|
|||||||
173
grid-n-view.js
173
grid-n-view.js
@ -128,6 +128,28 @@ function(elem) {
|
|||||||
&& rect.right <= (window.innerWidth
|
&& rect.right <= (window.innerWidth
|
||||||
|| document.documentElement.clientWidth) }
|
|| document.documentElement.clientWidth) }
|
||||||
|
|
||||||
|
// XXX move to types.js...
|
||||||
|
var ruler
|
||||||
|
var px2rem = function(px){
|
||||||
|
if(!ruler){
|
||||||
|
ruler = document.createElement('div')
|
||||||
|
document.body.append(ruler) }
|
||||||
|
ruler.style.width = '1rem'
|
||||||
|
var c = ruler.offsetWidth
|
||||||
|
return px / c }
|
||||||
|
var rem2px = function(rem){
|
||||||
|
if(!ruler){
|
||||||
|
ruler = document.createElement('div')
|
||||||
|
document.body.append(ruler) }
|
||||||
|
ruler.style.width = rem + 'em'
|
||||||
|
var px = ruler.offsetWidth
|
||||||
|
return px }
|
||||||
|
|
||||||
|
var getTouch = function(evt, id){
|
||||||
|
if(id != null && id !== false && evt.targetTouches){
|
||||||
|
for(var k in evt.targetTouches){
|
||||||
|
if(evt.targetTouches[k]?.identifier == id){
|
||||||
|
return evt.targetTouches[k] } } } }
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
@ -872,46 +894,141 @@ var Gallery = {
|
|||||||
|
|
||||||
// toolbar...
|
// toolbar...
|
||||||
var toolbar = this.dom.querySelector('.toolbar')
|
var toolbar = this.dom.querySelector('.toolbar')
|
||||||
|
var toolbar_moving = false
|
||||||
// prevent clicks in toolbar from affecting the gallery...
|
// prevent clicks in toolbar from affecting the gallery...
|
||||||
toolbar
|
toolbar
|
||||||
.addEventListener('click', function(evt){
|
.addEventListener('click', function(evt){
|
||||||
evt.stopPropagation() })
|
evt.stopPropagation() })
|
||||||
|
|
||||||
// toolbar: collapse: click, hold to make sticky...
|
// toolbar: collapse: click, hold to make sticky...
|
||||||
var hold_timeout
|
var hold_timeout
|
||||||
var handleInterationStart = function(evt){
|
var holding_toggle
|
||||||
|
var handleInteractionStart = function(evt){
|
||||||
|
holding_toggle = true
|
||||||
hold_timeout = setTimeout(
|
hold_timeout = setTimeout(
|
||||||
function(){
|
function(){
|
||||||
hold_timeout = undefined
|
hold_timeout = undefined
|
||||||
toolbar.classList.toggle('sticky') },
|
toolbar.classList.toggle('sticky') },
|
||||||
that.toolbar_hold ?? 300) }
|
that.toolbar_hold ?? 300) }
|
||||||
var handleInterationEnd = function(evt){
|
var handleInteractionEnd = function(evt){
|
||||||
evt.preventDefault()
|
if(holding_toggle){
|
||||||
hold_timeout
|
holding_toggle = false
|
||||||
&& clearTimeout(hold_timeout)
|
evt.preventDefault()
|
||||||
hold_timeout = undefined
|
hold_timeout
|
||||||
that.toggleToolbar() }
|
&& clearTimeout(hold_timeout)
|
||||||
|
hold_timeout = undefined
|
||||||
|
that.toggleToolbar() }}
|
||||||
var collapse_button = toolbar.querySelector('.collapse')
|
var collapse_button = toolbar.querySelector('.collapse')
|
||||||
collapse_button.addEventListener('touchstart', handleInterationStart)
|
collapse_button.addEventListener('touchstart', handleInteractionStart)
|
||||||
collapse_button.addEventListener('mousedown', handleInterationStart)
|
collapse_button.addEventListener('mousedown', handleInteractionStart)
|
||||||
collapse_button.addEventListener('touchend', handleInterationEnd)
|
// XXX should these be on document???
|
||||||
collapse_button.addEventListener('mouseup', handleInterationEnd)
|
// ...if yes we'll need to be carefull with .preventDefault(..)
|
||||||
|
document.addEventListener('touchend', handleInteractionEnd)
|
||||||
|
document.addEventListener('mouseup', handleInteractionEnd)
|
||||||
|
|
||||||
// toolbar: autohide...
|
// toolbar: autohide...
|
||||||
var hide_timeout
|
var hide_timeout
|
||||||
toolbar
|
// XXX does not work correctly with touch...
|
||||||
.addEventListener('mouseout', function(evt){
|
var toolbarAutoHideTimerStart = function(evt){
|
||||||
if(that.toolbar_autohide == 0
|
if(that.toolbar_autohide == 0
|
||||||
|| toolbar.classList.contains('sticky')){
|
|| toolbar.classList.contains('sticky')){
|
||||||
|
return }
|
||||||
|
hide_timeout = setTimeout(
|
||||||
|
function(){
|
||||||
|
hide_timeout = undefined
|
||||||
|
that.toggleToolbar('hide') },
|
||||||
|
that.toolbar_autohide ?? 1000) }
|
||||||
|
var toolbarAutoHideCancel = function(evt){
|
||||||
|
hide_timeout
|
||||||
|
&& clearTimeout(hide_timeout)
|
||||||
|
hide_timeout = undefined }
|
||||||
|
toolbar.addEventListener('mouseout', toolbarAutoHideTimerStart)
|
||||||
|
toolbar.addEventListener('touchend', toolbarAutoHideTimerStart)
|
||||||
|
toolbar.addEventListener('mouseover', toolbarAutoHideCancel)
|
||||||
|
toolbar.addEventListener('touchstart', toolbarAutoHideCancel)
|
||||||
|
|
||||||
|
/* XXX problems:
|
||||||
|
// - too many interactions: autohide, placement, ...
|
||||||
|
// - not sure if we need this...
|
||||||
|
// toolbar: move...
|
||||||
|
var handleToolbarMoveStart = function(evt){
|
||||||
|
evt.preventDefault()
|
||||||
|
evt.stopPropagation()
|
||||||
|
if(!toolbar_moving){
|
||||||
|
toolbar.classList.add('moving')
|
||||||
|
var x = evt.clientX
|
||||||
|
?? evt.targetTouches[0].clientX
|
||||||
|
var y = evt.clientY
|
||||||
|
?? evt.targetTouches[0].clientY
|
||||||
|
toolbar_moving = {
|
||||||
|
bounds: {
|
||||||
|
x: that.dom.offsetWidth - toolbar.offsetWidth - 20,
|
||||||
|
// XXX this gets off on high magnifications...
|
||||||
|
y: that.dom.offsetHeight - toolbar.offsetHeight - 20,
|
||||||
|
},
|
||||||
|
offset: {
|
||||||
|
x: x - toolbar.offsetLeft,
|
||||||
|
y: y - toolbar.offsetTop,
|
||||||
|
},
|
||||||
|
touch: evt.targetTouches ?
|
||||||
|
evt.targetTouches[0].identifier
|
||||||
|
: undefined,
|
||||||
|
} } }
|
||||||
|
var handleToolbarMoveEnd = function(evt){
|
||||||
|
if(toolbar_moving){
|
||||||
|
if(evt.targetTouches
|
||||||
|
&& (evt.targetTouches.length == 0
|
||||||
|
|| getTouch(evt, toolbar_moving.touch))){
|
||||||
return }
|
return }
|
||||||
hide_timeout = setTimeout(
|
evt.preventDefault()
|
||||||
function(){
|
evt.stopPropagation()
|
||||||
hide_timeout = undefined
|
toolbar.classList.remove('moving')
|
||||||
that.toggleToolbar('hide') },
|
toolbar_moving = false } }
|
||||||
that.toolbar_autohide ?? 1000) })
|
// XXX ignore non-local touches...
|
||||||
toolbar
|
// XXX disable button clicking while moving...
|
||||||
.addEventListener('mouseover', function(evt){
|
var handleToolbarMove = function(evt){
|
||||||
hide_timeout
|
if(toolbar_moving){
|
||||||
&& clearTimeout(hide_timeout)
|
var src = toolbar_moving.touch != null ?
|
||||||
hide_timeout = undefined })
|
getTouch(evt, toolbar_moving.touch)
|
||||||
|
: evt
|
||||||
|
if(!src){
|
||||||
|
return }
|
||||||
|
evt.preventDefault()
|
||||||
|
evt.stopPropagation()
|
||||||
|
var x = src.clientX
|
||||||
|
var y = src.clientY
|
||||||
|
toolbar_moving.x =
|
||||||
|
toolbar_moving.bounds?.x != null ?
|
||||||
|
Math.min(toolbar_moving.bounds.x,
|
||||||
|
Math.max(0,
|
||||||
|
x - toolbar_moving.offset.x))
|
||||||
|
: x - toolbar_moving.offset.x
|
||||||
|
toolbar_moving.y =
|
||||||
|
toolbar_moving.bounds?.y != null ?
|
||||||
|
Math.min(toolbar_moving.bounds.y,
|
||||||
|
Math.max(0,
|
||||||
|
y - toolbar_moving.offset.y))
|
||||||
|
: y - toolbar_moving.offset.y
|
||||||
|
// NOTE: we only allow a single requestAnimationFrame(..)
|
||||||
|
// to run per frame...
|
||||||
|
if(!toolbar_moving.animate){
|
||||||
|
toolbar_moving.animate = requestAnimationFrame(function(){
|
||||||
|
if(!toolbar_moving){
|
||||||
|
return }
|
||||||
|
toolbar.style.setProperty('--move-x', toolbar_moving.x + 'px')
|
||||||
|
toolbar.style.setProperty('--move-y', toolbar_moving.y + 'px')
|
||||||
|
delete toolbar_moving.animate }) } } }
|
||||||
|
// XXX to drag anywhere on the toolbar we need to prevent
|
||||||
|
// clicks while dragging...
|
||||||
|
toolbar.querySelector('.drag-handle')
|
||||||
|
.addEventListener('mousedown', handleToolbarMoveStart)
|
||||||
|
toolbar.querySelector('.drag-handle')
|
||||||
|
.addEventListener('touchstart', handleToolbarMoveStart)
|
||||||
|
this.dom.addEventListener('mousemove', handleToolbarMove)
|
||||||
|
this.dom.addEventListener('touchmove', handleToolbarMove)
|
||||||
|
document.addEventListener('touchend', handleToolbarMoveEnd)
|
||||||
|
document.addEventListener('mouseup', handleToolbarMoveEnd)
|
||||||
|
//*/
|
||||||
|
|
||||||
// image clicks...
|
// image clicks...
|
||||||
this.dom.querySelector('.images')
|
this.dom.querySelector('.images')
|
||||||
@ -937,6 +1054,7 @@ var Gallery = {
|
|||||||
.addEventListener('click', function(evt){
|
.addEventListener('click', function(evt){
|
||||||
that.unmark_current
|
that.unmark_current
|
||||||
&& (that.current = null) })
|
&& (that.current = null) })
|
||||||
|
|
||||||
// drag/drop: sort...
|
// drag/drop: sort...
|
||||||
var dragged
|
var dragged
|
||||||
this.dom
|
this.dom
|
||||||
@ -944,7 +1062,10 @@ var Gallery = {
|
|||||||
var i = that.images.indexOf(evt.target)
|
var i = that.images.indexOf(evt.target)
|
||||||
if(i >= 0){
|
if(i >= 0){
|
||||||
dragged = evt.target
|
dragged = evt.target
|
||||||
dragged.classList.add('dragged') } })
|
dragged.classList.add('dragged')
|
||||||
|
evt.dataTransfer.setDragImage(dragged, evt.offsetX, evt.offsetY)
|
||||||
|
// XXX add
|
||||||
|
} })
|
||||||
var skip_dragover = false
|
var skip_dragover = false
|
||||||
this.dom
|
this.dom
|
||||||
.addEventListener('dragenter', function(evt){
|
.addEventListener('dragenter', function(evt){
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user