0
Fork 0
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:
alonso.torres 2021-02-26 22:06:54 +01:00 committed by Andrey Antukh
parent 59022904fb
commit 6e88d3a04c
10 changed files with 194 additions and 143 deletions

File diff suppressed because one or more lines are too long

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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