split out the toolbar into a separate object...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2023-08-18 09:11:58 +03:00
parent 2c243b4132
commit 55c2dc83ca
2 changed files with 145 additions and 84 deletions

View File

@ -86,6 +86,12 @@ For more info see: <a href="./README.md">README.md</a>
<hr>
<h3>Settings</h3>
<button onclick="gallery.toolbar.movable()">toggle toolbar drag</button>
<hr>
<div class="gallery otter">
<!-- toolbar -->
<div class="toolbar-anchor">

View File

@ -117,6 +117,9 @@ function(elem){
parent = elem.parentElement }
return parent }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// XXX also need to check if scrolled under something...
var isVisible =
function(elem) {
@ -128,6 +131,8 @@ function(elem) {
&& rect.right <= (window.innerWidth
|| document.documentElement.clientWidth) }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// XXX move to types.js...
var ruler
var px2rem = function(px){
@ -145,6 +150,8 @@ var rem2px = function(rem){
var px = ruler.offsetWidth
return px }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
var getTouch = function(evt, id){
if(id != null && id !== false && evt.targetTouches){
for(var k in evt.targetTouches){
@ -152,6 +159,14 @@ var getTouch = function(evt, id){
return evt.targetTouches[k] } } } }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// XXX might be a good idea to allow bounds to be:
// string - css selector
// element -
// XXX might be a good idea to either:
// - scroll into view the dragged element
// - bound it by screen
// XXX need to check if element already set as movable...
var moveable = function(elem, options={}){
if(elem.dataset.movable){
@ -421,9 +436,6 @@ var Gallery = {
// XXX remove this when/if the selected options feels natural...
vertical_navigate_mode: 'intersection',
toolbar_hold: 300,
toolbar_autohide: 2000,
code: `
<div class="gallery">
<!-- gallery: content -->
@ -438,6 +450,17 @@ var Gallery = {
dom: undefined,
// XXX these are the same....
__toolbar: undefined,
get toolbar(){
if(this.dom){
return this.__toolbar
?? (this.__toolbar = {__proto__: Toolbar }
.setup(
this.dom.querySelector('.toolbar'),
this)) }
delete this.__toolbar
return undefined },
__lightbox: undefined,
get lightbox(){
if(this.dom){
@ -985,91 +1008,11 @@ var Gallery = {
this.dom.querySelector('.images').innerHTML = ''
return this },
toggleToolbar: function(action='toggle'){
var toolbar = this.dom.querySelector('.toolbar')?.classList
toolbar
&& (action == 'toggle' ?
toolbar.toggle('shown')
: action == 'show' ?
toolbar.add('shown')
: toolbar.remove('shown'))
return this },
setup: function(dom){
var that = this
this.dom = dom
// 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 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 handleInteractionEnd = function(evt){
if(holding_toggle){
holding_toggle = false
evt.preventDefault()
if(hold_timeout){
clearTimeout(hold_timeout)
hold_timeout = undefined
that.toggleToolbar() } }}
var collapse_button = toolbar.querySelector('.collapse')
collapse_button.addEventListener('touchstart', handleInteractionStart)
collapse_button.addEventListener('mousedown', handleInteractionStart)
collapse_button.addEventListener('touchend', handleInteractionEnd)
collapse_button.addEventListener('mouseup', handleInteractionEnd)
// toolbar: autohide...
var hide_timeout
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)
// toolbar: move...
// XXX to drag anywhere on the elem we need to prevent
// clicks while dragging...
moveable(toolbar, {
cls: 'moving',
handle: '.drag-handle',
// set bounds...
start: function(elem, data){
if(elem.classList.contains('fixed')){
return false }
data.bounds = {
top: 0,
left: 0,
right: that.dom.offsetWidth - elem.offsetWidth - 20,
bottom: that.dom.offsetHeight - elem.offsetHeight - 20,
} },
move: function(elem, data){
elem.style.setProperty('--move-x', data.x + 'px')
elem.style.setProperty('--move-y', data.y + 'px') }, })
this.toolbar
// image clicks...
this.dom.querySelector('.images')
@ -1272,6 +1215,118 @@ var Gallery = {
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
var Toolbar = {
dom: undefined,
gallery: undefined,
cls: 'toolbar',
hold: 300,
toolbar_autohide: 2000,
// XXX make these generic...
toggle: function(action='toggle'){
var toolbar = this.dom?.classList
toolbar
&& (action == 'toggle' ?
toolbar.toggle('shown')
: action == 'on' ?
toolbar.add('shown')
: toolbar.remove('shown'))
return this },
movable: function(action='toggle'){
var toolbar = this.dom?.classList
toolbar
&& (action == 'toggle' ?
toolbar.toggle('fixed')
: action == 'off' ?
toolbar.add('fixed')
: toolbar.remove('fixed'))
return this },
setup: function(dom, gallery){
var that = this
this.dom = dom
this.gallery = gallery
// toolbar...
var toolbar = this.dom
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 holding_toggle
var handleInteractionStart = function(evt){
holding_toggle = true
hold_timeout = setTimeout(
function(){
hold_timeout = undefined
toolbar.classList.toggle('sticky') },
that.hold ?? 300) }
var handleInteractionEnd = function(evt){
if(holding_toggle){
holding_toggle = false
evt.preventDefault()
if(hold_timeout){
clearTimeout(hold_timeout)
hold_timeout = undefined
that.toggle() } }}
var collapse_button = toolbar.querySelector('.collapse')
collapse_button.addEventListener('touchstart', handleInteractionStart)
collapse_button.addEventListener('mousedown', handleInteractionStart)
collapse_button.addEventListener('touchend', handleInteractionEnd)
collapse_button.addEventListener('mouseup', handleInteractionEnd)
// toolbar: autohide...
var hide_timeout
var toolbarAutoHideTimerStart = function(evt){
if(that.autohide == 0
|| toolbar.classList.contains('sticky')){
return }
hide_timeout = setTimeout(
function(){
hide_timeout = undefined
that.toggle('hide') },
that.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)
// toolbar: move...
// XXX to drag anywhere on the elem we need to prevent
// clicks while dragging...
moveable(toolbar, {
cls: 'moving',
handle: '.drag-handle',
// set bounds...
start: function(elem, data){
if(elem.classList.contains('fixed')){
return false }
data.bounds = {
top: 0,
left: 0,
right: that.gallery.dom.offsetWidth - elem.offsetWidth - 20,
bottom: that.gallery.dom.offsetHeight - elem.offsetHeight - 20,
} },
move: function(elem, data){
elem.style.setProperty('--move-x', data.x + 'px')
elem.style.setProperty('--move-y', data.y + 'px') }, })
return this },
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// This is a prototype for all modal views...