experimenting with draggable toolbar (disabled)

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2023-08-17 11:24:30 +03:00
parent 4f5717178b
commit 8394c8e05f
3 changed files with 210 additions and 69 deletions

View File

@ -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);
} }

View File

@ -78,6 +78,7 @@ For more info see: <a href="./README.md">README.md</a>
<div class="gallery otter"> <div class="gallery otter">
<!-- toolbar --> <!-- toolbar -->
<div class="toolbar-anchor">
<div class="toolbar"> <div class="toolbar">
<button class="drag-handle" title="drag">drag_indicator</button> <button class="drag-handle" title="drag">drag_indicator</button>
<div> <div>
@ -112,6 +113,7 @@ For more info see: <a href="./README.md">README.md</a>
</div> </div>
<button class="collapse" title="toggle toolbar (hold to make sticky)">keyboard_double_arrow_left</button> <button class="collapse" title="toggle toolbar (hold to make sticky)">keyboard_double_arrow_left</button>
</div> </div>
</div>
<!-- gallery: content --> <!-- gallery: content -->
<div class="images"> <div class="images">
<img src="images/500px/1.JPG" caption="Caption text"> <img src="images/500px/1.JPG" caption="Caption text">

View File

@ -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,33 +894,42 @@ 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){
if(holding_toggle){
holding_toggle = false
evt.preventDefault() evt.preventDefault()
hold_timeout hold_timeout
&& clearTimeout(hold_timeout) && clearTimeout(hold_timeout)
hold_timeout = undefined hold_timeout = undefined
that.toggleToolbar() } 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 } return }
@ -906,12 +937,98 @@ var Gallery = {
function(){ function(){
hide_timeout = undefined hide_timeout = undefined
that.toggleToolbar('hide') }, that.toggleToolbar('hide') },
that.toolbar_autohide ?? 1000) }) that.toolbar_autohide ?? 1000) }
toolbar var toolbarAutoHideCancel = function(evt){
.addEventListener('mouseover', function(evt){
hide_timeout hide_timeout
&& clearTimeout(hide_timeout) && clearTimeout(hide_timeout)
hide_timeout = undefined }) 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 }
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... // 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){