emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[nongnu] elpa/scroll-on-jump 222f9c1d33: Add support for ease-in and eas


From: ELPA Syncer
Subject: [nongnu] elpa/scroll-on-jump 222f9c1d33: Add support for ease-in and ease-out curves
Date: Mon, 23 Jan 2023 21:00:40 -0500 (EST)

branch: elpa/scroll-on-jump
commit 222f9c1d33659bc367a1b507a68c0df73f9e3db8
Author: Campbell Barton <ideasman42@gmail.com>
Commit: Campbell Barton <ideasman42@gmail.com>

    Add support for ease-in and ease-out curves
    
    Also add scroll-on-jump-curve-power to control the strength of the curve.
---
 changelog.rst     |  3 ++
 readme.rst        | 20 +++++++++---
 scroll-on-jump.el | 91 ++++++++++++++++++++++++++++++++++++++++---------------
 3 files changed, 86 insertions(+), 28 deletions(-)

diff --git a/changelog.rst b/changelog.rst
index b336034ab1..7c32d6bb86 100644
--- a/changelog.rst
+++ b/changelog.rst
@@ -3,6 +3,9 @@
 Change Log
 ##########
 
+  - Add ``scroll-on-jump-curve`` & ``scroll-on-jump-curve-power``
+    to support different kinds of curves & control their strength.
+
 - Version 0.2 (2023-01-22)
 
   - Add ``scroll-on-jump-mode-line-format`` to support overriding the 
mode-line while scrolling.
diff --git a/readme.rst b/readme.rst
index a4af4efebf..9df3920e2a 100644
--- a/readme.rst
+++ b/readme.rst
@@ -162,13 +162,25 @@ Customization
 
 While the defaults seem to work well, these values can be customized.
 
-``scroll-on-jump-duration``: 0.4
+``scroll-on-jump-duration``: ``0.4``
    The duration for jumping to take, set to ``0.0`` to jump immediately.
-``scroll-on-jump-smooth``: t
+``scroll-on-jump-smooth``: ``t``
    When not nil, use smooth scrolling (by pixels).
-``scroll-on-jump-use-curve``: t
+``scroll-on-jump-curve``: ``'smooth``
    Apply a curve to the scroll speed, starting and ending slow.
-``scroll-on-jump-mode-line-format``: nil
+
+   :'smooth: Ease in/out.
+   :'smooth-in: Ease in (end slow).
+   :'smooth-out: Ease in (start slow).
+   :'linear: Linear motion (no easing).
+``scroll-on-jump-curve-power``: ``3.0``
+   The strength of the curve (when non-linear).
+
+   Values between 2 and 8 work well.
+
+   - Below 2.0 approaches a linear curve.
+   - Above 8.0 can make the motion overly abrupt.
+``scroll-on-jump-mode-line-format``: ``nil``
    When non-nil, use this value for the ``mode-line-format`` while scrolling.
    This can be used to temporarily override the mode-line while scrolling.
    It can also help to avoid overly complex mode-lines from slowing down 
scrolling.
diff --git a/scroll-on-jump.el b/scroll-on-jump.el
index 0bc11ebbdf..6cb9006caf 100644
--- a/scroll-on-jump.el
+++ b/scroll-on-jump.el
@@ -40,9 +40,19 @@
   "Use smooth (pixel) scrolling, otherwise scroll by lines."
   :type 'boolean)
 
-(defcustom scroll-on-jump-use-curve t
-  "Apply a curve to the scroll speed, starting and ending slow."
-  :type 'boolean)
+(defcustom scroll-on-jump-curve 'smooth
+  "The the method scrolling is calculated."
+  :type
+  '(choice
+    (const :tag "Smooth in/out, starts & ends slow" smooth)
+    (const :tag "Smooth in, starts slow" smooth-in)
+    (const :tag "Smooth out, ends slow" smooth-out)
+    (const :tag "Linear" linear)))
+
+(defcustom scroll-on-jump-curve-power 3.0
+  "The strength of the curve (when set to linear).
+A value of 1.0 is linear, values between 2 and 8 work well."
+  :type 'float)
 
 (defcustom scroll-on-jump-mode-line-format nil
   "The `mode-line-format' to use or nil to leave the `mode-line-format' 
unchanged.
@@ -135,10 +145,6 @@ Argument ALSO-MOVE-POINT When non-nil, move the POINT as 
well."
    (t
     (cons 0 0))))
 
-(defun scroll-on-jump--interpolate-ease (a b factor)
-  "Blend FACTOR between A and B using ease style curvature."
-  (+ a (* (- b a) (- (* 3.0 factor factor) (* 2.0 factor factor factor)))))
-
 (defsubst scroll-on-jump--evil-visual-mode-workaround ()
   "Workaround for `evil-mode' line-mode."
   ;; Without this, the line mode point jumps back to the origin,
@@ -155,8 +161,57 @@ Argument ALSO-MOVE-POINT When non-nil, move the POINT as 
well."
 
 
 ;; ---------------------------------------------------------------------------
-;; Internal Logic
+;; Internal Interpolation Functions
+
+(defsubst scroll-on-jump--interp-linear-impl (a b factor)
+  "Internal macro for to blend A, B by FACTOR."
+  (+ a (* (- b a) factor)))
 
+(defun scroll-on-jump--interp-linear (a b factor)
+  "Blend FACTOR between A and B using linear curvature."
+  (scroll-on-jump--interp-linear-impl a b factor))
+
+(defun scroll-on-jump--interp-ease-in (a b factor)
+  "Blend FACTOR between A and B using ease-in curvature."
+  (scroll-on-jump--interp-linear-impl a b (expt factor 
scroll-on-jump-curve-power)))
+
+(defun scroll-on-jump--interp-ease-out (a b factor)
+  "Blend FACTOR between A and B using ease-in curvature."
+  (scroll-on-jump--interp-linear-impl
+   a b (- 1.0 (expt (- 1.0 factor) scroll-on-jump-curve-power))))
+
+(defun scroll-on-jump--interp-ease-in-out (a b factor)
+  "Blend FACTOR between A and B using ease-in-out curvature."
+  (cond
+   ((< factor 0.5)
+    (let ((f (* (expt (* factor 2.0) scroll-on-jump-curve-power) 0.5)))
+      (scroll-on-jump--interp-linear-impl a b f)))
+   (t
+    (let ((f (- 1.0 (* (expt (* (- 1.0 factor) 2.0) 
scroll-on-jump-curve-power) 0.5))))
+      (scroll-on-jump--interp-linear-impl a b f)))))
+
+(defun scroll-on-jump--interp-fn-get (curve)
+  "Return the interpolation function associated with CURVE."
+  (cond
+   ((<= scroll-on-jump-curve-power 1.0)
+    ;; A curve of 1.0 is linear by definition,
+    ;; also catches users entering in bad values (negative numbers for e.g.)
+    ;; that will only cause problems.
+    #'scroll-on-jump--interp-linear)
+   (t
+    (pcase curve
+      ('linear #'scroll-on-jump--interp-linear)
+      ('smooth #'scroll-on-jump--interp-ease-in-out)
+      ('smooth-in #'scroll-on-jump--interp-ease-in)
+      ('smooth-out #'scroll-on-jump--interp-ease-out)
+      (_
+       (message "Unknown curve (%S), using linear" curve)
+       ;; Fall back to linear (as good an option as any).
+       #'scroll-on-jump--interp-linear)))))
+
+
+;; ---------------------------------------------------------------------------
+;; Internal Logic
 
 (defun scroll-on-jump--immediate-scroll (window lines-scroll _dir)
   "Non animated scroll for WINDOW to move LINES-SCROLL."
@@ -171,7 +226,7 @@ Moving the point when ALSO-MOVE-POINT is set."
         (time-limit
          (* scroll-on-jump-duration
             (min 1.0 (/ (float (abs lines-scroll)) (float (window-body-height 
window))))))
-        (use-curve scroll-on-jump-use-curve))
+        (interp-fn (scroll-on-jump--interp-fn-get scroll-on-jump-curve)))
 
     ;; Animated scrolling (early exit on input to avoid annoying lag).
     (cond
@@ -188,13 +243,7 @@ Moving the point when ALSO-MOVE-POINT is set."
                   (step
                    (let* ((time-elapsed (float-time (time-subtract 
(current-time) time-init)))
                           (factor (min 1.0 (/ time-elapsed time-limit)))
-                          (lines-target
-                           (floor
-                            (cond
-                             (use-curve
-                              (scroll-on-jump--interpolate-ease 0.0 
lines-scroll-abs factor))
-                             (t
-                              (* lines-scroll-abs factor)))))
+                          (lines-target (floor (funcall interp-fn 0.0 
lines-scroll-abs factor)))
                           (lines-remainder (- lines-target lines-done-abs)))
                      ;; Step result, we must move at least one line.
                      (* dir (max 1 lines-remainder)))))
@@ -242,7 +291,7 @@ Argument ALSO-MOVE-POINT moves the point while scrolling."
         (time-limit
          (* scroll-on-jump-duration
             (min 1.0 (/ (float (abs lines-scroll)) (float (window-body-height 
window))))))
-        (use-curve scroll-on-jump-use-curve)
+        (interp-fn (scroll-on-jump--interp-fn-get scroll-on-jump-curve))
         (char-height (frame-char-height (window-frame window))))
 
     ;; Animated scrolling (early exit on input to avoid annoying lag).
@@ -270,13 +319,7 @@ Argument ALSO-MOVE-POINT moves the point while scrolling."
                   (step
                    (let* ((time-elapsed (float-time (time-subtract 
(current-time) time-init)))
                           (factor (min 1.0 (/ time-elapsed time-limit)))
-                          (px-target
-                           (floor
-                            (cond
-                             (use-curve
-                              (scroll-on-jump--interpolate-ease 0.0 
px-scroll-abs factor))
-                             (t
-                              (* px-scroll-abs factor)))))
+                          (px-target (floor (funcall interp-fn 0.0 
px-scroll-abs factor)))
                           (px-remainder (- px-target px-done-abs)))
                      (* dir px-remainder))))
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]