diff --git a/frontend/uxbox/data/workspace.cljs b/frontend/uxbox/data/workspace.cljs index aea5f0c0c8..d656c57774 100644 --- a/frontend/uxbox/data/workspace.cljs +++ b/frontend/uxbox/data/workspace.cljs @@ -175,6 +175,17 @@ (let [shape (get-in state [:shapes-by-id sid])] (update-in state [:shapes-by-id sid] shapes/-move {:dx dx :dy dy}))))) +(defn update-shape-rotation + [sid rotation] + {:pre [(number? rotation) + (>= rotation 0) + (>= 360 rotation)]} + (reify + rs/UpdateEvent + (-apply-update [_ state] + (update-in state [:shapes-by-id sid] + shapes/-rotate rotation)))) + ;; TODO: implement locked resize (defn update-shape-size diff --git a/frontend/uxbox/shapes.cljs b/frontend/uxbox/shapes.cljs index bfaf33f2f0..57241d9e51 100644 --- a/frontend/uxbox/shapes.cljs +++ b/frontend/uxbox/shapes.cljs @@ -45,6 +45,10 @@ dispatch-by-type :hierarchy #'+hierarchy+) +(defmulti -rotate + dispatch-by-type + :hierarchy #'+hierarchy+) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Implementation ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -60,3 +64,7 @@ (assoc shape :width width :height height)) + +(defmethod -rotate ::shape + [shape rotation] + (assoc shape :rotation rotation)) diff --git a/frontend/uxbox/ui/shapes.cljs b/frontend/uxbox/ui/shapes.cljs index 3b53bf8627..f4b673c6da 100644 --- a/frontend/uxbox/ui/shapes.cljs +++ b/frontend/uxbox/ui/shapes.cljs @@ -1,26 +1,37 @@ (ns uxbox.ui.shapes "A ui related implementation for uxbox.shapes ns." (:require [sablono.core :refer-macros [html]] + [cuerdas.core :as str] [uxbox.shapes :as shapes] [uxbox.util.data :refer (remove-nil-vals)])) (defn- transform-attr - [[key value :as pair]] + [data [key value :as pair]] (case key - :view-box [key (apply str (interpose " " value))] - :lock [:preserveAspectRatio - (if value "xMidYMid" "none")] + :view-box + [key (apply str (interpose " " value))] + + :lock + [:preserveAspectRatio (if value "xMidYMid" "none")] + + :rotation + (let [width (nth (:view-box data) 3) + center-x (+ (:x data) (/ (:width data) 2)) + center-y (+ (:y data) (/ (:height data) 2))] + [:transform (str/format "rotate(%s %s %s)" value center-x center-y)]) + pair)) (defn- transform-attrs - [{:keys [view-box lock] :as data}] - (let [xf (map transform-attr)] + [data] + (let [xf (map (partial transform-attr data))] (into {} xf data))) (defn- extract-attrs "Extract predefinet attrs from shapes." [shape] - (select-keys shape [:lock :width :height :view-box :x :y :cx :cy])) + (select-keys shape [:rotation :lock :width :height + :view-box :x :y :cx :cy])) (defmethod shapes/-render :builtin/icon [{:keys [data id] :as shape} attrs] @@ -28,9 +39,11 @@ (extract-attrs $) (remove-nil-vals $) (merge $ attrs {:lock false}) - (transform-attrs $))] + (transform-attrs $) + (merge $ {:key (str id)}))] (html - [:svg (merge attrs {:key (str id)}) data]))) + [:g attrs + [:svg attrs data]]))) (defmethod shapes/-render :builtin/icon-svg [{:keys [image id] :as shape} attrs] diff --git a/frontend/uxbox/ui/workspace/options.cljs b/frontend/uxbox/ui/workspace/options.cljs index b299b251b1..d532895711 100644 --- a/frontend/uxbox/ui/workspace/options.cljs +++ b/frontend/uxbox/ui/workspace/options.cljs @@ -84,8 +84,13 @@ (let [value (dom/event->value event) value (parse-int value 0) sid (:id shape)] - (println value) (-> (dw/update-shape-size sid {:height value}) + (rs/emit!)))) + (on-rotation-change [event] + (let [value (dom/event->value event) + value (parse-int value 0) + sid (:id shape)] + (-> (dw/update-shape-rotation sid value) (rs/emit!))))] (html [:div.element-set {:key (str (:id menu))} @@ -123,7 +128,12 @@ [:span "Rotation"] [:div.row-flex - [:input.slidebar {:type "range"}]]]]))) + [:input.slidebar + {:type "range" + :min 0 + :max 360 + :value (:rotation shape 0) + :on-change on-rotation-change}]]]]))) (defn element-opts-render [own shape]