🐛 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]
(-> shape (let [fill-color (or (get-in attrs [:fill])
(assoc :fill-color (:fill attrs "#000000")) (get-in attrs [:style :fill])
(assoc :fill-opacity (ud/parse-float (:fill-opacity attrs "1"))))) "#000000")
fill-opacity (ud/parse-float (or (get-in attrs [:fill-opacity])
(get-in attrs [:style :fill-opacity])
"1"))]
(-> shape
(assoc :fill-color fill-color)
(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]
(let [[_ from-id] (re-matches rex val)] (if (map? val)
(if (and from-id (contains? ids-mapping from-id)) (cd/mapm replace-ids val)
(str/replace val from-id (get ids-mapping from-id)) (let [[_ from-id] (re-matches rex val)]
val))) (if (and from-id (contains? ids-mapping from-id))
(str/replace val from-id (get ids-mapping from-id))
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]
(cond (try
(or (not color) (= color "none")) nil (cond
(or (not color) (= color "none")) nil
(and (str/starts-with? color "#") (= (count color) 4)) ;; TODO CHECK IF IT'S A GRADIENT
{:color (shorthex->longhex color) (str/starts-with? color "url")
:opacity 1} {:color :multiple
:opacity :multiple}
(and (str/starts-with? color "#") (= (count color) 9)) :else {:color (uc/parse-color color)
{:color (subs color 1 6) :opacity 1})
:opacity (-> (subs color 7 2) (hex->number))}
;; TODO CHECK IF IT'S A GRADIENT (catch :default e
(.error js/console "Error parsing color" e)
(str/starts-with? color "url") nil)))
{:color :multiple
:opacity :multiple}
:else 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,