diff --git a/resources/public/styles/partials/element-options.scss b/resources/public/styles/partials/element-options.scss index afe979eab..bc976e588 100644 --- a/resources/public/styles/partials/element-options.scss +++ b/resources/public/styles/partials/element-options.scss @@ -211,14 +211,16 @@ height: 100%; justify-content: center; margin: 0 4px; + .color-picker-body { height: 100%; margin-right: 15px; } .color-picker-bar { - height: 100%; + height: 205px; position: relative; width: 15px; + .color-bar-select { background-color: $color-white; height: 3px; diff --git a/src/uxbox/ui/colorpicker.cljs b/src/uxbox/ui/colorpicker.cljs index 2a30afcf5..64dcea409 100644 --- a/src/uxbox/ui/colorpicker.cljs +++ b/src/uxbox/ui/colorpicker.cljs @@ -3,7 +3,8 @@ [rum.core :as rum] [cats.labs.lens :as l] [goog.events :as events] - [uxbox.util.color :refer (rgb->hex)] + [uxbox.util.color :as color] + [uxbox.util.math :as mth] [uxbox.ui.mixins :as mx]) (:import goog.events.EventType)) @@ -11,49 +12,120 @@ ;; Color Picker ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(defn on-click-handler - [e own callback] - (let [canvas (mx/get-ref-dom own "colorpicker") - context (.getContext canvas "2d") +(defn- get-mouse-pos + [own ref event] + (let [canvas (mx/get-ref-dom own ref) brect (.getBoundingClientRect canvas) - x (- (.-pageX e) (.-left brect)) - y (- (.-pageY e) (.-top brect)) + x (- (.-clientX event) (.-left brect)) + y (- (.-clientY event) (.-top brect))] + [x y])) + +(defn- get-color + [own ref [x y]] + (let [canvas (mx/get-ref-dom own ref) + context (.getContext canvas "2d") image (.getImageData context x y 1 1) r (aget (.-data image) 0) g (aget (.-data image) 1) b (aget (.-data image) 2)] - (callback {:hex (rgb->hex [r g b]) - :rgb [r g b]}))) + (println [r g b]) + (color/rgb->hex [r g b]))) -(defn colorpicker-render +(defn- colorpicker-render [own callback] - (html - [:section.colorpicker - [:canvas - {:width "400" - :height "300" - :on-click #(on-click-handler % own callback) - :id "colorpicker" - :ref "colorpicker"}]])) + (let [local (:rum/local own) + bar-pos (:pos @local 0)] + (letfn [(on-bar-mouse-down [event]) + (on-bar-mouse-up [event]) + (on-picker-click [event] + (let [[x y :as pos] (get-mouse-pos own "colorpicker" event) + color (get-color own "colorpicker" pos)] + (callback {:hex color + :rgb (color/hex->rgb color)}))) + (on-bar-click [event] + (let [[x y :as pos] (get-mouse-pos own "colorbar" event) + color (get-color own "colorbar" pos) + pos (/ (* 100 y) 205)] + (swap! local assoc :pos pos :color color)))] + (html + [:div.element-color-picker + [:div.color-picker-body + [:canvas {:ref "colorpicker" + :on-click on-picker-click + :style {:border "1px solid #AAA"} + :width "205" + :height "205" + :id "colorpicker"}]] + [:div.color-picker-bar + [:div.color-bar-select {:style {:top (str bar-pos "%")} + :on-mouse-down on-bar-mouse-down + :on-mouse-up on-bar-mouse-up}] + [:canvas {:ref "colorbar" + :on-click on-bar-click + :width "15" + :height "205"}]]])))) + +(defn- draw-color-gradient + [context color] + (let [gradient1 (.createLinearGradient context 0, 102.5, 205, 102.5) + gradient2 (.createLinearGradient context 102.5, 205, 105, 0)] + + ;; Draw plain color + (set! (.-fillStyle context) color) + (.fillRect context 0 0 205 205) + + ;; Transparency gradient + (.addColorStop gradient2 0 "rgba(255,255,255,1)") + (.addColorStop gradient2 1 "rgba(0,0,0,0)") + + (set! (.-fillStyle context) gradient2) + (.fillRect context 0 0 205 205) + + ;; Color gradient + (.addColorStop gradient1 0 "rgba(0,0,0,1)") + (.addColorStop gradient1 0.8 "rgba(0,0,0,0)") + + (set! (.-fillStyle context) gradient1) + (.fillRect context 0 0 205 205))) (defn colorpicker-did-mount [own] - (let [canvas (mx/get-ref-dom own "colorpicker") - context (.getContext canvas "2d") - img (js/Image.)] - (set! (.-src img) "/images/colorspecrum-400x300.png") - (let [key (events/listen img EventType.LOAD #(.drawImage context img 0 0))] + (let [canvas1 (mx/get-ref-dom own "colorpicker") + context1 (.getContext canvas1 "2d") + canvas2 (mx/get-ref-dom own "colorbar") + context2 (.getContext canvas2 "2d") + img (js/Image.) + local (:rum/local own)] + + (add-watch local ::key + (fn [_ _ o v] + (println "add-watch" o v) + (when (not= (:color o) (:color v)) + (draw-color-gradient context1 (:color v))))) + + (draw-color-gradient context1 "#FF0000") + + (set! (.-src img) "/images/color-bar.png") + (let [key (events/listen img EventType.LOAD #(.drawImage context2 img 0 0))] (assoc own ::key key)))) (defn colorpicker-will-unmout [own] - (let [key (::key own)] + (let [key (::key own) + local (:rum/local own)] + (remove-watch local ::key) (events/unlistenByKey key))) +(defn- colorpicker-transfer-state + [old-own own] + (let [key (::key old-own)] + (assoc own ::key key))) + (def ^:static colorpicker (mx/component {:render colorpicker-render :did-mount colorpicker-did-mount :will-unmout colorpicker-will-unmout + :transfer-state colorpicker-transfer-state :name "colorpicker" - :mixins [mx/static]})) + :mixins [mx/static (mx/local)]})) diff --git a/src/uxbox/ui/dashboard/colors.cljs b/src/uxbox/ui/dashboard/colors.cljs index 933e4cc72..e99878340 100644 --- a/src/uxbox/ui/dashboard/colors.cljs +++ b/src/uxbox/ui/dashboard/colors.cljs @@ -188,17 +188,11 @@ :on-change on-change :value (or (:hex @local) color "") :type "text"}]] - [:div.element-color-picker - [:div.color-picker-body - [:img {:src "images/color-gamma.png", :border "none"}]] - [:div.color-picker-bar - [:div.color-bar-select] - [:img {:src "images/color-bar.png", :border "none"}]]] (colorpicker #(swap! local merge %)) [:input#project-btn.btn-primary {:value "+ Add color" :on-click submit - :type "submit"}]] + :type "button"}]] [:a.close {:on-click #(lightbox/close!)} i/close]]))))