From fc2a26f249c5230fb53562627e68c639dd4f2a0a Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Fri, 28 Jan 2022 13:39:17 +0100 Subject: [PATCH] :tada: Add border radius support to image shapes --- CHANGES.md | 1 + common/src/app/common/pages/common.cljc | 2 +- common/src/app/common/pages/init.cljc | 4 +++- common/src/app/common/pages/migrations.cljc | 19 +++++++++++++++++ frontend/src/app/main/ui/shapes/attrs.cljs | 5 +++++ frontend/src/app/main/ui/shapes/export.cljs | 12 ++++++++++- frontend/src/app/main/ui/shapes/image.cljs | 8 +++++-- .../main/ui/viewer/handoff/attributes.cljs | 2 +- .../ui/viewer/handoff/attributes/fill.cljs | 2 +- .../ui/viewer/handoff/attributes/shadow.cljs | 2 +- frontend/src/app/util/import/parser.cljs | 21 ++++++++++++++++--- 11 files changed, 67 insertions(+), 11 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 3f386a80f4..05ccca284f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,6 +6,7 @@ ### :sparkles: New features +- Support border radius and stroke properties for images [Taiga #497](https://tree.taiga.io/project/penpot/us/497) - Disallow using same password as user email [Taiga #2454](https://tree.taiga.io/project/penpot/us/2454) - Add configurable nudge amount [Taiga #910](https://tree.taiga.io/project/penpot/us/910) - Add stroke properties for image shapes [Taiga #497](https://tree.taiga.io/project/penpot/us/497) diff --git a/common/src/app/common/pages/common.cljc b/common/src/app/common/pages/common.cljc index 6356f4bbec..43cd9371cf 100644 --- a/common/src/app/common/pages/common.cljc +++ b/common/src/app/common/pages/common.cljc @@ -9,7 +9,7 @@ [app.common.colors :as clr] [app.common.uuid :as uuid])) -(def file-version 12) +(def file-version 13) (def default-color clr/gray-20) (def root uuid/zero) diff --git a/common/src/app/common/pages/init.cljc b/common/src/app/common/pages/init.cljc index 8e3b5bb92f..21a209c359 100644 --- a/common/src/app/common/pages/init.cljc +++ b/common/src/app/common/pages/init.cljc @@ -51,7 +51,9 @@ :rx 0 :ry 0} - {:type :image} + {:type :image + :rx 0 + :ry 0} {:type :circle :name "Circle-1" diff --git a/common/src/app/common/pages/migrations.cljc b/common/src/app/common/pages/migrations.cljc index dd7d232681..d87f2156e8 100644 --- a/common/src/app/common/pages/migrations.cljc +++ b/common/src/app/common/pages/migrations.cljc @@ -281,3 +281,22 @@ (d/update-in-when page [:options :saved-grids] #(d/mapm update-grid %)))] (update data :pages-index #(d/mapm update-page %)))) + +;; Add rx and ry to images +(defmethod migrate 13 + [data] + (letfn [(fix-radius [shape] + (if-not (or (contains? shape :rx) (contains? shape :r1)) + (-> shape + (assoc :rx 0) + (assoc :ry 0)) + shape)) + (update-object [_ object] + (cond-> object + (= :image (:type object)) + (fix-radius))) + + (update-page [_ page] + (update page :objects #(d/mapm update-object %)))] + + (update data :pages-index #(d/mapm update-page %)))) diff --git a/frontend/src/app/main/ui/shapes/attrs.cljs b/frontend/src/app/main/ui/shapes/attrs.cljs index 06ef83ccf7..dd6a041abb 100644 --- a/frontend/src/app/main/ui/shapes/attrs.cljs +++ b/frontend/src/app/main/ui/shapes/attrs.cljs @@ -214,3 +214,8 @@ (add-fill shape render-id))] (-> (obj/new) (obj/set! "style" fill-styles)))) + +(defn extract-border-radius-attrs + [shape] + (-> (obj/new) + (add-border-radius shape))) diff --git a/frontend/src/app/main/ui/shapes/export.cljs b/frontend/src/app/main/ui/shapes/export.cljs index bde04d4420..d61fe8a49d 100644 --- a/frontend/src/app/main/ui/shapes/export.cljs +++ b/frontend/src/app/main/ui/shapes/export.cljs @@ -64,6 +64,7 @@ (let [add! (add-factory shape) group? (= :group (:type shape)) rect? (= :rect (:type shape)) + image? (= :image (:type shape)) text? (= :text (:type shape)) path? (= :path (:type shape)) mask? (and group? (:masked-group? shape)) @@ -92,12 +93,21 @@ (add! :constraints-v) (add! :fixed-scroll) - (cond-> (and rect? (some? (:r1 shape))) + (cond-> (and (or rect? image?) (some? (:r1 shape))) (-> (add! :r1) (add! :r2) (add! :r3) (add! :r4))) + (cond-> (and image? (some? (:rx shape))) + (-> (add! :rx) + (add! :ry))) + + (cond-> image? + (-> (add! :fill-color) + (add! :fill-opacity) + (add! :fill-color-gradient))) + (cond-> path? (-> (add! :stroke-cap-start) (add! :stroke-cap-end))) diff --git a/frontend/src/app/main/ui/shapes/image.cljs b/frontend/src/app/main/ui/shapes/image.cljs index d438fa5cfe..988c522472 100644 --- a/frontend/src/app/main/ui/shapes/image.cljs +++ b/frontend/src/app/main/ui/shapes/image.cljs @@ -34,12 +34,14 @@ fill-image-id (str "fill-image-" render-id) shape (assoc shape :fill-image fill-image-id) props (-> (attrs/extract-style-attrs shape) + (obj/merge! (attrs/extract-border-radius-attrs shape)) (obj/merge! #js {:x x :y y :transform transform :width width - :height height}))] + :height height})) + path? (some? (.-d props))] [:g [:defs @@ -56,4 +58,6 @@ :width width :height height}]]]] [:& shape-custom-stroke {:shape shape} - [:> :rect props]]])) + (if path? + [:> :path props] + [:> :rect props])]])) diff --git a/frontend/src/app/main/ui/viewer/handoff/attributes.cljs b/frontend/src/app/main/ui/viewer/handoff/attributes.cljs index 2792ae1fef..7a09206895 100644 --- a/frontend/src/app/main/ui/viewer/handoff/attributes.cljs +++ b/frontend/src/app/main/ui/viewer/handoff/attributes.cljs @@ -26,7 +26,7 @@ :rect [:layout :fill :stroke :shadow :blur :svg] :circle [:layout :fill :stroke :shadow :blur :svg] :path [:layout :fill :stroke :shadow :blur :svg] - :image [:image :layout :shadow :blur :svg] + :image [:image :layout :fill :stroke :shadow :blur :svg] :text [:layout :text :shadow :blur]}) (mf/defc attributes diff --git a/frontend/src/app/main/ui/viewer/handoff/attributes/fill.cljs b/frontend/src/app/main/ui/viewer/handoff/attributes/fill.cljs index c1ee2269f0..8c600a2d74 100644 --- a/frontend/src/app/main/ui/viewer/handoff/attributes/fill.cljs +++ b/frontend/src/app/main/ui/viewer/handoff/attributes/fill.cljs @@ -24,7 +24,7 @@ (defn has-color? [shape] (and - (not (contains? #{:image :text :group} (:type shape))) + (not (contains? #{:text :group} (:type shape))) (or (:fill-color shape) (:fill-color-gradient shape)))) diff --git a/frontend/src/app/main/ui/viewer/handoff/attributes/shadow.cljs b/frontend/src/app/main/ui/viewer/handoff/attributes/shadow.cljs index 67a934f5c7..511f4ad782 100644 --- a/frontend/src/app/main/ui/viewer/handoff/attributes/shadow.cljs +++ b/frontend/src/app/main/ui/viewer/handoff/attributes/shadow.cljs @@ -60,7 +60,7 @@ (mf/defc shadow-panel [{:keys [shapes]}] (let [shapes (->> shapes (filter has-shadow?))] - (when (seq shapes) + (when (and (seq shapes) (> (count shapes) 0)) [:div.attributes-block [:div.attributes-block-title [:div.attributes-block-title-text (tr "handoff.attributes.shadow")] diff --git a/frontend/src/app/util/import/parser.cljs b/frontend/src/app/util/import/parser.cljs index 82fd838ad9..63cc626689 100644 --- a/frontend/src/app/util/import/parser.cljs +++ b/frontend/src/app/util/import/parser.cljs @@ -364,7 +364,11 @@ (let [fill (:fill svg-data) hide-fill-on-export (get-meta node :hide-fill-on-export str->bool) gradient (when (str/starts-with? fill "url") - (parse-gradient node fill))] + (parse-gradient node fill)) + meta-fill-color (get-meta node :fill-color) + meta-fill-opacity (get-meta node :fill-opacity) + meta-fill-color-gradient (get-meta node :fill-color-gradient)] + (cond-> props :always (assoc :fill-color nil @@ -380,7 +384,16 @@ :fill-opacity (-> svg-data (:fill-opacity "1") d/parse-double)) (some? hide-fill-on-export) - (assoc :hide-fill-on-export hide-fill-on-export)))) + (assoc :hide-fill-on-export hide-fill-on-export) + + (some? meta-fill-color) + (assoc :fill-color meta-fill-color + :fill-opacity (d/parse-double meta-fill-opacity)) + + (some? meta-fill-color-gradient) + (assoc :fill-color-gradient meta-fill-color-gradient + :fill-color nil + :fill-opacity nil)))) (defn add-stroke [props node svg-data] @@ -763,7 +776,9 @@ (add-rect-data node svg-data)) (cond-> (some? (get-in node [:attrs :penpot:media-id])) - (add-image-data type node)) + (-> + (add-rect-data node svg-data) + (add-image-data type node))) (cond-> (= :text type) (add-text-data node))