diff options
| author | Lars Ingebrigtsen | 2021-11-12 03:27:23 +0100 |
|---|---|---|
| committer | Lars Ingebrigtsen | 2021-11-12 03:31:53 +0100 |
| commit | a204b29d5ba01f382203686929fa367a9baa58d5 (patch) | |
| tree | 320352bc9185dca149728415d5ca7b96a04aed04 | |
| parent | fe0f7bddb648a75d1db4ea574536a207ea881712 (diff) | |
| download | emacs-a204b29d5ba01f382203686929fa367a9baa58d5.tar.gz emacs-a204b29d5ba01f382203686929fa367a9baa58d5.zip | |
Allow stopping animations automatically when the image disappears
* lisp/image.el (image-animate): Allow the animation to be stopped
automatically when the image is removed from the buffer.
(image-animate-timeout): Stop the animation if the image is
removed (and that has been requested).
* lisp/net/shr.el (shr-put-image): Stop animations if the image is
removed.
| -rw-r--r-- | lisp/image.el | 94 | ||||
| -rw-r--r-- | lisp/net/shr.el | 15 |
2 files changed, 65 insertions, 44 deletions
diff --git a/lisp/image.el b/lisp/image.el index a149caa1a97..edbf6c54df6 100644 --- a/lisp/image.el +++ b/lisp/image.el | |||
| @@ -836,15 +836,18 @@ in which case you might want to use `image-default-frame-delay'." | |||
| 836 | 836 | ||
| 837 | (make-obsolete 'image-animated-p 'image-multi-frame-p "24.4") | 837 | (make-obsolete 'image-animated-p 'image-multi-frame-p "24.4") |
| 838 | 838 | ||
| 839 | ;; "Destructively"? | 839 | (defun image-animate (image &optional index limit position) |
| 840 | (defun image-animate (image &optional index limit) | ||
| 841 | "Start animating IMAGE. | 840 | "Start animating IMAGE. |
| 842 | Animation occurs by destructively altering the IMAGE spec list. | 841 | Animation occurs by destructively altering the IMAGE spec list. |
| 843 | 842 | ||
| 844 | With optional INDEX, begin animating from that animation frame. | 843 | With optional INDEX, begin animating from that animation frame. |
| 845 | LIMIT specifies how long to animate the image. If omitted or | 844 | LIMIT specifies how long to animate the image. If omitted or |
| 846 | nil, play the animation until the end. If t, loop forever. If a | 845 | nil, play the animation until the end. If t, loop forever. If a |
| 847 | number, play until that number of seconds has elapsed." | 846 | number, play until that number of seconds has elapsed. |
| 847 | |||
| 848 | If POSITION (which should be buffer position where the image is | ||
| 849 | displayed), stop the animation if the image is no longer | ||
| 850 | displayed." | ||
| 848 | (let ((animation (image-multi-frame-p image)) | 851 | (let ((animation (image-multi-frame-p image)) |
| 849 | timer) | 852 | timer) |
| 850 | (when animation | 853 | (when animation |
| @@ -852,6 +855,9 @@ number, play until that number of seconds has elapsed." | |||
| 852 | (cancel-timer timer)) | 855 | (cancel-timer timer)) |
| 853 | (plist-put (cdr image) :animate-buffer (current-buffer)) | 856 | (plist-put (cdr image) :animate-buffer (current-buffer)) |
| 854 | (plist-put (cdr image) :animate-tardiness 0) | 857 | (plist-put (cdr image) :animate-tardiness 0) |
| 858 | (when position | ||
| 859 | (plist-put (cdr image) :animate-position | ||
| 860 | (set-marker (make-marker) position (current-buffer)))) | ||
| 855 | ;; Stash the data about the animation here so that we don't | 861 | ;; Stash the data about the animation here so that we don't |
| 856 | ;; trigger image recomputation unnecessarily later. | 862 | ;; trigger image recomputation unnecessarily later. |
| 857 | (plist-put (cdr image) :animate-multi-frame-data animation) | 863 | (plist-put (cdr image) :animate-multi-frame-data animation) |
| @@ -925,40 +931,54 @@ for the animation speed. A negative value means to animate in reverse." | |||
| 925 | (plist-put (cdr image) :animate-tardiness | 931 | (plist-put (cdr image) :animate-tardiness |
| 926 | (+ (* (plist-get (cdr image) :animate-tardiness) 0.9) | 932 | (+ (* (plist-get (cdr image) :animate-tardiness) 0.9) |
| 927 | (float-time (time-since target-time)))) | 933 | (float-time (time-since target-time)))) |
| 928 | (when (and (buffer-live-p (plist-get (cdr image) :animate-buffer)) | 934 | (let ((buffer (plist-get (cdr image) :animate-buffer)) |
| 929 | ;; Cumulatively delayed two seconds more than expected. | 935 | (position (plist-get (cdr image) :animate-position))) |
| 930 | (or (< (plist-get (cdr image) :animate-tardiness) 2) | 936 | (when (and (buffer-live-p buffer) |
| 931 | (progn | 937 | ;; If we have a :animate-position setting, the caller |
| 932 | (message "Stopping animation; animation possibly too big") | 938 | ;; has requested that the animation be stopped if the |
| 933 | nil))) | 939 | ;; image is no longer displayed in the buffer. |
| 934 | (image-show-frame image n t) | 940 | (or (null position) |
| 935 | (let* ((speed (image-animate-get-speed image)) | 941 | (with-current-buffer buffer |
| 936 | (time (current-time)) | 942 | (let ((disp (get-text-property position 'display))) |
| 937 | (time-to-load-image (time-since time)) | 943 | (and (consp disp) |
| 938 | (stated-delay-time | 944 | (eq (car disp) 'image) |
| 939 | (/ (or (cdr (plist-get (cdr image) :animate-multi-frame-data)) | 945 | ;; We can't check `eq'-ness of the image |
| 940 | image-default-frame-delay) | 946 | ;; itself, since that may change. |
| 941 | (float (abs speed)))) | 947 | (eq position |
| 942 | ;; Subtract off the time we took to load the image from the | 948 | (plist-get (cdr disp) :animate-position)))))) |
| 943 | ;; stated delay time. | 949 | ;; Cumulatively delayed two seconds more than expected. |
| 944 | (delay (max (float-time (time-subtract stated-delay-time | 950 | (or (< (plist-get (cdr image) :animate-tardiness) 2) |
| 945 | time-to-load-image)) | 951 | (progn |
| 946 | image-minimum-frame-delay)) | 952 | (message "Stopping animation; animation possibly too big") |
| 947 | done) | 953 | nil))) |
| 948 | (setq n (if (< speed 0) | 954 | (image-show-frame image n t) |
| 949 | (1- n) | 955 | (let* ((speed (image-animate-get-speed image)) |
| 950 | (1+ n))) | 956 | (time (current-time)) |
| 951 | (if limit | 957 | (time-to-load-image (time-since time)) |
| 952 | (cond ((>= n count) (setq n 0)) | 958 | (stated-delay-time |
| 953 | ((< n 0) (setq n (1- count)))) | 959 | (/ (or (cdr (plist-get (cdr image) :animate-multi-frame-data)) |
| 954 | (and (or (>= n count) (< n 0)) (setq done t))) | 960 | image-default-frame-delay) |
| 955 | (setq time-elapsed (+ delay time-elapsed)) | 961 | (float (abs speed)))) |
| 956 | (if (numberp limit) | 962 | ;; Subtract off the time we took to load the image from the |
| 957 | (setq done (>= time-elapsed limit))) | 963 | ;; stated delay time. |
| 958 | (unless done | 964 | (delay (max (float-time (time-subtract stated-delay-time |
| 959 | (run-with-timer delay nil #'image-animate-timeout | 965 | time-to-load-image)) |
| 960 | image n count time-elapsed limit | 966 | image-minimum-frame-delay)) |
| 961 | (+ (float-time) delay)))))) | 967 | done) |
| 968 | (setq n (if (< speed 0) | ||
| 969 | (1- n) | ||
| 970 | (1+ n))) | ||
| 971 | (if limit | ||
| 972 | (cond ((>= n count) (setq n 0)) | ||
| 973 | ((< n 0) (setq n (1- count)))) | ||
| 974 | (and (or (>= n count) (< n 0)) (setq done t))) | ||
| 975 | (setq time-elapsed (+ delay time-elapsed)) | ||
| 976 | (if (numberp limit) | ||
| 977 | (setq done (>= time-elapsed limit))) | ||
| 978 | (unless done | ||
| 979 | (run-with-timer delay nil #'image-animate-timeout | ||
| 980 | image n count time-elapsed limit | ||
| 981 | (+ (float-time) delay))))))) | ||
| 962 | 982 | ||
| 963 | 983 | ||
| 964 | (defvar imagemagick-types-inhibit) | 984 | (defvar imagemagick-types-inhibit) |
diff --git a/lisp/net/shr.el b/lisp/net/shr.el index 71c18ff9947..19d324b16f2 100644 --- a/lisp/net/shr.el +++ b/lisp/net/shr.el | |||
| @@ -1174,13 +1174,14 @@ element is the data blob and the second element is the content-type." | |||
| 1174 | (when (and (> (current-column) 0) | 1174 | (when (and (> (current-column) 0) |
| 1175 | (> (car (image-size image t)) 400)) | 1175 | (> (car (image-size image t)) 400)) |
| 1176 | (insert "\n")) | 1176 | (insert "\n")) |
| 1177 | (if (eq size 'original) | 1177 | (let ((image-pos (point))) |
| 1178 | (insert-sliced-image image (or alt "*") nil 20 1) | 1178 | (if (eq size 'original) |
| 1179 | (insert-image image (or alt "*"))) | 1179 | (insert-sliced-image image (or alt "*") nil 20 1) |
| 1180 | (put-text-property start (point) 'image-size size) | 1180 | (insert-image image (or alt "*"))) |
| 1181 | (when (and shr-image-animate | 1181 | (put-text-property start (point) 'image-size size) |
| 1182 | (cdr (image-multi-frame-p image))) | 1182 | (when (and shr-image-animate |
| 1183 | (image-animate image nil 60))) | 1183 | (cdr (image-multi-frame-p image))) |
| 1184 | (image-animate image nil 60 image-pos)))) | ||
| 1184 | image) | 1185 | image) |
| 1185 | (insert (or alt "")))) | 1186 | (insert (or alt "")))) |
| 1186 | 1187 | ||