mirror of
https://github.com/penpot/penpot.git
synced 2025-08-07 14:38:33 +02:00
Implement rotation for shapes.
This commit is contained in:
parent
edc8d25ab3
commit
cab871fc95
4 changed files with 53 additions and 11 deletions
|
@ -175,6 +175,17 @@
|
||||||
(let [shape (get-in state [:shapes-by-id sid])]
|
(let [shape (get-in state [:shapes-by-id sid])]
|
||||||
(update-in state [:shapes-by-id sid] shapes/-move {:dx dx :dy dy})))))
|
(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
|
;; TODO: implement locked resize
|
||||||
|
|
||||||
(defn update-shape-size
|
(defn update-shape-size
|
||||||
|
|
|
@ -45,6 +45,10 @@
|
||||||
dispatch-by-type
|
dispatch-by-type
|
||||||
:hierarchy #'+hierarchy+)
|
:hierarchy #'+hierarchy+)
|
||||||
|
|
||||||
|
(defmulti -rotate
|
||||||
|
dispatch-by-type
|
||||||
|
:hierarchy #'+hierarchy+)
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; Implementation
|
;; Implementation
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
@ -60,3 +64,7 @@
|
||||||
(assoc shape
|
(assoc shape
|
||||||
:width width
|
:width width
|
||||||
:height height))
|
:height height))
|
||||||
|
|
||||||
|
(defmethod -rotate ::shape
|
||||||
|
[shape rotation]
|
||||||
|
(assoc shape :rotation rotation))
|
||||||
|
|
|
@ -1,26 +1,37 @@
|
||||||
(ns uxbox.ui.shapes
|
(ns uxbox.ui.shapes
|
||||||
"A ui related implementation for uxbox.shapes ns."
|
"A ui related implementation for uxbox.shapes ns."
|
||||||
(:require [sablono.core :refer-macros [html]]
|
(:require [sablono.core :refer-macros [html]]
|
||||||
|
[cuerdas.core :as str]
|
||||||
[uxbox.shapes :as shapes]
|
[uxbox.shapes :as shapes]
|
||||||
[uxbox.util.data :refer (remove-nil-vals)]))
|
[uxbox.util.data :refer (remove-nil-vals)]))
|
||||||
|
|
||||||
(defn- transform-attr
|
(defn- transform-attr
|
||||||
[[key value :as pair]]
|
[data [key value :as pair]]
|
||||||
(case key
|
(case key
|
||||||
:view-box [key (apply str (interpose " " value))]
|
:view-box
|
||||||
:lock [:preserveAspectRatio
|
[key (apply str (interpose " " value))]
|
||||||
(if value "xMidYMid" "none")]
|
|
||||||
|
: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))
|
pair))
|
||||||
|
|
||||||
(defn- transform-attrs
|
(defn- transform-attrs
|
||||||
[{:keys [view-box lock] :as data}]
|
[data]
|
||||||
(let [xf (map transform-attr)]
|
(let [xf (map (partial transform-attr data))]
|
||||||
(into {} xf data)))
|
(into {} xf data)))
|
||||||
|
|
||||||
(defn- extract-attrs
|
(defn- extract-attrs
|
||||||
"Extract predefinet attrs from shapes."
|
"Extract predefinet attrs from shapes."
|
||||||
[shape]
|
[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
|
(defmethod shapes/-render :builtin/icon
|
||||||
[{:keys [data id] :as shape} attrs]
|
[{:keys [data id] :as shape} attrs]
|
||||||
|
@ -28,9 +39,11 @@
|
||||||
(extract-attrs $)
|
(extract-attrs $)
|
||||||
(remove-nil-vals $)
|
(remove-nil-vals $)
|
||||||
(merge $ attrs {:lock false})
|
(merge $ attrs {:lock false})
|
||||||
(transform-attrs $))]
|
(transform-attrs $)
|
||||||
|
(merge $ {:key (str id)}))]
|
||||||
(html
|
(html
|
||||||
[:svg (merge attrs {:key (str id)}) data])))
|
[:g attrs
|
||||||
|
[:svg attrs data]])))
|
||||||
|
|
||||||
(defmethod shapes/-render :builtin/icon-svg
|
(defmethod shapes/-render :builtin/icon-svg
|
||||||
[{:keys [image id] :as shape} attrs]
|
[{:keys [image id] :as shape} attrs]
|
||||||
|
|
|
@ -84,8 +84,13 @@
|
||||||
(let [value (dom/event->value event)
|
(let [value (dom/event->value event)
|
||||||
value (parse-int value 0)
|
value (parse-int value 0)
|
||||||
sid (:id shape)]
|
sid (:id shape)]
|
||||||
(println value)
|
|
||||||
(-> (dw/update-shape-size sid {:height 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!))))]
|
(rs/emit!))))]
|
||||||
(html
|
(html
|
||||||
[:div.element-set {:key (str (:id menu))}
|
[:div.element-set {:key (str (:id menu))}
|
||||||
|
@ -123,7 +128,12 @@
|
||||||
|
|
||||||
[:span "Rotation"]
|
[:span "Rotation"]
|
||||||
[:div.row-flex
|
[: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
|
(defn element-opts-render
|
||||||
[own shape]
|
[own shape]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue