mirror of
https://github.com/penpot/penpot.git
synced 2025-01-24 07:29:08 -05:00
✨ Adds imported rectangles SVGs
This commit is contained in:
parent
59022904fb
commit
6e88d3a04c
10 changed files with 194 additions and 143 deletions
File diff suppressed because one or more lines are too long
|
@ -281,6 +281,7 @@
|
|||
(d/export gtr/transform-rect)
|
||||
(d/export gtr/update-group-selrect)
|
||||
(d/export gtr/transform-points)
|
||||
(d/export gtr/calculate-adjust-matrix)
|
||||
|
||||
;; PATHS
|
||||
(d/export gsp/content->points)
|
||||
|
|
|
@ -139,11 +139,15 @@
|
|||
|
||||
(defn- calculate-height
|
||||
"Calculates the height of a paralelogram given by the points"
|
||||
[[p1 _ p3 p4]]
|
||||
(let [v1 (gpt/to-vec p3 p4)
|
||||
v2 (gpt/to-vec p4 p1)
|
||||
angle (gpt/angle-with-other v1 v2)]
|
||||
(* (gpt/length v2) (mth/sin (mth/radians angle)))))
|
||||
[[p1 _ _ p4]]
|
||||
(-> (gpt/to-vec p4 p1)
|
||||
(gpt/length)))
|
||||
|
||||
(defn- calculate-width
|
||||
"Calculates the width of a paralelogram given by the points"
|
||||
[[p1 p2 _ _]]
|
||||
(-> (gpt/to-vec p1 p2)
|
||||
(gpt/length)))
|
||||
|
||||
(defn- calculate-rotation
|
||||
"Calculates the rotation between two shapes given the resize vector direction"
|
||||
|
@ -173,7 +177,8 @@
|
|||
"Calculates a matrix that is a series of transformations we have to do to the transformed rectangle so that
|
||||
after applying them the end result is the `shape-pathn-temp`.
|
||||
This is compose of three transformations: skew, resize and rotation"
|
||||
[points-temp points-rec flip-x flip-y]
|
||||
([points-temp points-rec] (calculate-adjust-matrix points-temp points-rec false false))
|
||||
([points-temp points-rec flip-x flip-y]
|
||||
(let [center (gco/center-points points-temp)
|
||||
|
||||
stretch-matrix (gmt/matrix)
|
||||
|
@ -193,7 +198,12 @@
|
|||
h3 (if-not (mth/almost-zero? h2) (/ h1 h2) 1)
|
||||
h3 (if (mth/nan? h3) 1 h3)
|
||||
|
||||
stretch-matrix (gmt/multiply stretch-matrix (gmt/scale-matrix (gpt/point 1 h3)))
|
||||
w1 (max 1 (calculate-width points-temp))
|
||||
w2 (max 1 (calculate-width (transform-points points-rec center stretch-matrix)))
|
||||
w3 (if-not (mth/almost-zero? w2) (/ w1 w2) 1)
|
||||
w3 (if (mth/nan? w3) 1 w3)
|
||||
|
||||
stretch-matrix (gmt/multiply stretch-matrix (gmt/scale-matrix (gpt/point w3 h3)))
|
||||
|
||||
rotation-angle (calculate-rotation
|
||||
center
|
||||
|
@ -204,13 +214,12 @@
|
|||
|
||||
stretch-matrix (gmt/multiply (gmt/rotate-matrix rotation-angle) stretch-matrix)
|
||||
|
||||
|
||||
;; This is the inverse to be able to remove the transformation
|
||||
stretch-matrix-inverse (-> (gmt/matrix)
|
||||
(gmt/scale (gpt/point 1 (/ 1 h3)))
|
||||
(gmt/scale (gpt/point (/ 1 w3) (/ 1 h3)))
|
||||
(gmt/skew (- skew-angle) 0)
|
||||
(gmt/rotate (- rotation-angle)))]
|
||||
[stretch-matrix stretch-matrix-inverse]))
|
||||
[stretch-matrix stretch-matrix-inverse rotation-angle])))
|
||||
|
||||
(defn apply-transform
|
||||
"Given a new set of points transformed, set up the rectangle so it keeps
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -17,8 +17,8 @@
|
|||
[app.common.uuid :as uuid]
|
||||
[app.main.data.workspace.common :as dwc]
|
||||
[app.util.color :as uc]
|
||||
[app.util.data :as ud]
|
||||
[app.util.geom.path :as ugp]
|
||||
[app.util.object :as obj]
|
||||
[app.util.svg :as usvg]
|
||||
[beicon.core :as rx]
|
||||
[cuerdas.core :as str]
|
||||
|
@ -58,12 +58,12 @@
|
|||
(get-in shape [:svg-attrs :fill-opacity])
|
||||
(-> (update :svg-attrs dissoc :fill-opacity)
|
||||
(assoc :fill-opacity (-> (get-in shape [:svg-attrs :fill-opacity])
|
||||
(ud/parse-float))))
|
||||
(d/parse-double))))
|
||||
|
||||
(get-in shape [:svg-attrs :style :fill-opacity])
|
||||
(-> (update :svg-attrs dissoc :fill-opacity)
|
||||
(assoc :fill-opacity (-> (get-in shape [:svg-attrs :style :fill-opacity])
|
||||
(ud/parse-float))))))
|
||||
(d/parse-double))))))
|
||||
|
||||
(defonce default-stroke {:stroke-color "#000000"
|
||||
:stroke-opacity 1
|
||||
|
@ -84,12 +84,12 @@
|
|||
(get-in shape [:svg-attrs :stroke-width])
|
||||
(-> (update :svg-attrs dissoc :stroke-width)
|
||||
(assoc :stroke-width (-> (get-in shape [:svg-attrs :stroke-width])
|
||||
(ud/parse-float))))
|
||||
(d/parse-double))))
|
||||
|
||||
(get-in shape [:svg-attrs :style :stroke-width])
|
||||
(-> (update-in [:svg-attrs :style] dissoc :stroke-width)
|
||||
(assoc :stroke-width (-> (get-in shape [:svg-attrs :style :stroke-width])
|
||||
(ud/parse-float)))))]
|
||||
(d/parse-double)))))]
|
||||
shape
|
||||
#_(if (d/any-key? shape :stroke-color :stroke-opacity :stroke-width)
|
||||
(merge default-stroke shape)
|
||||
|
@ -131,10 +131,12 @@
|
|||
svg-transform
|
||||
(gsh/transform-content svg-transform))
|
||||
|
||||
attrs (d/update-when attrs :transform #(-> (usvg/parse-transform %) str))
|
||||
;; attrs (d/update-when attrs :transform #(-> (usvg/parse-transform %) str))
|
||||
|
||||
selrect (gsh/content->selrect content)
|
||||
points (gsh/rect->points selrect)]
|
||||
points (gsh/rect->points selrect)
|
||||
|
||||
origin (gpt/negate (gpt/point svg-data))]
|
||||
(-> {:id (uuid/next)
|
||||
:type :path
|
||||
:name name
|
||||
|
@ -145,7 +147,78 @@
|
|||
(assoc :svg-viewbox (select-keys selrect [:x :y :width :height]))
|
||||
(assoc :svg-attrs (dissoc attrs :d :transform))
|
||||
(assoc :svg-transform svg-transform)
|
||||
(gsh/translate-to-frame svg-data))))
|
||||
(gsh/translate-to-frame origin))))
|
||||
|
||||
|
||||
(defn inverse-matrix [{:keys [a b c d e f]}]
|
||||
(let [dom-matrix (-> (js/DOMMatrix.)
|
||||
(obj/set! "a" a)
|
||||
(obj/set! "b" b)
|
||||
(obj/set! "c" c)
|
||||
(obj/set! "d" d)
|
||||
(obj/set! "e" e)
|
||||
(obj/set! "f" f)
|
||||
(.inverse))]
|
||||
(gmt/matrix (obj/get dom-matrix "a")
|
||||
(obj/get dom-matrix "b")
|
||||
(obj/get dom-matrix "c")
|
||||
(obj/get dom-matrix "d")
|
||||
(obj/get dom-matrix "e")
|
||||
(obj/get dom-matrix "f"))))
|
||||
|
||||
(defn calculate-rect-metadata [rect-data transform]
|
||||
(let [points (-> (gsh/rect->points rect-data)
|
||||
(gsh/transform-points transform))
|
||||
|
||||
center (gsh/center-points points)
|
||||
|
||||
rect-shape (-> (gsh/make-centered-rect center (:width rect-data) (:height rect-data))
|
||||
(update :width max 1)
|
||||
(update :height max 1))
|
||||
|
||||
selrect (gsh/rect->selrect rect-shape)
|
||||
|
||||
rect-points (gsh/rect->points rect-shape)
|
||||
|
||||
[shape-transform shape-transform-inv rotation]
|
||||
(gsh/calculate-adjust-matrix points rect-points)]
|
||||
|
||||
(merge rect-shape
|
||||
{:selrect selrect
|
||||
:points points
|
||||
:rotation rotation
|
||||
:transform shape-transform
|
||||
:transform-inverse shape-transform-inv})))
|
||||
|
||||
(def default-rect {:x 0 :y 0 :width 1 :height 1 :rx 0 :ry 0})
|
||||
|
||||
(defn create-rect-shape [name frame-id svg-data {:keys [attrs] :as data}]
|
||||
(let [svg-transform (usvg/parse-transform (:transform attrs))
|
||||
transform (->> svg-transform
|
||||
(gmt/transform-in (gpt/point svg-data)))
|
||||
|
||||
rect (->> (select-keys attrs [:x :y :width :height])
|
||||
(d/mapm #(d/parse-double %2)))
|
||||
|
||||
origin (gpt/negate (gpt/point svg-data))
|
||||
|
||||
rect-data (-> (merge default-rect rect)
|
||||
(update :x - (:x origin))
|
||||
(update :y - (:y origin)))
|
||||
|
||||
metadata (calculate-rect-metadata rect-data transform)]
|
||||
(-> {:id (uuid/next)
|
||||
:type :rect
|
||||
:name name
|
||||
:frame-id frame-id}
|
||||
(cond->
|
||||
(contains? attrs :rx) (:rx attrs)
|
||||
(contains? attrs :rx) (:rx attrs))
|
||||
|
||||
(merge metadata)
|
||||
(assoc :svg-transform transform)
|
||||
(assoc :svg-viewbox (select-keys rect [:x :y :width :height]))
|
||||
(assoc :svg-attrs (dissoc attrs :x :y :width :height :rx :ry :transform)))))
|
||||
|
||||
(defn create-group [name frame-id svg-data {:keys [attrs]}]
|
||||
(let [{:keys [x y width height]} svg-data]
|
||||
|
@ -167,11 +240,13 @@
|
|||
att-refs (usvg/find-attr-references attrs)
|
||||
references (usvg/find-def-references (:defs svg-data) att-refs)]
|
||||
|
||||
;; SVG graphic elements
|
||||
;; :circle :ellipse :image :line :path :polygon :polyline :rect :text :use
|
||||
(-> (case tag
|
||||
:g (create-group name frame-id svg-data element-data)
|
||||
;; :rect (parse-rect data)
|
||||
:path (create-path-shape name frame-id (gpt/negate (gpt/point svg-data)) element-data)
|
||||
(create-raw-svg name frame-id svg-data element-data))
|
||||
:rect (create-rect-shape name frame-id svg-data element-data)
|
||||
:path (create-path-shape name frame-id svg-data element-data)
|
||||
#_other (create-raw-svg name frame-id svg-data element-data))
|
||||
|
||||
(assoc :svg-defs (select-keys (:defs svg-data) references))
|
||||
(setup-fill)
|
||||
|
|
|
@ -27,7 +27,8 @@
|
|||
(def svg-ids-ctx (mf/create-context nil))
|
||||
|
||||
(defn set-styles [attrs shape]
|
||||
(let [custom-attrs (usa/extract-style-attrs shape)
|
||||
(let [custom-attrs (-> (usa/extract-style-attrs shape)
|
||||
(obj/without ["transform"]))
|
||||
attrs (cond-> attrs
|
||||
(string? (:style attrs)) usvg/clean-attrs)
|
||||
style (obj/merge! (clj->js (:style attrs {}))
|
||||
|
|
|
@ -44,8 +44,6 @@
|
|||
:style {:stroke color
|
||||
:fill "transparent"
|
||||
:stroke-width "1px"
|
||||
:stroke-opacity 0.5
|
||||
:stroke-dasharray 4
|
||||
:pointer-events "none"}}])
|
||||
|
||||
(mf/defc render-rect-points [{:keys [points color]}]
|
||||
|
@ -62,7 +60,7 @@
|
|||
[props]
|
||||
(let [shape (-> (unchecked-get props "shape"))
|
||||
frame (unchecked-get props "frame")
|
||||
selrect (gsh/points->selrect (-> shape :points))
|
||||
bounding-box (gsh/points->selrect (-> shape :points))
|
||||
shape-center (gsh/center-shape shape)
|
||||
line-color (rdcolor #js {:seed (str (:id shape))})
|
||||
zoom (mf/deref refs/selected-zoom)
|
||||
|
@ -71,25 +69,30 @@
|
|||
(map gsh/transform-shape))]
|
||||
|
||||
[:g.bounding-box
|
||||
[:text {:x (:x selrect)
|
||||
:y (- (:y selrect) 5)
|
||||
[:text {:x (:x bounding-box)
|
||||
:y (- (:y bounding-box) 5)
|
||||
:font-size 10
|
||||
:fill line-color
|
||||
:stroke "white"
|
||||
:stroke-width 0.1}
|
||||
(str/format "%s - (%s, %s)" (str/slice (str (:id shape)) 0 8) (fixed (:x selrect)) (fixed (:y selrect)))]
|
||||
(str/format "%s - (%s, %s)" (str/slice (str (:id shape)) 0 8) (fixed (:x bounding-box)) (fixed (:y bounding-box)))]
|
||||
|
||||
[:g.center
|
||||
[:& cross-point {:point shape-center
|
||||
:zoom zoom
|
||||
:color line-color}]
|
||||
:color line-color}]]
|
||||
|
||||
[:g.points
|
||||
(for [point (:points shape)]
|
||||
[:& cross-point {:point point
|
||||
:zoom zoom
|
||||
:color line-color}])
|
||||
#_[:& render-rect-points {:points (:points shape)
|
||||
:color line-color}]]
|
||||
|
||||
[:& render-rect-points {:points (:points shape)
|
||||
[:g.selrect
|
||||
[:& render-rect {:rect (:selrect shape)
|
||||
;; :transform (gsh/transform-matrix shape)
|
||||
:color line-color}]
|
||||
|
||||
[:& render-rect {:rect selrect
|
||||
:color line-color}]]))
|
||||
#_[:& render-rect {:rect bounding-box
|
||||
:color line-color}]]]))
|
||||
|
|
|
@ -225,7 +225,7 @@
|
|||
"skewY" (apply gmt/skew-matrix (format-skew-y-params params))))
|
||||
|
||||
(defn parse-transform [transform-attr]
|
||||
(when transform-attr
|
||||
(if transform-attr
|
||||
(let [process-matrix
|
||||
(fn [[_ type params]]
|
||||
(let [params (->> (re-seq params-regex params)
|
||||
|
@ -236,5 +236,6 @@
|
|||
matrices (->> (re-seq matrices-regex transform-attr)
|
||||
(map process-matrix)
|
||||
(map to-matrix))]
|
||||
(reduce gmt/multiply (gmt/matrix) matrices))))
|
||||
(reduce gmt/multiply (gmt/matrix) matrices))
|
||||
(gmt/matrix)))
|
||||
|
||||
|
|
94
vendor/svgclean/main.js
vendored
94
vendor/svgclean/main.js
vendored
|
@ -1,74 +1,38 @@
|
|||
/*
|
||||
|
||||
const plugins = [
|
||||
{removeDimensions: true},
|
||||
{removeScriptElement: true},
|
||||
{removeViewBox: false},
|
||||
{moveElemsAttrsToGroup: false},
|
||||
{convertStyleToAttrs: false},
|
||||
{removeUselessDefs: false},
|
||||
{convertPathData: {
|
||||
{ "minifyStyles" : false },
|
||||
{ "convertStyleToAttrs" : false },
|
||||
{
|
||||
"cleanupIDs" : {
|
||||
remove: false,
|
||||
minify: false,
|
||||
force: false
|
||||
}
|
||||
},
|
||||
{ "cleanupListOfValues" : true },
|
||||
{ "removeUnknownsAndDefaults" : false },
|
||||
{ "removeViewBox" : false },
|
||||
{ "convertShapeToPath" : false },
|
||||
{ "convertEllipseToCircle" : false },
|
||||
{ "moveElemsAttrsToGroup" : false },
|
||||
{ "collapseGroups" : false },
|
||||
{
|
||||
"convertPathData" : {
|
||||
lineShorthands: false,
|
||||
curveSmoothShorthands: false,
|
||||
forceAbsolutePath: true,
|
||||
}}
|
||||
}
|
||||
},
|
||||
{ "convertTransform" : false },
|
||||
{ "removeEmptyContainers" : false },
|
||||
{ "mergePaths" : false },
|
||||
{ "sortDefsChildren" : false },
|
||||
{ "removeDimensions" : true },
|
||||
{ "removeStyleElement" : true },
|
||||
{ "removeScriptElement" : true },
|
||||
{ "removeOffCanvasPaths" : true },
|
||||
];
|
||||
*/
|
||||
|
||||
const plugins = [
|
||||
// 'removeDoctype',
|
||||
// 'removeXMLProcInst',
|
||||
// 'removeComments',
|
||||
// 'removeMetadata',
|
||||
// 'removeXMLNS',
|
||||
// 'removeEditorsNSData',
|
||||
// 'cleanupAttrs',
|
||||
// 'inlineStyles',
|
||||
// 'minifyStyles',
|
||||
// 'convertStyleToAttrs'
|
||||
// 'cleanupIDs',
|
||||
// 'prefixIds',
|
||||
// 'removeRasterImages',
|
||||
// 'removeUselessDefs',
|
||||
// 'cleanupNumericValues',
|
||||
// 'cleanupListOfValues',
|
||||
// 'convertColors',
|
||||
// 'removeUnknownsAndDefaults',
|
||||
// 'removeNonInheritableGroupAttrs',
|
||||
// 'removeUselessStrokeAndFill',
|
||||
// 'removeViewBox',
|
||||
// 'cleanupEnableBackground',
|
||||
// 'removeHiddenElems',
|
||||
// 'removeEmptyText',
|
||||
// 'convertShapeToPath',
|
||||
// 'convertEllipseToCircle',
|
||||
// 'moveElemsAttrsToGroup',
|
||||
// 'moveGroupAttrsToElems',
|
||||
// 'collapseGroups',
|
||||
// {'convertPathData': {
|
||||
// 'lineShorthands': false,
|
||||
// 'curveSmoothShorthands': false,
|
||||
// 'forceAbsolutePath': true,
|
||||
// }},
|
||||
// 'convertTransform',
|
||||
// 'removeEmptyAttrs',
|
||||
// 'removeEmptyContainers',
|
||||
// 'mergePaths',
|
||||
// 'removeUnusedNS',
|
||||
// 'sortAttrs',
|
||||
// 'sortDefsChildren',
|
||||
// 'removeTitle',
|
||||
// 'removeDesc',
|
||||
// 'removeDimensions',
|
||||
// 'removeAttrs',
|
||||
// 'removeAttributesBySelector',
|
||||
// 'removeElementsByAttr',
|
||||
// 'addClassesToSVGElement',
|
||||
// 'removeStyleElement',
|
||||
// 'removeScriptElement',
|
||||
// 'addAttributesToSVGElement',
|
||||
// 'removeOffCanvasPaths',
|
||||
// 'reusePaths',
|
||||
];
|
||||
|
||||
const svgc = require("./src/svgclean.js");
|
||||
const inst = svgc.configure({plugins});
|
||||
|
|
|
@ -38,9 +38,6 @@ exports.fn = function(item) {
|
|||
!item.isEmpty() &&
|
||||
!item.someAttr(function(attr) {
|
||||
return ~referencesProps.indexOf(attr.name) && ~attr.value.indexOf('url(');
|
||||
}) &&
|
||||
item.content.every(function(inner) {
|
||||
return inner.isElem(pathElems) && !inner.hasAttr('id');
|
||||
})
|
||||
) {
|
||||
item.content.forEach(function(inner) {
|
||||
|
|
Loading…
Add table
Reference in a new issue