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 ****/
|
||||
|
||||
/* 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 {
|
||||
--move-x: 0;
|
||||
--move-y: 0;
|
||||
|
||||
--padding: 0.5rem;
|
||||
--top: 1rem;
|
||||
--height: calc((var(--toolbar-button-size) + var(--padding) * 2));
|
||||
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
position: sticky;
|
||||
|
||||
left: var(--move-x);
|
||||
top: var(--move-y);
|
||||
|
||||
width: fit-content;
|
||||
top: calc(var(--height) * -1 + var(--top));
|
||||
|
||||
padding: var(--padding);
|
||||
padding-right: 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%;
|
||||
|
||||
z-index: calc(var(--base-layer) + 2);
|
||||
translate: 0 0;
|
||||
|
||||
border: solid 1px var(--gallery-secondary-color);
|
||||
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);
|
||||
|
||||
transition:
|
||||
left 0.2s,
|
||||
padding-right 0.2s,
|
||||
opacity 0.2s,
|
||||
translate 0.2s;
|
||||
@ -282,6 +293,10 @@ body {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.gallery .toolbar.moving {
|
||||
transition: none;
|
||||
}
|
||||
|
||||
/* sticky toolbar indicator... */
|
||||
.gallery .toolbar.sticky:after {
|
||||
content: "lock";
|
||||
@ -305,7 +320,10 @@ body {
|
||||
/* collapsed toolbar (default)... */
|
||||
/* XXX shoud the toolbar be vertical??? */
|
||||
.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: var(--height);
|
||||
}
|
||||
|
||||
@ -78,39 +78,41 @@ For more info see: <a href="./README.md">README.md</a>
|
||||
|
||||
<div class="gallery otter">
|
||||
<!-- toolbar -->
|
||||
<div class="toolbar">
|
||||
<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 class="toolbar-anchor">
|
||||
<div class="toolbar">
|
||||
<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" 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>
|
||||
<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>
|
||||
<!-- gallery: content -->
|
||||
<div class="images">
|
||||
|
||||
173
grid-n-view.js
173
grid-n-view.js
@ -128,6 +128,28 @@ function(elem) {
|
||||
&& rect.right <= (window.innerWidth
|
||||
|| 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...
|
||||
var toolbar = this.dom.querySelector('.toolbar')
|
||||
var toolbar_moving = false
|
||||
// prevent clicks in toolbar from affecting the gallery...
|
||||
toolbar
|
||||
.addEventListener('click', function(evt){
|
||||
evt.stopPropagation() })
|
||||
|
||||
// toolbar: collapse: click, hold to make sticky...
|
||||
var hold_timeout
|
||||
var handleInterationStart = function(evt){
|
||||
var holding_toggle
|
||||
var handleInteractionStart = function(evt){
|
||||
holding_toggle = true
|
||||
hold_timeout = setTimeout(
|
||||
function(){
|
||||
hold_timeout = undefined
|
||||
toolbar.classList.toggle('sticky') },
|
||||
that.toolbar_hold ?? 300) }
|
||||
var handleInterationEnd = function(evt){
|
||||
evt.preventDefault()
|
||||
hold_timeout
|
||||
&& clearTimeout(hold_timeout)
|
||||
hold_timeout = undefined
|
||||
that.toggleToolbar() }
|
||||
var handleInteractionEnd = function(evt){
|
||||
if(holding_toggle){
|
||||
holding_toggle = false
|
||||
evt.preventDefault()
|
||||
hold_timeout
|
||||
&& clearTimeout(hold_timeout)
|
||||
hold_timeout = undefined
|
||||
that.toggleToolbar() }}
|
||||
var collapse_button = toolbar.querySelector('.collapse')
|
||||
collapse_button.addEventListener('touchstart', handleInterationStart)
|
||||
collapse_button.addEventListener('mousedown', handleInterationStart)
|
||||
collapse_button.addEventListener('touchend', handleInterationEnd)
|
||||
collapse_button.addEventListener('mouseup', handleInterationEnd)
|
||||
collapse_button.addEventListener('touchstart', handleInteractionStart)
|
||||
collapse_button.addEventListener('mousedown', handleInteractionStart)
|
||||
// XXX should these be on document???
|
||||
// ...if yes we'll need to be carefull with .preventDefault(..)
|
||||
document.addEventListener('touchend', handleInteractionEnd)
|
||||
document.addEventListener('mouseup', handleInteractionEnd)
|
||||
|
||||
// toolbar: autohide...
|
||||
var hide_timeout
|
||||
toolbar
|
||||
.addEventListener('mouseout', function(evt){
|
||||
if(that.toolbar_autohide == 0
|
||||
|| toolbar.classList.contains('sticky')){
|
||||
// XXX does not work correctly with touch...
|
||||
var toolbarAutoHideTimerStart = function(evt){
|
||||
if(that.toolbar_autohide == 0
|
||||
|| 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 }
|
||||
hide_timeout = setTimeout(
|
||||
function(){
|
||||
hide_timeout = undefined
|
||||
that.toggleToolbar('hide') },
|
||||
that.toolbar_autohide ?? 1000) })
|
||||
toolbar
|
||||
.addEventListener('mouseover', function(evt){
|
||||
hide_timeout
|
||||
&& clearTimeout(hide_timeout)
|
||||
hide_timeout = undefined })
|
||||
evt.preventDefault()
|
||||
evt.stopPropagation()
|
||||
toolbar.classList.remove('moving')
|
||||
toolbar_moving = false } }
|
||||
// XXX ignore non-local touches...
|
||||
// XXX disable button clicking while moving...
|
||||
var handleToolbarMove = function(evt){
|
||||
if(toolbar_moving){
|
||||
var src = toolbar_moving.touch != null ?
|
||||
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...
|
||||
this.dom.querySelector('.images')
|
||||
@ -937,6 +1054,7 @@ var Gallery = {
|
||||
.addEventListener('click', function(evt){
|
||||
that.unmark_current
|
||||
&& (that.current = null) })
|
||||
|
||||
// drag/drop: sort...
|
||||
var dragged
|
||||
this.dom
|
||||
@ -944,7 +1062,10 @@ var Gallery = {
|
||||
var i = that.images.indexOf(evt.target)
|
||||
if(i >= 0){
|
||||
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
|
||||
this.dom
|
||||
.addEventListener('dragenter', function(evt){
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user