🐛 Clamp gradient stop offsets to valid range (#10881)

* 🐛 Clamp gradient stop offsets to valid [0, 1] range

Fixed a bug where gradient stop offsets outside the valid [0, 1] range were being sent to the server, causing schema validation errors ('invalid shape found').

Changes:
- Viewport gradient handler: clamp offset in points-on-pointer-down before creating new stops
- Colorpicker gradient preview: clamp offset in handle-preview-down before adding stops
- Data layer: clamp offset parameter in update-colorpicker-add-stop and all stop offsets in update-colorpicker-stops; added app.common.math require

All clamping follows the existing pattern used in handle-marker-pointer-move.

AI-assisted-by: deepseek-v4-flash

* 💄 Fix formatting in gradient handlers

Fix cljfmt formatting issues in gradient handler functions.

AI-assisted-by: qwen3.7-plus
This commit is contained in:
Andrey Antukh 2026-07-30 12:49:00 +02:00 committed by GitHub
parent 25618febcd
commit fadb3124a0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 8 additions and 3 deletions

View File

@ -9,6 +9,7 @@
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.files.helpers :as cfh]
[app.common.math :as mth]
[app.common.schema :as sm]
[app.common.types.color :as clr]
[app.common.types.fills :as types.fills]
@ -950,7 +951,8 @@
(or (not cap-stops?) (< (count stops) types.fills/MAX-GRADIENT-STOPS))]
(if can-add-stop?
(let [new-stop (-> (clr/interpolate-gradient stops offset)
(let [offset (mth/clamp offset 0 1)
new-stop (-> (clr/interpolate-gradient stops offset)
(split-color-components))
stops (conj stops new-stop)
stops (into [] (sort-by :offset stops))
@ -973,7 +975,8 @@
stops (mapv split-color-components
(if cap-stops?
(take types.fills/MAX-GRADIENT-STOPS stops)
stops))]
stops))
stops (mapv #(update % :offset (fn [o] (mth/clamp o 0 1))) stops)]
(-> state
(assoc :current-color (get stops stop))
(assoc :stops stops))))))))

View File

@ -121,7 +121,7 @@
delta (if prev-t
(str "(+" (ct/diff-ms prev-t t) "ms)")
"(+0ms)")
delta-pad (str/pad delta {:length 10 :type :right})]
delta-pad (str/pad delta {:length 10 :type :right})]
(recur t
(next xs)
(conj! out (str iso " " delta-pad " " name))))

View File

@ -233,6 +233,7 @@
(mf/deps on-add-stop-preview)
(fn [^js e]
(let [offset (-> (event->offset e)
(mth/clamp 0 1)
(mth/precision 2))]
(when on-add-stop-preview
(on-add-stop-preview offset)))))

View File

@ -189,6 +189,7 @@
lv (-> (gpt/to-vec from-p to-p) (gpt/unit))
nv (gpt/normal-left lv)
offset (-> (gsp/project-t position [from-p to-p] nv)
(mth/clamp 0 1)
(mth/precision 2))
new-stop (cc/interpolate-gradient stops offset)
stops (conj stops new-stop)