0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-01-08 07:50:43 -05:00

🐛 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]))
(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]}]
(cond (string? tag) tag
(keyword? tag) (name tag)
@ -38,9 +68,15 @@
:else (str tag)))
(defn setup-fill [shape attrs]
(-> shape
(assoc :fill-color (:fill attrs "#000000"))
(assoc :fill-opacity (ud/parse-float (:fill-opacity attrs "1")))))
(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
(assoc :fill-color fill-color)
(assoc :fill-opacity fill-opacity))))
(defn setup-stroke [shape attrs]
(-> shape
@ -67,7 +103,7 @@
:height height
:x x
:y y
:content data}
:content (if (map? data) (update data :attrs clean-attrs) data)}
(gsh/setup-selrect)))
(defn parse-path [name frame-id {:keys [attrs] :as data}]
@ -78,10 +114,6 @@
:type :path
:name name
:frame-id frame-id
;; :width width
;; :height height
;; :x x
;; :y y
:content content
:selrect selrect
:points points}

View file

@ -34,10 +34,16 @@
(:fill-color-gradient shape)
(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")
: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)))
(defn add-stroke [attrs shape render-id]
@ -58,8 +64,10 @@
(defn extract-style-attrs
([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)
(add-border-radius shape)
(add-fill shape render-id)
(add-stroke shape render-id)))))
(obj/set! "style" styles)))))

View file

@ -23,35 +23,6 @@
;; 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]
(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
"Converts the viewBox into a rectangle"
[vbox]
@ -106,18 +77,24 @@
;; 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)))
(fn replace-ids [key val]
(if (map? val)
(cd/mapm replace-ids 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))))
attrs (->> attrs
(cd/mapm replace-ids)
(clean-attrs))
attrs (cd/mapm replace-ids attrs)
attrs (obj/merge! (clj->js attrs)
(usa/extract-style-attrs shape))
custom-attrs (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])]

View file

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

View file

@ -114,3 +114,7 @@
(= color :multiple)
(= gradient :multiple)
(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},
{removeViewBox: false},
{moveElemsAttrsToGroup: false},
{convertStyleToAttrs: false},
{convertPathData: {
lineShorthands: false,
curveSmoothShorthands: false,