🐛 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)] 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))

View file

@ -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]

View file

@ -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))))

View file

@ -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))