aboutsummaryrefslogtreecommitdiff
path: root/docs/prototypes/gallery-widget.el
diff options
context:
space:
mode:
Diffstat (limited to 'docs/prototypes/gallery-widget.el')
-rw-r--r--docs/prototypes/gallery-widget.el29
1 files changed, 23 insertions, 6 deletions
diff --git a/docs/prototypes/gallery-widget.el b/docs/prototypes/gallery-widget.el
index 5a80e59..543affe 100644
--- a/docs/prototypes/gallery-widget.el
+++ b/docs/prototypes/gallery-widget.el
@@ -49,6 +49,12 @@ a typo'd token must fail loudly, not render black."
"Needle angle at value 0, degrees from vertical (negative = left).")
(defconst gallery-widget--gauge-max-deg 60.0
"Needle angle at value 100.")
+(defconst gallery-widget--gauge-cx 48
+ "Horizontal center of the needle gauge.")
+(defconst gallery-widget--gauge-cy 48
+ "Vertical center and baseline of the needle gauge.")
+(defconst gallery-widget--gauge-radius 47
+ "Outer radius of the needle gauge.")
(defun gallery-widget--clamp-value (value)
"Validate VALUE is a number and clamp it to the gauge's 0-100 range.
@@ -76,27 +82,36 @@ Positive angles swing right, matching the gauge's needle travel."
"Format coordinate N with two decimals for stable, readable SVG output."
(format "%.2f" n))
+(defun gallery-widget--semicircle-path (cx cy radius &optional close)
+ "Return an upper semicircle path centered at (CX, CY) with RADIUS.
+Append a closing segment when CLOSE is non-nil."
+ (format "M %g %g A %g %g 0 0 1 %g %g%s"
+ (- cx radius) cy radius radius (+ cx radius) cy
+ (if close " Z" "")))
+
(defun gallery-widget--node (svg tag &rest attrs)
"Append a TAG element with ATTRS plist to SVG and return it."
(let ((node (dom-node tag
(cl-loop for (k v) on attrs by #'cddr
collect (cons (intern (substring (symbol-name k) 1))
v)))))
- (svg--append svg node)
+ (dom-append-child svg node)
node))
(defun gallery-widget-needle-gauge (value)
"Render the gallery's needle gauge at VALUE (0-100) as an svg.el object.
Geometry mirrors the web card: 96px-wide semicircular dial, pivot at its
bottom center, 40px needle sweeping -60..+60 degrees, readout below."
- (let* ((w 96) (h 64) (cx 48.0) (cy 48.0)
+ (let* ((w 96) (h 64)
+ (cx gallery-widget--gauge-cx)
+ (cy gallery-widget--gauge-cy)
;; clamp once; the angle and the readout render the same value
(value (gallery-widget--clamp-value value))
(angle (gallery-widget--needle-angle value))
(tip (gallery-widget--polar cx cy 40.0 angle))
(svg (svg-create w h :viewBox (format "0 0 %d %d" w h))))
;; glow filter: the SVG equivalent of the web card's box-shadow bloom
- (svg--append
+ (dom-append-child
svg
(dom-node 'defs nil
(dom-node 'filter
@@ -107,13 +122,15 @@ bottom center, 40px needle sweeping -60..+60 degrees, readout below."
(stdDeviation . "2"))))))
;; arc: 2px wash stroke, centerline radius 47 (96px circle, 2px border)
(gallery-widget--node svg 'path
- :d "M 1 48 A 47 47 0 0 1 95 48"
+ :d (gallery-widget--semicircle-path
+ cx cy gallery-widget--gauge-radius)
:fill "none"
:stroke (gallery-widget-token 'wash)
:stroke-width "2")
;; ticks: 8px steel radials at -60 / 0 / +60
(dolist (deg '(-60.0 0.0 60.0))
- (let ((outer (gallery-widget--polar cx cy 47.0 deg))
+ (let ((outer (gallery-widget--polar
+ cx cy gallery-widget--gauge-radius deg))
(inner (gallery-widget--polar cx cy 39.0 deg)))
(gallery-widget--node svg 'line
:class "tick"
@@ -148,7 +165,7 @@ bottom center, 40px needle sweeping -60..+60 degrees, readout below."
;; lower half of its 8px circle; here the dome is drawn directly)
(gallery-widget--node svg 'path
:class "hub"
- :d "M 44 48 A 4 4 0 0 1 52 48 Z"
+ :d (gallery-widget--semicircle-path cx cy 4 t)
:fill (gallery-widget-token 'gold))
;; value readout, matching the web card's cream bold figure
(svg-text svg (format "%d%%" (round value))