scroll bounding to screen works...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2023-08-18 13:23:27 +03:00
parent 55c2dc83ca
commit a6d04eff3b
2 changed files with 71 additions and 14 deletions

View File

@ -271,6 +271,8 @@ body {
padding-right: var(--height); padding-right: var(--height);
padding-left: var(--height); padding-left: var(--height);
/*scroll-margin: var(--gallery-image-scroll-margin);*/
translate: 0 0; translate: 0 0;
border: solid 1px var(--gallery-secondary-color); border: solid 1px var(--gallery-secondary-color);

View File

@ -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: // XXX might be a good idea to allow bounds to be:
// string - css selector // string - css selector
// element - // element -
@ -176,15 +179,26 @@ var moveable = function(elem, options={}){
cls, cls,
handle, handle,
bounds, bounds,
// can be:
// 'x'
// 'y'
// undefined
lock,
start = function(elem, data){ start = function(elem, data){
bounds bounds
?? (data.bounds = bounds) ?? (data.bounds = bounds)
return data }, return data },
beforeMove, beforeMove,
// can be:
// 'strict'
// 'scroll' / true
// false
keepInView = true,
move = function(elem, data){ move = function(elem, data){
elem.style.left = data.x + 'px' data.x != null
elem.style.top = data.y + 'px' && (elem.style.left = data.x + 'px')
}, data.y != null
&& (elem.style.top = data.y + 'px') },
end, end,
} = options } = options
handle = typeof(handle) == 'string' ? handle = typeof(handle) == 'string' ?
@ -228,27 +242,61 @@ var moveable = function(elem, options={}){
return } return }
evt.preventDefault() evt.preventDefault()
evt.stopPropagation() evt.stopPropagation()
// viewport bounding box in elem coordinates...
var x = src.clientX var x = src.clientX
var y = src.clientY var y = src.clientY
data.x = data.x =
data.bounds != null ? lock == 'x' ?
Math.min(data.bounds.right, null
Math.max(data.bounds.left, : 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 : x - data.offset.x
data.y = data.y =
data.bounds != null ? lock == 'y' ?
Math.min(data.bounds.bottom, null
Math.max(data.bounds.top, : 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 : 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(..) // NOTE: we only allow a single requestAnimationFrame(..)
// to run per frame... // to run per frame...
if(!data.animate){ if(!data.animate){
data.animate = requestAnimationFrame(function(){ data.animate = requestAnimationFrame(function(){
if(!data){ if(!data){
return } 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 }) } } } delete data.animate }) } } }
var handleMoveEnd = function(evt){ var handleMoveEnd = function(evt){
if(data){ if(data){
@ -1306,6 +1354,9 @@ var Toolbar = {
// toolbar: move... // toolbar: move...
// XXX to drag anywhere on the elem we need to prevent // XXX to drag anywhere on the elem we need to prevent
// clicks while dragging... // 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, { moveable(toolbar, {
cls: 'moving', cls: 'moving',
handle: '.drag-handle', handle: '.drag-handle',
@ -1319,9 +1370,13 @@ var Toolbar = {
right: that.gallery.dom.offsetWidth - elem.offsetWidth - 20, right: that.gallery.dom.offsetWidth - elem.offsetWidth - 20,
bottom: that.gallery.dom.offsetHeight - elem.offsetHeight - 20, bottom: that.gallery.dom.offsetHeight - elem.offsetHeight - 20,
} }, } },
//keepInView: 'scroll',
keepInView: 'strict',
move: function(elem, data){ move: function(elem, data){
elem.style.setProperty('--move-x', data.x + 'px') data.x != null
elem.style.setProperty('--move-y', data.y + 'px') }, }) && elem.style.setProperty('--move-x', data.x + 'px')
data.y != null
&& elem.style.setProperty('--move-y', data.y + 'px') }, })
return this }, return this },
} }