🐛 Fixes problems with svg imports

This commit is contained in:
alonso.torres 2021-01-14 22:47:03 +01:00 committed by Andrey Antukh
parent fd4c61ece7
commit 999e2f6633
8 changed files with 100 additions and 74 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -31,6 +31,36 @@
[width height])) [width height]))
(defn clean-attrs
"Transforms attributes to their react equivalent"
[attrs]
(letfn [(transform-key [key]
(-> (name key)
(str/replace ":" "-")
(str/camel)
(keyword)))
(format-styles [style-str]
(->> (str/split style-str ";")
(map str/trim)
(map #(str/split % ":"))
(group-by first)
(map (fn [[key val]]
(vector
(transform-key key)
(second (first val)))))
(into {})))
(map-fn [[key val]]
(cond
(= key :class) [:className val]
(= key :style) [key (format-styles val)]
:else (vector (transform-key key) val)))]
(->> attrs
(map map-fn)
(into {}))))
(defn tag-name [{:keys [tag]}] (defn tag-name [{:keys [tag]}]
(cond (string? tag) tag (cond (string? tag) tag
(keyword? tag) (name tag) (keyword? tag) (name tag)
@ -38,9 +68,15 @@
:else (str tag))) :else (str tag)))
(defn setup-fill [shape attrs] (defn setup-fill [shape attrs]
(let [fill-color (or (get-in attrs [:fill])
(get-in attrs [:style :fill])
"#000000")
fill-opacity (ud/parse-float (or (get-in attrs [:fill-opacity])
(get-in attrs [:style :fill-opacity])
"1"))]
(-> shape (-> shape
(assoc :fill-color (:fill attrs "#000000")) (assoc :fill-color fill-color)
(assoc :fill-opacity (ud/parse-float (:fill-opacity attrs "1"))))) (assoc :fill-opacity fill-opacity))))
(defn setup-stroke [shape attrs] (defn setup-stroke [shape attrs]
(-> shape (-> shape
@ -67,7 +103,7 @@
:height height :height height
:x x :x x
:y y :y y
:content data} :content (if (map? data) (update data :attrs clean-attrs) data)}
(gsh/setup-selrect))) (gsh/setup-selrect)))
(defn parse-path [name frame-id {:keys [attrs] :as data}] (defn parse-path [name frame-id {:keys [attrs] :as data}]
@ -78,10 +114,6 @@
:type :path :type :path
:name name :name name
:frame-id frame-id :frame-id frame-id
;; :width width
;; :height height
;; :x x
;; :y y
:content content :content content
:selrect selrect :selrect selrect
:points points} :points points}

View file

@ -34,10 +34,16 @@
(:fill-color-gradient shape) (:fill-color-gradient shape)
(obj/merge! attrs #js {:fill (str/format "url(#%s)" fill-color-gradient-id)}) (obj/merge! attrs #js {:fill (str/format "url(#%s)" fill-color-gradient-id)})
(not (:fill-color-gradient shape)) (and (not= :svg-raw (:type shape))
(not (:fill-color-gradient shape)))
(obj/merge! attrs #js {:fill (or (:fill-color shape) "transparent") (obj/merge! attrs #js {:fill (or (:fill-color shape) "transparent")
:fillOpacity (:fill-opacity shape nil)}) :fillOpacity (:fill-opacity shape nil)})
(and (= :svg-raw (:type shape))
(or (:fill-opacity shape) (:fill-color shape)))
(obj/merge! attrs #js {:fill (:fill-color shape)
:fillOpacity (:fill-opacity shape nil)})
:else attrs))) :else attrs)))
(defn add-stroke [attrs shape render-id] (defn add-stroke [attrs shape render-id]
@ -58,8 +64,10 @@
(defn extract-style-attrs (defn extract-style-attrs
([shape] ([shape]
(let [render-id (mf/use-ctx muc/render-ctx)] (let [render-id (mf/use-ctx muc/render-ctx)
styles (-> (obj/new)
(add-fill shape render-id)
(add-stroke shape render-id))]
(-> (obj/new) (-> (obj/new)
(add-border-radius shape) (add-border-radius shape)
(add-fill shape render-id) (obj/set! "style" styles)))))
(add-stroke shape render-id)))))

View file

@ -23,35 +23,6 @@
;; Context to store a re-mapping of the ids ;; Context to store a re-mapping of the ids
(def svg-ids-ctx (mf/create-context nil)) (def svg-ids-ctx (mf/create-context nil))
(defn clean-attrs
"Transforms attributes to their react equivalent"
[attrs]
(letfn [(transform-key [key]
(-> (name key)
(str/replace ":" "-")
(str/camel)
(keyword)))
(format-styles [style-str]
(->> (str/split style-str ";")
(map str/trim)
(map #(str/split % ":"))
(group-by first)
(map (fn [[key val]]
(vector
(transform-key key)
(second (first val)))))
(into {})))
(map-fn [[key val]]
(cond
(= key :style) [key (format-styles val)]
:else (vector (transform-key key) val)))]
(->> attrs
(map map-fn)
(into {}))))
(defn vbox->rect (defn vbox->rect
"Converts the viewBox into a rectangle" "Converts the viewBox into a rectangle"
[vbox] [vbox]
@ -106,18 +77,24 @@
;; Replaces the attributes ID's so there are no collisions between shapes ;; Replaces the attributes ID's so there are no collisions between shapes
replace-ids replace-ids
(fn [key val] (fn replace-ids [key val]
(if (map? val)
(cd/mapm replace-ids val)
(let [[_ from-id] (re-matches rex val)] (let [[_ from-id] (re-matches rex val)]
(if (and from-id (contains? ids-mapping from-id)) (if (and from-id (contains? ids-mapping from-id))
(str/replace val from-id (get ids-mapping from-id)) (str/replace val from-id (get ids-mapping from-id))
val))) val))))
attrs (->> attrs attrs (cd/mapm replace-ids attrs)
(cd/mapm replace-ids)
(clean-attrs))
attrs (obj/merge! (clj->js attrs) custom-attrs (usa/extract-style-attrs shape)
(usa/extract-style-attrs shape))
style (obj/merge! (clj->js (:style attrs {}))
(obj/get custom-attrs "style"))
attrs (-> (clj->js attrs)
(obj/merge! custom-attrs)
(obj/set! "style" style))
element-id (get-in content [:attrs :id])] element-id (get-in content [:attrs :id])]

View file

@ -12,6 +12,7 @@
[rumext.alpha :as mf] [rumext.alpha :as mf]
[cuerdas.core :as str] [cuerdas.core :as str]
[app.util.data :as d] [app.util.data :as d]
[app.util.color :as uc]
[app.main.ui.workspace.sidebar.options.measures :refer [measure-attrs measures-menu]] [app.main.ui.workspace.sidebar.options.measures :refer [measure-attrs measures-menu]]
[app.main.ui.workspace.sidebar.options.fill :refer [fill-attrs fill-menu]] [app.main.ui.workspace.sidebar.options.fill :refer [fill-attrs fill-menu]]
[app.main.ui.workspace.sidebar.options.stroke :refer [stroke-attrs stroke-menu]] [app.main.ui.workspace.sidebar.options.stroke :refer [stroke-attrs stroke-menu]]
@ -28,29 +29,27 @@
(str "#" r r g g b b))) (str "#" r r g g b b)))
(defn parse-color [color] (defn parse-color [color]
(try
(cond (cond
(or (not color) (= color "none")) nil (or (not color) (= color "none")) nil
(and (str/starts-with? color "#") (= (count color) 4))
{:color (shorthex->longhex color)
:opacity 1}
(and (str/starts-with? color "#") (= (count color) 9))
{:color (subs color 1 6)
:opacity (-> (subs color 7 2) (hex->number))}
;; TODO CHECK IF IT'S A GRADIENT ;; TODO CHECK IF IT'S A GRADIENT
(str/starts-with? color "url") (str/starts-with? color "url")
{:color :multiple {:color :multiple
:opacity :multiple} :opacity :multiple}
:else nil)) :else {:color (uc/parse-color color)
:opacity 1})
(catch :default e
(.error js/console "Error parsing color" e)
nil)))
(defn get-fill-values [shape] (defn get-fill-values [shape]
(let [fill-values (or (select-keys shape fill-attrs)) (let [fill-values (or (select-keys shape fill-attrs))
color (-> (get-in shape [:content :attrs :fill]) color (-> (or (get-in shape [:content :attrs :fill])
(get-in shape [:content :attrs :style :fill]))
(parse-color)) (parse-color))
fill-values (if (and (empty? fill-values) color) fill-values (if (and (empty? fill-values) color)
@ -61,15 +60,20 @@
(defn get-stroke-values [shape] (defn get-stroke-values [shape]
(let [stroke-values (or (select-keys shape stroke-attrs)) (let [stroke-values (or (select-keys shape stroke-attrs))
color (-> (get-in shape [:content :attrs :stroke]) color (-> (or (get-in shape [:content :attrs :stroke])
(get-in shape [:content :attrs :style :stroke]))
(parse-color)) (parse-color))
stroke-color (:color color "#000000") stroke-color (:color color "#000000")
stroke-opacity (:opacity color 1) stroke-opacity (:opacity color 1)
stroke-style (-> (get-in shape [:content :attrs :stroke-style] (if color "solid" "none")) stroke-style (-> (or (get-in shape [:content :attrs :stroke-style])
(get-in shape [:content :attrs :style :stroke-style])
(if color "solid" "none"))
keyword) keyword)
stroke-alignment :center stroke-alignment :center
stroke-width (-> (get-in shape [:content :attrs :stroke-width] "1") stroke-width (-> (or (get-in shape [:content :attrs :stroke-width])
(get-in shape [:content :attrs :style :stroke-width])
"1")
(d/parse-int)) (d/parse-int))
stroke-values (if (empty? stroke-values) stroke-values (if (empty? stroke-values)

View file

@ -114,3 +114,7 @@
(= color :multiple) (= color :multiple)
(= gradient :multiple) (= gradient :multiple)
(and gradient color))) (and gradient color)))
(defn parse-color [^string color-str]
(let [result (gcolor/parse color-str)]
(str (.-hex ^js result))))

View file

@ -3,6 +3,7 @@ const plugins = [
{removeScriptElement: true}, {removeScriptElement: true},
{removeViewBox: false}, {removeViewBox: false},
{moveElemsAttrsToGroup: false}, {moveElemsAttrsToGroup: false},
{convertStyleToAttrs: false},
{convertPathData: { {convertPathData: {
lineShorthands: false, lineShorthands: false,
curveSmoothShorthands: false, curveSmoothShorthands: false,