mirror of
https://github.com/penpot/penpot.git
synced 2026-04-29 21:28:20 +00:00
138 lines
4.0 KiB
Clojure
138 lines
4.0 KiB
Clojure
;; This Source Code Form is subject to the terms of the Mozilla Public
|
|
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
;;
|
|
;; Copyright (c) KALEIDOS INC
|
|
|
|
(ns app.util.path.format
|
|
(:require
|
|
[app.common.svg.path.command :as upc]
|
|
[app.common.svg.path.subpath :refer [pt=]]
|
|
[app.util.array :as arr]))
|
|
|
|
;; TODO: move to common
|
|
|
|
(def path-precision 3)
|
|
|
|
(defn- join-params
|
|
([a]
|
|
(js* "\"\"+~{}"
|
|
(.toFixed a path-precision)))
|
|
([a b]
|
|
(js* "\"\"+~{}+\",\"+~{}"
|
|
(.toFixed a path-precision)
|
|
(.toFixed b path-precision)))
|
|
([a b c]
|
|
(js* "\"\"+~{}+\",\"+~{}+\",\"+~{}"
|
|
(.toFixed a path-precision)
|
|
(.toFixed b path-precision)
|
|
(.toFixed c path-precision)))
|
|
([a b c d]
|
|
(js* "\"\"+~{}+\",\"+~{}+\",\"+~{}+\",\"+~{}"
|
|
(.toFixed a path-precision)
|
|
(.toFixed b path-precision)
|
|
(.toFixed c path-precision)
|
|
(.toFixed d path-precision)))
|
|
([a b c d e]
|
|
(js* "\"\"+~{}+\",\"+~{}+\",\"+~{}+\",\"+~{}+\",\"+~{}"
|
|
(.toFixed a path-precision)
|
|
(.toFixed b path-precision)
|
|
(.toFixed c path-precision)
|
|
(.toFixed d path-precision)
|
|
(.toFixed e path-precision)))
|
|
([a b c d e f]
|
|
(js* "\"\"+~{}+\",\"+~{}+\",\"+~{}+\",\"+~{}+\",\"+~{}+\",\"+~{}"
|
|
(.toFixed a path-precision)
|
|
(.toFixed b path-precision)
|
|
(.toFixed c path-precision)
|
|
(.toFixed d path-precision)
|
|
(.toFixed e path-precision)
|
|
(.toFixed f path-precision)))
|
|
([a b c d e f g]
|
|
(js* "\"\"+~{}+\",\"+~{}+\",\"+~{}+\",\"+~{}+\",\"+~{}+\",\"+~{}+\",\"+~{}"
|
|
(.toFixed a path-precision)
|
|
(.toFixed b path-precision)
|
|
(.toFixed c path-precision)
|
|
(.toFixed d path-precision)
|
|
(.toFixed e path-precision)
|
|
(.toFixed f path-precision)
|
|
(.toFixed g path-precision))))
|
|
|
|
(defn- translate-params
|
|
[command {:keys [x y] :as params}]
|
|
(case command
|
|
(:move-to :line-to :smooth-quadratic-bezier-curve-to)
|
|
(join-params x y)
|
|
|
|
:close-path
|
|
""
|
|
|
|
(:line-to-horizontal :line-to-vertical)
|
|
(:value params)
|
|
|
|
:curve-to
|
|
(let [{:keys [c1x c1y c2x c2y]} params]
|
|
(join-params (or c1x x) (or c1y y) (or c2x x) (or c2y y) x y))
|
|
|
|
(:smooth-curve-to :quadratic-bezier-curve-to)
|
|
(let [{:keys [cx cy]} params]
|
|
(join-params cx cy x y))
|
|
|
|
:elliptical-arc
|
|
(let [{:keys [rx ry x-axis-rotation large-arc-flag sweep-flag]} params]
|
|
(join-params rx ry x-axis-rotation large-arc-flag sweep-flag x y))
|
|
|
|
""))
|
|
|
|
(defn- translate-command
|
|
[cname]
|
|
(case cname
|
|
:move-to "M"
|
|
:close-path "Z"
|
|
:line-to "L"
|
|
:line-to-horizontal "H"
|
|
:line-to-vertical "V"
|
|
:curve-to "C"
|
|
:smooth-curve-to "S"
|
|
:quadratic-bezier-curve-to "Q"
|
|
:smooth-quadratic-bezier-curve-to "T"
|
|
:elliptical-arc "A"
|
|
""))
|
|
|
|
|
|
(defn- command->string
|
|
[{:keys [command relative params]}]
|
|
(let [cmd (cond-> (translate-command command)
|
|
relative (.toLowerCase))
|
|
prm (translate-params command params)]
|
|
(js* "~{} + ~{}" cmd prm)))
|
|
|
|
(defn- set-point
|
|
[command {:keys [x y]}]
|
|
(update command :params assoc :x x :y y))
|
|
|
|
(defn format-path [content]
|
|
(try
|
|
(let [result (make-array (count content))]
|
|
(reduce (fn [last-move current]
|
|
(let [point (upc/command->point current)
|
|
current-move? (= :move-to (:command current))
|
|
last-move (if current-move? point last-move)]
|
|
|
|
(if (and (not current-move?) (pt= last-move point))
|
|
(arr/conj! result (command->string (set-point current last-move)))
|
|
(arr/conj! result (command->string current)))
|
|
|
|
(when (and (not current-move?) (pt= last-move point))
|
|
(arr/conj! result "Z"))
|
|
|
|
last-move))
|
|
nil
|
|
content)
|
|
(.join ^js result ""))
|
|
|
|
(catch :default err
|
|
(.error js/console err)
|
|
nil)))
|
|
|