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:
parent
9043d2574b
commit
bb07c4b3b7
4 changed files with 92 additions and 49 deletions
|
@ -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))
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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))))
|
||||
|
||||
|
||||
|
|
|
@ -41,6 +41,10 @@
|
|||
|
||||
;; TODO CHECK IF IT'S A GRADIENT
|
||||
|
||||
(str/starts-with? color "url")
|
||||
{:color :multiple
|
||||
:opacity :multiple}
|
||||
|
||||
:else nil))
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue