mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-06-23 15:30:45 -04:00
Implement touch gestures for panning image in popup
This commit is contained in:
parent
7b7d2d44b1
commit
3eecc86589
@ -8,6 +8,8 @@ from ajax import absolute_path
|
|||||||
from dom import add_extra_css, svgicon, unique_id
|
from dom import add_extra_css, svgicon, unique_id
|
||||||
from gettext import gettext as _
|
from gettext import gettext as _
|
||||||
from popups import MODAL_Z_INDEX
|
from popups import MODAL_Z_INDEX
|
||||||
|
from read_book.flow_mode import FlickAnimator
|
||||||
|
from read_book.touch import TouchHandler, install_handlers
|
||||||
from utils import debounce
|
from utils import debounce
|
||||||
|
|
||||||
add_extra_css(def():
|
add_extra_css(def():
|
||||||
@ -44,9 +46,14 @@ def fit_image(width, height, pwidth, pheight):
|
|||||||
return scaled, int(width), int(height)
|
return scaled, int(width), int(height)
|
||||||
|
|
||||||
|
|
||||||
class ImagePopup:
|
class ImagePopup(TouchHandler):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
TouchHandler.__init__(self)
|
||||||
|
self.flick_animator = fa = FlickAnimator()
|
||||||
|
fa.scroll_x = self.scroll_x
|
||||||
|
fa.scroll_y = self.scroll_y
|
||||||
|
fa.cancel_current_drag_scroll = def(): pass
|
||||||
self._container = None
|
self._container = None
|
||||||
self.container_id = unique_id('image-popup')
|
self.container_id = unique_id('image-popup')
|
||||||
self.img = None
|
self.img = None
|
||||||
@ -78,12 +85,12 @@ class ImagePopup:
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
document.body.appendChild(self._container)
|
document.body.appendChild(self._container)
|
||||||
|
install_handlers(self.canvas, self)
|
||||||
window.addEventListener('resize', debounce(self.resize_canvas, 250))
|
window.addEventListener('resize', debounce(self.resize_canvas, 250))
|
||||||
return self._container
|
return self._container
|
||||||
|
|
||||||
def onkeydown(self, ev):
|
def onkeydown(self, ev):
|
||||||
ev.preventDefault(), ev.stopPropagation()
|
ev.preventDefault(), ev.stopPropagation()
|
||||||
console.log(ev.key)
|
|
||||||
if ev.key is ' ':
|
if ev.key is ' ':
|
||||||
return self.toggle_fit_to_window()
|
return self.toggle_fit_to_window()
|
||||||
if ev.key is 'Escape':
|
if ev.key is 'Escape':
|
||||||
@ -101,6 +108,27 @@ class ImagePopup:
|
|||||||
if ev.key is 'ArrowRight':
|
if ev.key is 'ArrowRight':
|
||||||
return self.scroll_right((window.innerWidth - 10) if ev.getModifierState("Control") else 10)
|
return self.scroll_right((window.innerWidth - 10) if ev.getModifierState("Control") else 10)
|
||||||
|
|
||||||
|
def handle_gesture(self, gesture):
|
||||||
|
self.flick_animator.stop()
|
||||||
|
if gesture.type is 'swipe':
|
||||||
|
if not self.img_ok or self.fit_to_window:
|
||||||
|
return
|
||||||
|
if gesture.points.length > 1 and not gesture.is_held:
|
||||||
|
delta = gesture.points[-2] - gesture.points[-1]
|
||||||
|
if Math.abs(delta) >= 1:
|
||||||
|
if gesture.axis is 'vertical':
|
||||||
|
self.scroll_y(delta)
|
||||||
|
else:
|
||||||
|
self.scroll_x(delta)
|
||||||
|
if not gesture.active and not gesture.is_held:
|
||||||
|
self.flick_animator.start(gesture)
|
||||||
|
if gesture.type is 'pinch' and self.img_ok:
|
||||||
|
if gesture.direction is 'in':
|
||||||
|
self.fit_to_window = True
|
||||||
|
else:
|
||||||
|
self.fit_to_window = False
|
||||||
|
self.update_canvas()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def vertical_max_bounce_distance(self):
|
def vertical_max_bounce_distance(self):
|
||||||
return Math.min(60, window.innerHeight / 2)
|
return Math.min(60, window.innerHeight / 2)
|
||||||
@ -151,6 +179,18 @@ class ImagePopup:
|
|||||||
self.x = x
|
self.x = x
|
||||||
self.update_canvas()
|
self.update_canvas()
|
||||||
|
|
||||||
|
def scroll_y(self, amt):
|
||||||
|
if amt < 0:
|
||||||
|
self.scroll_up(-amt)
|
||||||
|
elif amt > 0:
|
||||||
|
self.scroll_down(amt)
|
||||||
|
|
||||||
|
def scroll_x(self, amt):
|
||||||
|
if amt < 0:
|
||||||
|
self.scroll_left(-amt)
|
||||||
|
elif amt > 0:
|
||||||
|
self.scroll_right(amt)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def canvas(self):
|
def canvas(self):
|
||||||
return self.container.getElementsByTagName('canvas')[0]
|
return self.container.getElementsByTagName('canvas')[0]
|
||||||
@ -184,9 +224,11 @@ class ImagePopup:
|
|||||||
self.update_canvas()
|
self.update_canvas()
|
||||||
|
|
||||||
def show_container(self):
|
def show_container(self):
|
||||||
|
self.flick_animator.stop()
|
||||||
self.container.style.display = 'block'
|
self.container.style.display = 'block'
|
||||||
|
|
||||||
def hide_container(self):
|
def hide_container(self):
|
||||||
|
self.flick_animator.stop()
|
||||||
self.container.style.display = 'none'
|
self.container.style.display = 'none'
|
||||||
|
|
||||||
def show_url(self, url):
|
def show_url(self, url):
|
||||||
|
@ -422,8 +422,11 @@ class FlickAnimator:
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.animation_id = None
|
self.animation_id = None
|
||||||
|
|
||||||
def start(self, gesture):
|
def cancel_current_drag_scroll(self):
|
||||||
cancel_drag_scroll()
|
cancel_drag_scroll()
|
||||||
|
|
||||||
|
def start(self, gesture):
|
||||||
|
self.cancel_current_drag_scroll()
|
||||||
self.vertical = gesture.axis is 'vertical'
|
self.vertical = gesture.axis is 'vertical'
|
||||||
now = window.performance.now()
|
now = window.performance.now()
|
||||||
points = times = None
|
points = times = None
|
||||||
@ -449,11 +452,17 @@ class FlickAnimator:
|
|||||||
if abs(delta) >= 1:
|
if abs(delta) >= 1:
|
||||||
delta = Math.round(delta)
|
delta = Math.round(delta)
|
||||||
if self.vertical:
|
if self.vertical:
|
||||||
window.scrollBy(0, delta)
|
self.scroll_y(delta)
|
||||||
else:
|
else:
|
||||||
window.scrollBy(delta, 0)
|
self.scroll_x(delta)
|
||||||
self.animation_id = window.requestAnimationFrame(self.auto_scroll)
|
self.animation_id = window.requestAnimationFrame(self.auto_scroll)
|
||||||
|
|
||||||
|
def scroll_y(self, delta):
|
||||||
|
window.scrollBy(0, delta)
|
||||||
|
|
||||||
|
def scroll_x(self, delta):
|
||||||
|
window.scrollBy(delta, 0)
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
if self.animation_id is not None:
|
if self.animation_id is not None:
|
||||||
window.cancelAnimationFrame(self.animation_id)
|
window.cancelAnimationFrame(self.animation_id)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user