mirror of
https://github.com/penpot/penpot.git
synced 2025-05-30 21:56:11 +02: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)]
|
objects (dissoc objects id)]
|
||||||
(cond-> objects
|
(cond-> objects
|
||||||
(and (not= parent-id frame-id)
|
(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)))
|
(update-in [parent-id :shapes] (fn [s] (filterv #(not= % id) s)))
|
||||||
|
|
||||||
(and (:shape-ref parent) (not ignore-touched))
|
(and (:shape-ref parent) (not ignore-touched))
|
||||||
|
|
|
@ -401,16 +401,19 @@
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(update state :workspace-local
|
(update state :workspace-local
|
||||||
(fn [{:keys [vbox vport left-sidebar? zoom] :as local}]
|
(fn [{:keys [vbox vport left-sidebar? zoom] :as local}]
|
||||||
(let [wprop (/ (:width vport) width)
|
(if (or (mth/almost-zero? width) (mth/almost-zero? height))
|
||||||
hprop (/ (:height vport) height)
|
;; If we have a resize to zero just keep the old value
|
||||||
left-offset (if left-sidebar? 0 (/ (* -1 15 16) zoom))]
|
local
|
||||||
(-> local ;; This matches $width-settings-bar
|
(let [wprop (/ (:width vport) width)
|
||||||
(assoc :vport size) ;; in frontend/resources/styles/main/partials/sidebar.scss
|
hprop (/ (:height vport) height)
|
||||||
(update :vbox (fn [vbox]
|
left-offset (if left-sidebar? 0 (/ (* -1 15 16) zoom))]
|
||||||
(-> vbox
|
(-> local ;; This matches $width-settings-bar
|
||||||
(update :width #(/ % wprop))
|
(assoc :vport size) ;; in frontend/resources/styles/main/partials/sidebar.scss
|
||||||
(update :height #(/ % hprop))
|
(update :vbox (fn [vbox]
|
||||||
(assoc :left-offset left-offset)))))))))))
|
(-> vbox
|
||||||
|
(update :width #(/ % wprop))
|
||||||
|
(update :height #(/ % hprop))
|
||||||
|
(assoc :left-offset left-offset))))))))))))
|
||||||
|
|
||||||
|
|
||||||
(defn start-pan [state]
|
(defn start-pan [state]
|
||||||
|
|
|
@ -13,11 +13,16 @@
|
||||||
[app.common.geom.point :as gpt]
|
[app.common.geom.point :as gpt]
|
||||||
[app.common.geom.shapes :as gsh]
|
[app.common.geom.shapes :as gsh]
|
||||||
[app.main.ui.shapes.attrs :as usa]
|
[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]
|
[app.util.object :as obj]
|
||||||
[cuerdas.core :as str]
|
[cuerdas.core :as str]
|
||||||
[rumext.alpha :as mf]))
|
[rumext.alpha :as mf]))
|
||||||
|
|
||||||
|
;; Context to store a re-mapping of the ids
|
||||||
|
(def svg-ids-ctx (mf/create-context nil))
|
||||||
|
|
||||||
(defn clean-attrs
|
(defn clean-attrs
|
||||||
"Transforms attributes to their react equivalent"
|
"Transforms attributes to their react equivalent"
|
||||||
[attrs]
|
[attrs]
|
||||||
|
@ -51,7 +56,7 @@
|
||||||
"Converts the viewBox into a rectangle"
|
"Converts the viewBox into a rectangle"
|
||||||
[vbox]
|
[vbox]
|
||||||
(when 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})))
|
{:x x :y y :width width :height height})))
|
||||||
|
|
||||||
(defn vbox-center [shape]
|
(defn vbox-center [shape]
|
||||||
|
@ -74,50 +79,81 @@
|
||||||
{:keys [x y width height]} (gsh/center->rect center (:width bounds) (:height bounds))]
|
{:keys [x y width height]} (gsh/center->rect center (:width bounds) (:height bounds))]
|
||||||
(str x " " y " " width " " height)))
|
(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]
|
(defn svg-raw-shape [shape-wrapper]
|
||||||
(mf/fnc svg-raw-shape
|
(mf/fnc svg-raw-shape
|
||||||
{::mf/wrap-props false}
|
{::mf/wrap-props false}
|
||||||
[props]
|
[props]
|
||||||
(let [frame (unchecked-get props "frame")
|
(let [frame (unchecked-get props "frame")
|
||||||
shape (unchecked-get props "shape")
|
shape (unchecked-get props "shape")
|
||||||
childs (unchecked-get props "childs")
|
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))
|
new-mapping (mf/use-memo #(when (= tag :svg) (generate-id-mapping content)))
|
||||||
(usa/extract-style-attrs shape))]
|
ids-mapping (if (= tag :svg)
|
||||||
|
new-mapping
|
||||||
|
(mf/use-ctx svg-ids-ctx))
|
||||||
|
|
||||||
(cond
|
rex #"[^#]*#([^)\s]+).*"
|
||||||
;; 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)))]
|
|
||||||
|
|
||||||
[:g.svg-raw {:transform (gsh/transform-matrix shape)}
|
;; Replaces the attributes ID's so there are no collisions between shapes
|
||||||
[:> "svg" attrs
|
replace-ids
|
||||||
(for [item childs]
|
(fn [key val]
|
||||||
[:& shape-wrapper {:frame frame
|
(let [[_ from-id] (re-matches rex val)]
|
||||||
:shape item
|
(if (and from-id (contains? ids-mapping from-id))
|
||||||
:key (:id item)}])]])
|
(str/replace val from-id (get ids-mapping from-id))
|
||||||
|
val)))
|
||||||
|
|
||||||
;; Other tags different than root
|
attrs (->> attrs
|
||||||
(map? content)
|
(cd/mapm replace-ids)
|
||||||
[:> (name tag) attrs
|
(clean-attrs))
|
||||||
(for [item childs]
|
|
||||||
[:& shape-wrapper {:frame frame
|
|
||||||
:shape item
|
|
||||||
:key (:id item)}])]
|
|
||||||
|
|
||||||
;; String content
|
attrs (obj/merge! (clj->js attrs)
|
||||||
(string? content) content
|
(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
|
;; TODO CHECK IF IT'S A GRADIENT
|
||||||
|
|
||||||
|
(str/starts-with? color "url")
|
||||||
|
{:color :multiple
|
||||||
|
:opacity :multiple}
|
||||||
|
|
||||||
:else nil))
|
:else nil))
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue