diff --git a/CHANGES.md b/CHANGES.md index c6b6e4a41..ddfcb61a7 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -11,6 +11,7 @@ - Add visualization and mouse control to paddings in frames with layout [Taiga #4839](https://tree.taiga.io/project/penpot/task/4839) - Allow for absolute positioned elements inside layout [Taiga #4834](https://tree.taiga.io/project/penpot/us/4834) - Add z-index option for flex layout items [Taiga #2980](https://tree.taiga.io/project/penpot/us/2980) +- Scale content proportionally affects strokes, shadows, blurs and corners [Taiga #1951](https://tree.taiga.io/project/penpot/us/1951) ### :bug: Bugs fixed diff --git a/common/src/app/common/geom/shapes/corners.cljc b/common/src/app/common/geom/shapes/corners.cljc index ec7a825b7..553d66136 100644 --- a/common/src/app/common/geom/shapes/corners.cljc +++ b/common/src/app/common/geom/shapes/corners.cljc @@ -54,3 +54,27 @@ (if (and (some? r1) (some? r2) (some? r3) (some? r4)) (fix-radius width height r1 r2 r3 r4) [r1 r2 r3 r4])) + +(defn update-corners-scale-1 + "Scales round corners (using a single value)" + [shape scale] + (update shape :rx * scale)) + +(defn update-corners-scale-4 + "Scales round corners (using four values)" + [shape scale] + (-> shape + (update :r1 * scale) + (update :r2 * scale) + (update :r3 * scale) + (update :r4 * scale))) + +(defn update-corners-scale + "Scales round corners" + [shape scale] + (cond-> shape + (and (some? (:rx shape)) (> (:rx shape) 0)) + (update-corners-scale-1 scale) + + (and (some? (:r1 shape)) (> (:r1 shape) 0)) + (update-corners-scale-4 scale))) diff --git a/common/src/app/common/geom/shapes/effects.cljc b/common/src/app/common/geom/shapes/effects.cljc new file mode 100644 index 000000000..912b2de6c --- /dev/null +++ b/common/src/app/common/geom/shapes/effects.cljc @@ -0,0 +1,20 @@ +(ns app.common.geom.shapes.effects) + +(defn update-shadow-scale + [shadow scale] + (-> shadow + (update :offset-x * scale) + (update :offset-y * scale) + (update :spread * scale) + (update :blur * scale))) + +(defn update-shadows-scale + [shape scale] + (update shape :shadow + (fn [shadow] + (mapv #(update-shadow-scale % scale) shadow)))) + +(defn update-blur-scale + [shape scale] + (update-in shape [:blur :value] * scale)) + diff --git a/common/src/app/common/geom/shapes/strokes.cljc b/common/src/app/common/geom/shapes/strokes.cljc new file mode 100644 index 000000000..e155dde7b --- /dev/null +++ b/common/src/app/common/geom/shapes/strokes.cljc @@ -0,0 +1,11 @@ +(ns app.common.geom.shapes.strokes) + +(defn update-stroke-width + [stroke scale] + (update stroke :stroke-width * scale)) + +(defn update-strokes-width + [shape scale] + (update shape :strokes + (fn [strokes] + (mapv #(update-stroke-width % scale) strokes)))) diff --git a/common/src/app/common/pages/helpers.cljc b/common/src/app/common/pages/helpers.cljc index 6ab947d90..3c4649c5e 100644 --- a/common/src/app/common/pages/helpers.cljc +++ b/common/src/app/common/pages/helpers.cljc @@ -54,6 +54,10 @@ [{:keys [type]}] (= type :text)) +(defn rect-shape? + [{:keys [type]}] + (= type :rect)) + (defn image-shape? [{:keys [type]}] (= type :image)) diff --git a/common/src/app/common/types/modifiers.cljc b/common/src/app/common/types/modifiers.cljc index 5d2764bb7..5097550e9 100644 --- a/common/src/app/common/types/modifiers.cljc +++ b/common/src/app/common/types/modifiers.cljc @@ -12,6 +12,9 @@ [app.common.geom.matrix :as gmt] [app.common.geom.point :as gpt] [app.common.geom.shapes.common :as gco] + [app.common.geom.shapes.corners :as gsc] + [app.common.geom.shapes.effects :as gse] + [app.common.geom.shapes.strokes :as gss] [app.common.math :as mth] [app.common.pages.helpers :as cph] [app.common.spec :as us] @@ -252,7 +255,7 @@ (defn resize ([modifiers vector origin] - (assert (valid-vector? vector) (dm/str "Invalid move vector: " (:x vector) "," (:y vector))) + (assert (valid-vector? vector) (dm/str "Invalid resize vector: " (:x vector) "," (:y vector))) (let [modifiers (or modifiers (empty)) order (inc (dm/get-prop modifiers :last-order)) modifiers (assoc modifiers :last-order order)] @@ -260,12 +263,12 @@ (resize-vec? vector) (update :geometry-child maybe-add-resize (resize-op order vector origin))))) - ([modifiers vector origin transform transform-inverse] + ([modifiers vector origin transform transform-inverse] (resize modifiers vector origin transform transform-inverse nil)) ;; `precise?` works so we don't remove almost empty resizes. This will be used in the pixel-precision ([modifiers vector origin transform transform-inverse {:keys [precise?]}] - (assert (valid-vector? vector) (dm/str "Invalid move vector: " (:x vector) "," (:y vector))) + (assert (valid-vector? vector) (dm/str "Invalid resize vector: " (:x vector) "," (:y vector))) (let [modifiers (or modifiers (empty)) order (inc (dm/get-prop modifiers :last-order)) modifiers (assoc modifiers :last-order order)] @@ -653,7 +656,19 @@ (cond-> shape (cph/text-shape? shape) - (update :content scale-text-content value)))] + (update :content scale-text-content value) + + (cph/rect-shape? shape) + (gsc/update-corners-scale value) + + (d/not-empty? (:strokes shape)) + (gss/update-strokes-width value) + + (d/not-empty? (:shadow shape)) + (gse/update-shadows-scale value) + + (some? (:blur shape)) + (gse/update-blur-scale value)))] (let [remove-children (fn [shapes children-to-remove] diff --git a/frontend/src/app/main/data/workspace/modifiers.cljs b/frontend/src/app/main/data/workspace/modifiers.cljs index 87691506f..110439add 100644 --- a/frontend/src/app/main/data/workspace/modifiers.cljs +++ b/frontend/src/app/main/data/workspace/modifiers.cljs @@ -419,6 +419,15 @@ :points :x :y + :rx + :ry + :r1 + :r2 + :r3 + :r4 + :shadow + :blur + :strokes :width :height :content