0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-01-10 08:50:57 -05:00

🐛 Fixes problems with raw-svg

This commit is contained in:
alonso.torres 2021-01-11 11:43:12 +01:00 committed by Hirunatan
parent 9043d2574b
commit bb07c4b3b7
4 changed files with 92 additions and 49 deletions

View file

@ -106,7 +106,7 @@
objects (dissoc objects id)]
(cond-> objects
(and (not= parent-id frame-id)
(= :group (:type parent)))
(#{:group :svg-raw} (:type parent)))
(update-in [parent-id :shapes] (fn [s] (filterv #(not= % id) s)))
(and (:shape-ref parent) (not ignore-touched))

View file

@ -401,16 +401,19 @@
(update [_ state]
(update state :workspace-local
(fn [{:keys [vbox vport left-sidebar? zoom] :as local}]
(let [wprop (/ (:width vport) width)
hprop (/ (:height vport) height)
left-offset (if left-sidebar? 0 (/ (* -1 15 16) zoom))]
(-> local ;; This matches $width-settings-bar
(assoc :vport size) ;; in frontend/resources/styles/main/partials/sidebar.scss
(update :vbox (fn [vbox]
(-> vbox
(update :width #(/ % wprop))
(update :height #(/ % hprop))
(assoc :left-offset left-offset)))))))))))
(if (or (mth/almost-zero? width) (mth/almost-zero? height))
;; If we have a resize to zero just keep the old value
local
(let [wprop (/ (:width vport) width)
hprop (/ (:height vport) height)
left-offset (if left-sidebar? 0 (/ (* -1 15 16) zoom))]
(-> local ;; This matches $width-settings-bar
(assoc :vport size) ;; in frontend/resources/styles/main/partials/sidebar.scss
(update :vbox (fn [vbox]
(-> vbox
(update :width #(/ % wprop))
(update :height #(/ % hprop))
(assoc :left-offset left-offset))))))))))))
(defn start-pan [state]

View file

@ -13,11 +13,16 @@
[app.common.geom.point :as gpt]
[app.common.geom.shapes :as gsh]
[app.main.ui.shapes.attrs :as usa]
[app.util.data :as d]
[app.util.data :as ud]
[app.common.data :as cd]
[app.common.uuid :as uuid]
[app.util.object :as obj]
[cuerdas.core :as str]
[rumext.alpha :as mf]))
;; Context to store a re-mapping of the ids
(def svg-ids-ctx (mf/create-context nil))
(defn clean-attrs
"Transforms attributes to their react equivalent"
[attrs]
@ -51,7 +56,7 @@
"Converts the viewBox into a rectangle"
[vbox]
(when vbox
(let [[x y width height] (map d/parse-float (str/split vbox " "))]
(let [[x y width height] (map ud/parse-float (str/split vbox " "))]
{:x x :y y :width width :height height})))
(defn vbox-center [shape]
@ -74,50 +79,81 @@
{:keys [x y width height]} (gsh/center->rect center (:width bounds) (:height bounds))]
(str x " " y " " width " " height)))
(defn generate-id-mapping [content]
(letfn [(visit-node [result node]
(let [element-id (get-in node [:attrs :id])
result (cond-> result
element-id (assoc element-id (str (uuid/next))))]
(reduce visit-node result (:content node))))]
(visit-node {} content)))
(defn svg-raw-shape [shape-wrapper]
(mf/fnc svg-raw-shape
{::mf/wrap-props false}
[props]
(let [frame (unchecked-get props "frame")
shape (unchecked-get props "shape")
childs (unchecked-get props "childs")
{::mf/wrap-props false}
[props]
(let [frame (unchecked-get props "frame")
shape (unchecked-get props "shape")
childs (unchecked-get props "childs")
{:keys [tag attrs] :as content} (:content shape)
{:keys [tag attrs] :as content} (:content shape)
attrs (obj/merge! (clj->js (clean-attrs attrs))
(usa/extract-style-attrs shape))]
new-mapping (mf/use-memo #(when (= tag :svg) (generate-id-mapping content)))
ids-mapping (if (= tag :svg)
new-mapping
(mf/use-ctx svg-ids-ctx))
(cond
;; Root SVG TAG
(and (map? content) (= tag :svg))
(let [;; {:keys [x y width height]} (-> (:points shape) gsh/points->selrect)
{:keys [x y width height]} shape
attrs (-> attrs
(obj/set! "x" x)
(obj/set! "y" y)
(obj/set! "width" width)
(obj/set! "height" height)
(obj/set! "preserveAspectRatio" "none")
#_(obj/set! "viewBox" (transform-viewbox shape)))]
rex #"[^#]*#([^)\s]+).*"
[:g.svg-raw {:transform (gsh/transform-matrix shape)}
[:> "svg" attrs
(for [item childs]
[:& shape-wrapper {:frame frame
:shape item
:key (:id item)}])]])
;; Replaces the attributes ID's so there are no collisions between shapes
replace-ids
(fn [key val]
(let [[_ from-id] (re-matches rex val)]
(if (and from-id (contains? ids-mapping from-id))
(str/replace val from-id (get ids-mapping from-id))
val)))
;; Other tags different than root
(map? content)
[:> (name tag) attrs
(for [item childs]
[:& shape-wrapper {:frame frame
:shape item
:key (:id item)}])]
attrs (->> attrs
(cd/mapm replace-ids)
(clean-attrs))
;; String content
(string? content) content
attrs (obj/merge! (clj->js attrs)
(usa/extract-style-attrs shape))
:else nil))))
element-id (get-in content [:attrs :id])]
(cond
;; Root SVG TAG
(and (map? content) (= tag :svg))
(let [{:keys [x y width height]} shape
attrs (-> attrs
(obj/set! "x" x)
(obj/set! "y" y)
(obj/set! "width" width)
(obj/set! "height" height)
(obj/set! "preserveAspectRatio" "none")
#_(obj/set! "viewBox" (transform-viewbox shape)))]
[:& (mf/provider svg-ids-ctx) {:value ids-mapping}
[:g.svg-raw {:transform (gsh/transform-matrix shape)}
[:> "svg" attrs
(for [item childs]
[:& shape-wrapper {:frame frame
:shape item
:key (:id item)}])]]])
;; Other tags different than root
(map? content)
(let [attrs (cond-> attrs
element-id (obj/set! "id" (get ids-mapping element-id)))]
[:> (name tag) attrs
(for [item childs]
[:& shape-wrapper {:frame frame
:shape item
:key (:id item)}])])
;; String content
(string? content) content
:else nil))))

View file

@ -41,6 +41,10 @@
;; TODO CHECK IF IT'S A GRADIENT
(str/starts-with? color "url")
{:color :multiple
:opacity :multiple}
:else nil))