-
-
+
diff --git a/grid-n-view.js b/grid-n-view.js
index 62ec2bc..d4fd03a 100644
--- a/grid-n-view.js
+++ b/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){