mirror of
https://github.com/penpot/penpot.git
synced 2025-05-17 22:36:11 +02:00
Merge pull request #624 from penpot/feature/flip
Adds flip vertical/horizontal commands
This commit is contained in:
commit
8e5fd5892e
13 changed files with 181 additions and 120 deletions
|
@ -4805,5 +4805,19 @@
|
|||
"es" : "Pulsar para cerrar la ruta"
|
||||
},
|
||||
"unused" : true
|
||||
},
|
||||
"workspace.shape.menu.flip-horizontal" : {
|
||||
"used-in" : [ "src/app/main/ui/workspace/context_menu.cljs:146" ],
|
||||
"translations" : {
|
||||
"en" : "Flip horizontal",
|
||||
"es" : "Voltear horizontal"
|
||||
}
|
||||
},
|
||||
"workspace.shape.menu.flip-vertical" : {
|
||||
"used-in" : [ "src/app/main/ui/workspace/context_menu.cljs:143" ],
|
||||
"translations" : {
|
||||
"en" : "Flip vertical",
|
||||
"es" : "Voltear vertical"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1799,6 +1799,8 @@
|
|||
(d/export dwt/set-modifiers)
|
||||
(d/export dwt/apply-modifiers)
|
||||
(d/export dwt/update-dimensions)
|
||||
(d/export dwt/flip-horizontal-selected)
|
||||
(d/export dwt/flip-vertical-selected)
|
||||
|
||||
;; Persistence
|
||||
|
||||
|
|
|
@ -90,12 +90,15 @@
|
|||
path)))
|
||||
|
||||
(defn- points->components [shape content]
|
||||
(let [rotation (:rotation shape 0)
|
||||
(let [transform (:transform shape)
|
||||
transform-inverse (:transform-inverse shape)
|
||||
center (gsh/center-shape shape)
|
||||
content-rotated (gsh/transform-content content (gmt/rotate-matrix (- rotation) center))
|
||||
base-content (gsh/transform-content
|
||||
content
|
||||
(gmt/transform-in center transform-inverse))
|
||||
|
||||
;; Calculates the new selrect with points given the old center
|
||||
points (-> (gsh/content->selrect content-rotated)
|
||||
points (-> (gsh/content->selrect base-content)
|
||||
(gsh/rect->points)
|
||||
(gsh/transform-points center (:transform shape (gmt/matrix))))
|
||||
|
||||
|
|
|
@ -108,6 +108,14 @@
|
|||
:command (ds/c-mod "k")
|
||||
:fn #(st/emit! dwl/add-component)}
|
||||
|
||||
:flip-vertical {:tooltip (ds/shift "V")
|
||||
:command "shift+v"
|
||||
:fn #(st/emit! (dw/flip-vertical-selected))}
|
||||
|
||||
:flip-horizontal {:tooltip (ds/shift "V")
|
||||
:command "shift+h"
|
||||
:fn #(st/emit! (dw/flip-horizontal-selected))}
|
||||
|
||||
:reset-zoom {:tooltip (ds/shift "0")
|
||||
:command "shift+0"
|
||||
:fn #(st/emit! dw/reset-zoom)}
|
||||
|
|
|
@ -82,8 +82,6 @@
|
|||
{:keys [rotation]} shape
|
||||
shapev (-> (gpt/point width height))
|
||||
|
||||
rotation (if (= :path (:type shape)) 0 rotation)
|
||||
|
||||
;; Vector modifiers depending on the handler
|
||||
handler-modif (let [[x y] (handler-modifiers handler)] (gpt/point x y))
|
||||
|
||||
|
@ -125,15 +123,7 @@
|
|||
;; lock flag that can be activated on element options.
|
||||
(normalize-proportion-lock [[point shift?]]
|
||||
(let [proportion-lock? (:proportion-lock shape)]
|
||||
[point (or proportion-lock? shift?)]))
|
||||
|
||||
;; Applies alginment to point if it is currently
|
||||
;; activated on the current workspace
|
||||
;; (apply-grid-alignment [point]
|
||||
;; (if @refs/selected-alignment
|
||||
;; (uwrk/align-point point)
|
||||
;; (rx/of point)))
|
||||
]
|
||||
[point (or proportion-lock? shift?)]))]
|
||||
(reify
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
|
@ -142,8 +132,7 @@
|
|||
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [current-pointer @ms/mouse-position
|
||||
initial-position (merge current-pointer initial)
|
||||
(let [initial-position @ms/mouse-position
|
||||
stoper (rx/filter ms/mouse-up? stream)
|
||||
layout (:workspace-layout state)
|
||||
page-id (:current-page-id state)
|
||||
|
@ -541,3 +530,37 @@
|
|||
objects (dwc/lookup-page-objects state page-id)
|
||||
ids (d/concat [] ids (mapcat #(cp/get-children % objects) ids))]
|
||||
(rx/of (apply-modifiers ids))))))
|
||||
|
||||
(defn flip-horizontal-selected []
|
||||
(ptk/reify ::flip-horizontal-selected
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [objects (dwc/lookup-page-objects state)
|
||||
selected (get-in state [:workspace-local :selected])
|
||||
shapes (map #(get objects %) selected)
|
||||
selrect (gsh/selection-rect (->> shapes (map gsh/transform-shape)))
|
||||
origin (gpt/point (:x selrect) (+ (:y selrect) (/ (:height selrect) 2)))]
|
||||
|
||||
(rx/of (set-modifiers selected
|
||||
{:resize-vector (gpt/point -1.0 1.0)
|
||||
:resize-origin origin
|
||||
:displacement (gmt/translate-matrix (gpt/point (- (:width selrect)) 0))}
|
||||
false)
|
||||
(apply-modifiers selected))))))
|
||||
|
||||
(defn flip-vertical-selected []
|
||||
(ptk/reify ::flip-vertical-selected
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [objects (dwc/lookup-page-objects state)
|
||||
selected (get-in state [:workspace-local :selected])
|
||||
shapes (map #(get objects %) selected)
|
||||
selrect (gsh/selection-rect (->> shapes (map gsh/transform-shape)))
|
||||
origin (gpt/point (+ (:x selrect) (/ (:width selrect) 2)) (:y selrect))]
|
||||
|
||||
(rx/of (set-modifiers selected
|
||||
{:resize-vector (gpt/point 1.0 -1.0)
|
||||
:resize-origin origin
|
||||
:displacement (gmt/translate-matrix (gpt/point 0 (- (:height selrect))))}
|
||||
false)
|
||||
(apply-modifiers selected))))))
|
||||
|
|
|
@ -20,15 +20,13 @@
|
|||
|
||||
(mf/defc linear-gradient [{:keys [id gradient shape]}]
|
||||
(let [{:keys [x y width height]} (:selrect shape)
|
||||
transform (case (:type shape)
|
||||
:path (gmt/matrix)
|
||||
(gsh/inverse-transform-matrix shape (gpt/point 0.5 0.5)))]
|
||||
transform (when (= :path (:type shape)) (gsh/transform-matrix shape nil (gpt/point 0.5 0.5)))]
|
||||
[:linearGradient {:id id
|
||||
:x1 (:start-x gradient)
|
||||
:y1 (:start-y gradient)
|
||||
:x2 (:end-x gradient)
|
||||
:y2 (:end-y gradient)
|
||||
:gradient-transform transform}
|
||||
:gradientTransform transform}
|
||||
(for [{:keys [offset color opacity]} (:stops gradient)]
|
||||
[:stop {:key (str id "-stop-" offset)
|
||||
:offset (or offset 0)
|
||||
|
@ -37,9 +35,8 @@
|
|||
|
||||
(mf/defc radial-gradient [{:keys [id gradient shape]}]
|
||||
(let [{:keys [x y width height]} (:selrect shape)
|
||||
transform (case (:type shape)
|
||||
:path (gmt/matrix)
|
||||
(gsh/inverse-transform-matrix shape))]
|
||||
center (gsh/center-shape shape)
|
||||
transform (when (= :path (:type shape)) (gsh/transform-matrix shape))]
|
||||
(let [[x y] (if (= (:type shape) :frame) [0 0] [x y])
|
||||
translate-vec (gpt/point (+ x (* width (:start-x gradient)))
|
||||
(+ y (* height (:start-y gradient))))
|
||||
|
|
|
@ -72,6 +72,8 @@
|
|||
do-remove-group (st/emitf dw/ungroup-selected)
|
||||
do-mask-group (st/emitf dw/mask-group)
|
||||
do-unmask-group (st/emitf dw/unmask-group)
|
||||
do-flip-vertical (st/emitf (dw/flip-vertical-selected))
|
||||
do-flip-horizontal (st/emitf (dw/flip-horizontal-selected))
|
||||
do-add-component (st/emitf dwl/add-component)
|
||||
do-detach-component (st/emitf (dwl/detach-component id))
|
||||
do-reset-component (st/emitf (dwl/reset-component id))
|
||||
|
@ -133,7 +135,18 @@
|
|||
:on-click do-create-group}]
|
||||
[:& menu-entry {:title (t locale "workspace.shape.menu.mask")
|
||||
:shortcut (sc/get-tooltip :mask)
|
||||
:on-click do-mask-group}]])
|
||||
:on-click do-mask-group}]
|
||||
[:& menu-separator]])
|
||||
|
||||
(when (>= (count selected) 1)
|
||||
[:*
|
||||
[:& menu-entry {:title (t locale "workspace.shape.menu.flip-vertical")
|
||||
:shortcut (sc/get-tooltip :flip-vertical)
|
||||
:on-click do-flip-vertical}]
|
||||
[:& menu-entry {:title (t locale "workspace.shape.menu.flip-horizontal")
|
||||
:shortcut (sc/get-tooltip :flip-horizontal)
|
||||
:on-click do-flip-horizontal}]
|
||||
[:& menu-separator]])
|
||||
|
||||
(when (and (= (count selected) 1) (= (:type shape) :group))
|
||||
[:*
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
[beicon.core :as rx]
|
||||
[okulary.core :as l]
|
||||
[app.common.math :as mth]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.matrix :as gmt]
|
||||
[app.util.dom :as dom]
|
||||
|
@ -238,16 +239,22 @@
|
|||
gradient (mf/deref current-gradient-ref)
|
||||
editing-spot (mf/deref editing-spot-ref)
|
||||
|
||||
transform (gsh/transform-matrix shape)
|
||||
transform-inverse (gsh/inverse-transform-matrix shape)
|
||||
|
||||
{:keys [x y width height] :as sr} (:selrect shape)
|
||||
|
||||
[{start-color :color start-opacity :opacity}
|
||||
{end-color :color end-opacity :opacity}] (:stops gradient)
|
||||
|
||||
from-p (gpt/point (+ x (* width (:start-x gradient)))
|
||||
(+ y (* height (:start-y gradient))))
|
||||
from-p (-> (gpt/point (+ x (* width (:start-x gradient)))
|
||||
(+ y (* height (:start-y gradient))))
|
||||
|
||||
to-p (gpt/point (+ x (* width (:end-x gradient)))
|
||||
(+ y (* height (:end-y gradient))))
|
||||
(gpt/transform transform))
|
||||
|
||||
to-p (-> (gpt/point (+ x (* width (:end-x gradient)))
|
||||
(+ y (* height (:end-y gradient))))
|
||||
(gpt/transform transform))
|
||||
|
||||
gradient-vec (gpt/to-vec from-p to-p)
|
||||
gradient-length (gpt/length gradient-vec)
|
||||
|
@ -263,14 +270,16 @@
|
|||
(st/emit! (dc/update-gradient changes)))
|
||||
|
||||
on-change-start (fn [point]
|
||||
(let [start-x (/ (- (:x point) x) width)
|
||||
(let [point (gpt/transform point transform-inverse)
|
||||
start-x (/ (- (:x point) x) width)
|
||||
start-y (/ (- (:y point) y) height)
|
||||
start-x (mth/precision start-x 2)
|
||||
start-y (mth/precision start-y 2)]
|
||||
(change! {:start-x start-x :start-y start-y})))
|
||||
|
||||
on-change-finish (fn [point]
|
||||
(let [end-x (/ (- (:x point) x) width)
|
||||
(let [point (gpt/transform point transform-inverse)
|
||||
end-x (/ (- (:x point) x) width)
|
||||
end-y (/ (- (:y point) y) height)
|
||||
|
||||
end-x (mth/precision end-x 2)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue