0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-02-08 08:09:14 -05:00

🐛 Fix color wrapper choppiness (#5655)

* ♻️ Remove unused state om tokens colorpicker ramp component

* 🐛 Fix color wrapper choppiness

*  Add performance related changes for colorpicker ramp selector

*  Add performance oriented changes to tokens ramp component

---------

Co-authored-by: Andrey Fedorov <oran9e.red@gmail.com>
This commit is contained in:
Andrey Antukh 2025-01-24 09:37:11 +01:00 committed by GitHub
parent cf25614afb
commit 32f0da7514
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 105 additions and 57 deletions

View file

@ -248,11 +248,12 @@
[[h s brightness]]
(if (= s 0)
[brightness brightness brightness]
(let [sextant (int (mth/floor (/ h 60)))
remainder (- (/ h 60) sextant)
val1 (int (* brightness (- 1 s)))
val2 (int (* brightness (- 1 (* s remainder))))
val3 (int (* brightness (- 1 (* s (- 1 remainder)))))]
(let [sextant (int (mth/floor (/ h 60)))
remainder (- (/ h 60) sextant)
brightness (d/nilv brightness 0)
val1 (int (* brightness (- 1 s)))
val2 (int (* brightness (- 1 (* s remainder))))
val3 (int (* brightness (- 1 (* s (- 1 remainder)))))]
(case sextant
1 [val2 brightness val1]
2 [val1 brightness val3]

View file

@ -33,7 +33,7 @@
[app.main.ui.workspace.colorpicker.harmony :refer [harmony-selector]]
[app.main.ui.workspace.colorpicker.hsva :refer [hsva-selector]]
[app.main.ui.workspace.colorpicker.libraries :refer [libraries]]
[app.main.ui.workspace.colorpicker.ramp :refer [ramp-selector]]
[app.main.ui.workspace.colorpicker.ramp :refer [ramp-selector*]]
[app.main.ui.workspace.colorpicker.shortcuts :as sc]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]]
@ -346,7 +346,7 @@
[:div {:class (stl/css :picker-detail-wrapper)}
[:div {:class (stl/css :center-circle)}]
[:canvas#picker-detail {:class (stl/css :picker-detail) :width 256 :height 140}]]
[:& ramp-selector
[:> ramp-selector*
{:color current-color
:disable-opacity disable-opacity
:on-change handle-change-color

View file

@ -8,6 +8,7 @@
(:require-macros [app.main.style :as stl])
(:require
[app.common.colors :as cc]
[app.common.data :as d]
[app.common.math :as mth]
[app.main.ui.components.color-bullet :as cb]
[app.main.ui.workspace.colorpicker.slider-selector :refer [slider-selector]]
@ -51,48 +52,82 @@
:top (str (* 100 (- 1 (/ value 255))) "%")}}]]))
(mf/defc ramp-selector [{:keys [color disable-opacity on-change on-start-drag on-finish-drag]}]
(let [{hex :hex
hue :h saturation :s value :v alpha :alpha} color
(defn- enrich-color-map
[{:keys [h s v] :as color}]
(let [h (d/nilv h 0)
s (d/nilv s 0)
v (d/nilv v 0)
hsv [h s v]
[r g b] (cc/hsv->rgb hsv)]
(assoc color
:hex (cc/hsv->hex hsv)
:h h :s s :v v
:r r :g g :b b)))
(mf/defc ramp-selector*
[{:keys [color disable-opacity on-change on-start-drag on-finish-drag]}]
(let [internal-color*
(mf/use-state #(enrich-color-map color))
internal-color
(deref internal-color*)
h (get internal-color :h)
s (get internal-color :s)
v (get internal-color :v)
hex (get internal-color :hex)
alpha (get internal-color :alpha)
bullet-color
(mf/with-memo [hex alpha]
{:color hex :opacity alpha})
on-change-value-saturation
(fn [new-saturation new-value]
(let [hex (cc/hsv->hex [hue new-saturation new-value])
[r g b] (cc/hex->rgb hex)]
(on-change {:hex hex
:r r :g g :b b
:s new-saturation
:v new-value})))
(mf/use-fn
(mf/deps internal-color on-change)
(fn [saturation value]
(let [color (-> internal-color
(assoc :s saturation)
(assoc :v value)
(enrich-color-map))]
(reset! internal-color* color)
(on-change color))))
on-change-hue
(fn [new-hue]
(let [hex (cc/hsv->hex [new-hue saturation value])
[r g b] (cc/hex->rgb hex)]
(on-change {:hex hex
:r r :g g :b b
:h new-hue})))
(mf/use-fn
(mf/deps internal-color on-change)
(fn [hue]
(let [color (-> internal-color
(assoc :h hue)
enrich-color-map)]
(reset! internal-color* color)
(on-change color))))
on-change-opacity
(fn [new-opacity]
(on-change {:alpha new-opacity}))]
(mf/use-fn
(mf/deps internal-color on-change)
(fn [opacity]
(let [color (assoc internal-color :alpha opacity)]
(reset! internal-color* color)
(on-change color))))]
[:*
[:& value-saturation-selector
{:hue hue
:saturation saturation
:value value
{:hue h
:saturation s
:value v
:on-change on-change-value-saturation
:on-start-drag on-start-drag
:on-finish-drag on-finish-drag}]
[:div {:class (stl/css :shade-selector)
:style #js {"--bullet-size" "52px"}}
[:& cb/color-bullet {:color {:color hex
:opacity alpha}
:style {:--bullet-size "52px"}}
[:& cb/color-bullet {:color bullet-color
:area true}]
[:div {:class (stl/css :sliders-wrapper)}
[:& slider-selector {:type :hue
:max-value 360
:value hue
:value h
:on-change on-change-hue
:on-start-drag on-start-drag
:on-finish-drag on-finish-drag}]

View file

@ -19,7 +19,7 @@
[app.main.ui.ds.foundations.typography.heading :refer [heading*]]
[app.main.ui.ds.foundations.typography.text :refer [text*]]
[app.main.ui.workspace.colorpicker :as colorpicker]
[app.main.ui.workspace.colorpicker.ramp :refer [ramp-selector]]
[app.main.ui.workspace.colorpicker.ramp :refer [ramp-selector*]]
[app.main.ui.workspace.tokens.components.controls.input-token-color-bullet :refer [input-token-color-bullet*]]
[app.main.ui.workspace.tokens.components.controls.input-tokens :refer [input-tokens*]]
[app.main.ui.workspace.tokens.errors :as wte]
@ -156,31 +156,43 @@
(defonce form-token-cache-atom (atom nil))
(mf/defc ramp
(defn hex->value
[hex]
(when-let [tc (tinycolor/valid-color hex)]
(let [hex (str "#" (tinycolor/->hex tc))
[r g b] (c/hex->rgb hex)
[h s v] (c/hex->hsv hex)]
{:hex hex
:r r :g g :b b
:h h :s s :v v
:alpha 1})))
(mf/defc ramp*
[{:keys [color on-change]}]
(let [wrapper-node-ref (mf/use-ref nil)
dragging? (mf/use-state)
hex->value (fn [hex]
(when-let [tc (tinycolor/valid-color hex)]
(let [hex (str "#" (tinycolor/->hex tc))
[r g b] (c/hex->rgb hex)
[h s v] (c/hex->hsv hex)]
{:hex hex
:r r :g g :b b
:h h :s s :v v
:alpha 1})))
value (mf/use-state (hex->value color))
on-change' (fn [{:keys [hex]}]
(reset! value (hex->value hex))
(when-not (and @dragging? hex)
(on-change hex)))]
(colorpicker/use-color-picker-css-variables! wrapper-node-ref @value)
dragging-ref (mf/use-ref false)
on-start-drag
(mf/use-fn #(mf/set-ref-val! dragging-ref true))
on-finish-drag
(mf/use-fn #(mf/set-ref-val! dragging-ref false))
on-change'
(mf/use-fn
(mf/deps on-change)
(fn [{:keys [hex]}]
(let [dragging? (mf/ref-val dragging-ref)]
(when-not (and dragging? hex)
(on-change hex)))))]
(colorpicker/use-color-picker-css-variables! wrapper-node-ref (hex->value color))
[:div {:ref wrapper-node-ref}
[:& ramp-selector
{:color @value
[:> ramp-selector*
{:color (hex->value color)
:disable-opacity true
:on-start-drag #(reset! dragging? true)
:on-finish-drag #(reset! dragging? false)
:on-start-drag on-start-drag
:on-finish-drag on-finish-drag
:on-change on-change'}]]))
(mf/defc token-value-or-errors
@ -419,9 +431,9 @@
[:> input-token-color-bullet*
{:color @color :on-click on-display-colorpicker}])]
(when @color-ramp-open?
[:& ramp {:color (some-> (or @token-resolve-result (:value token))
(tinycolor/valid-color))
:on-change on-update-color}])
[:> ramp* {:color (some-> (or @token-resolve-result (:value token))
(tinycolor/valid-color))
:on-change on-update-color}])
[:& token-value-or-errors {:result-or-errors @token-resolve-result}]]
[:div {:class (stl/css :input-row)}