diff --git a/src/pyj/image_popup.pyj b/src/pyj/image_popup.pyj index 00cb45204a..9ec425fd47 100644 --- a/src/pyj/image_popup.pyj +++ b/src/pyj/image_popup.pyj @@ -8,6 +8,8 @@ from ajax import absolute_path from dom import add_extra_css, svgicon, unique_id from gettext import gettext as _ 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 add_extra_css(def(): @@ -44,9 +46,14 @@ def fit_image(width, height, pwidth, pheight): return scaled, int(width), int(height) -class ImagePopup: +class ImagePopup(TouchHandler): 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_id = unique_id('image-popup') self.img = None @@ -78,12 +85,12 @@ class ImagePopup: ), ) document.body.appendChild(self._container) + install_handlers(self.canvas, self) window.addEventListener('resize', debounce(self.resize_canvas, 250)) return self._container def onkeydown(self, ev): ev.preventDefault(), ev.stopPropagation() - console.log(ev.key) if ev.key is ' ': return self.toggle_fit_to_window() if ev.key is 'Escape': @@ -101,6 +108,27 @@ class ImagePopup: if ev.key is 'ArrowRight': 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 def vertical_max_bounce_distance(self): return Math.min(60, window.innerHeight / 2) @@ -151,6 +179,18 @@ class ImagePopup: self.x = x 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 def canvas(self): return self.container.getElementsByTagName('canvas')[0] @@ -184,9 +224,11 @@ class ImagePopup: self.update_canvas() def show_container(self): + self.flick_animator.stop() self.container.style.display = 'block' def hide_container(self): + self.flick_animator.stop() self.container.style.display = 'none' def show_url(self, url): diff --git a/src/pyj/read_book/flow_mode.pyj b/src/pyj/read_book/flow_mode.pyj index d01c367df7..1354c44b5e 100644 --- a/src/pyj/read_book/flow_mode.pyj +++ b/src/pyj/read_book/flow_mode.pyj @@ -422,8 +422,11 @@ class FlickAnimator: def __init__(self): self.animation_id = None - def start(self, gesture): + def cancel_current_drag_scroll(self): cancel_drag_scroll() + + def start(self, gesture): + self.cancel_current_drag_scroll() self.vertical = gesture.axis is 'vertical' now = window.performance.now() points = times = None @@ -449,11 +452,17 @@ class FlickAnimator: if abs(delta) >= 1: delta = Math.round(delta) if self.vertical: - window.scrollBy(0, delta) + self.scroll_y(delta) else: - window.scrollBy(delta, 0) + self.scroll_x(delta) 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): if self.animation_id is not None: window.cancelAnimationFrame(self.animation_id)