From a6d04eff3b5ffca7fc4032208c3fdcadca49929d Mon Sep 17 00:00:00 2001 From: "Alex A. Naanou" Date: Fri, 18 Aug 2023 13:23:27 +0300 Subject: [PATCH] scroll bounding to screen works... Signed-off-by: Alex A. Naanou --- css/grid-n-view.css | 2 ++ grid-n-view.js | 83 +++++++++++++++++++++++++++++++++++++-------- 2 files changed, 71 insertions(+), 14 deletions(-) diff --git a/css/grid-n-view.css b/css/grid-n-view.css index b24e234..f6344ce 100644 --- a/css/grid-n-view.css +++ b/css/grid-n-view.css @@ -271,6 +271,8 @@ body { padding-right: var(--height); padding-left: var(--height); + /*scroll-margin: var(--gallery-image-scroll-margin);*/ + translate: 0 0; border: solid 1px var(--gallery-secondary-color); diff --git a/grid-n-view.js b/grid-n-view.js index 277fc4e..2881ca2 100644 --- a/grid-n-view.js +++ b/grid-n-view.js @@ -161,6 +161,9 @@ var getTouch = function(evt, id){ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// XXX constrain this to: +// viewport -- DONE but needs to be smoother... +// parent // XXX might be a good idea to allow bounds to be: // string - css selector // element - @@ -176,15 +179,26 @@ var moveable = function(elem, options={}){ cls, handle, bounds, + // can be: + // 'x' + // 'y' + // undefined + lock, start = function(elem, data){ bounds ?? (data.bounds = bounds) return data }, beforeMove, + // can be: + // 'strict' + // 'scroll' / true + // false + keepInView = true, move = function(elem, data){ - elem.style.left = data.x + 'px' - elem.style.top = data.y + 'px' - }, + data.x != null + && (elem.style.left = data.x + 'px') + data.y != null + && (elem.style.top = data.y + 'px') }, end, } = options handle = typeof(handle) == 'string' ? @@ -228,27 +242,61 @@ var moveable = function(elem, options={}){ return } evt.preventDefault() evt.stopPropagation() + // viewport bounding box in elem coordinates... var x = src.clientX var y = src.clientY data.x = - data.bounds != null ? - Math.min(data.bounds.right, - Math.max(data.bounds.left, + lock == 'x' ? + null + : data.bounds != null ? + Math.min( + data.bounds.right, + Math.max( + data.bounds.left, x - data.offset.x)) - : x - data.offset.x + : x - data.offset.x data.y = - data.bounds != null ? - Math.min(data.bounds.bottom, - Math.max(data.bounds.top, + lock == 'y' ? + null + : data.bounds != null ? + Math.min( + data.bounds.bottom, + Math.max( + data.bounds.top, y - data.offset.y)) - : y - data.offset.y + : y - data.offset.y + // restrict to viewport... + if(keepInView == 'strict'){ + var bb = elem.getBoundingClientRect() + var screen = { + top: t = elem.offsetTop - bb.top, + left: l = elem.offsetLeft - bb.left, + bottom: window.innerHeight + t - elem.offsetHeight, + right: window.innerWidth + l - elem.offsetWidth, + } + data.x = Math.min( + screen.right, + Math.max( + screen.left, + data.x)) + data.y = Math.min( + screen.bottom, + Math.max( + screen.top, + data.y)) } // NOTE: we only allow a single requestAnimationFrame(..) // to run per frame... if(!data.animate){ data.animate = requestAnimationFrame(function(){ if(!data){ return } - move(elem, data) + move + && move(elem, data) + // keep in view... + // NOTE: this works best with CSS's scroll-margin... + ;(keepInView == 'scroll' + || keepInView === true) + && elem.scrollIntoView({ block: 'nearest' }) delete data.animate }) } } } var handleMoveEnd = function(evt){ if(data){ @@ -1306,6 +1354,9 @@ var Toolbar = { // toolbar: move... // XXX to drag anywhere on the elem we need to prevent // clicks while dragging... + // XXX prevent from scrolling off screen when placed a bottom + // and scrolling up -- i.e. keep within viewport and gallery + // at all times... moveable(toolbar, { cls: 'moving', handle: '.drag-handle', @@ -1319,9 +1370,13 @@ var Toolbar = { right: that.gallery.dom.offsetWidth - elem.offsetWidth - 20, bottom: that.gallery.dom.offsetHeight - elem.offsetHeight - 20, } }, + //keepInView: 'scroll', + keepInView: 'strict', move: function(elem, data){ - elem.style.setProperty('--move-x', data.x + 'px') - elem.style.setProperty('--move-y', data.y + 'px') }, }) + data.x != null + && elem.style.setProperty('--move-x', data.x + 'px') + data.y != null + && elem.style.setProperty('--move-y', data.y + 'px') }, }) return this }, }