mirror of
https://github.com/penpot/penpot.git
synced 2025-05-09 20:26:37 +02:00
91 lines
3 KiB
Clojure
91 lines
3 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.main.ui.cursors
|
|
(:require
|
|
[app.common.uri :as u]
|
|
[clojure.core :as c]
|
|
[clojure.java.io :as io]
|
|
[cuerdas.core :as str]))
|
|
|
|
(def cursor-folder "images/cursors")
|
|
|
|
(def default-hotspot-x 12)
|
|
(def default-hotspot-y 12)
|
|
(def default-rotation 0)
|
|
(def default-height 20)
|
|
|
|
(defn parse-svg [svg-data]
|
|
(-> svg-data
|
|
;; Remove the <?xml ?> header
|
|
(str/replace #"(?i)<\?xml[^\?]*\?>", "")
|
|
|
|
;; Remove comments
|
|
(str/replace #"<\!\-\-(.*?(?=\-\->))\-\->" "")
|
|
|
|
;; Remove end of line
|
|
(str/replace #"\r?\n|\r" " ")
|
|
|
|
;; Replace double quotes for single
|
|
(str/replace #"\"" "'")
|
|
|
|
;; Remove the svg root tag
|
|
(str/replace #"(?i)<svg.*?>" "")
|
|
|
|
;; And the closing tag
|
|
(str/replace #"(?i)<\/svg>" "")
|
|
|
|
;; Remove some defs that can be redundant
|
|
(str/replace #"<defs.*?/>" "")
|
|
|
|
;; Unifies the spaces into single space
|
|
(str/replace #"\s+" " ")
|
|
|
|
;; Remove spaces at the beginning of the svg
|
|
(str/replace #"^\s+" "")
|
|
|
|
;; Remove spaces at the end
|
|
(str/replace #"\s+$" "")))
|
|
|
|
(defn encode-svg-cursor
|
|
[id rotation x y height]
|
|
(let [svg-path (str cursor-folder "/" (name id) ".svg")
|
|
data (-> svg-path io/resource slurp parse-svg)
|
|
data (u/percent-encode data)
|
|
|
|
data (if rotation
|
|
(str/fmt "%3Cg transform='rotate(%s 8,8)'%3E%s%3C/g%3E" rotation data)
|
|
data)]
|
|
(str "url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' width='20px' "
|
|
"height='" height "px' %3E" data "%3C/svg%3E\") " x " " y ", auto")))
|
|
|
|
(defmacro cursor-ref
|
|
"Creates a static cursor given its name, rotation and x/y hotspot"
|
|
([id] (encode-svg-cursor id default-rotation default-hotspot-x default-hotspot-y default-height))
|
|
([id rotation] (encode-svg-cursor id rotation default-hotspot-x default-hotspot-y default-height))
|
|
([id rotation x y] (encode-svg-cursor id rotation x y default-height))
|
|
([id rotation x y height] (encode-svg-cursor id rotation x y height)))
|
|
|
|
(defmacro cursor-fn
|
|
"Creates a dynamic cursor that can be rotated in runtime"
|
|
[id initial]
|
|
(let [[cp1 cp2] (-> (encode-svg-cursor id "$$$"
|
|
default-hotspot-x
|
|
default-hotspot-y
|
|
default-height)
|
|
(str/split #"\$\$\$"))]
|
|
`(fn [rot#]
|
|
(str/concat ~cp1 (+ ~initial rot#) ~cp2))))
|
|
|
|
(defmacro collect-cursors
|
|
[]
|
|
(let [ns-info (:ns &env)]
|
|
`(cljs.core/js-obj
|
|
~@(->> (:defs ns-info)
|
|
(map val)
|
|
(filter (fn [entry] (-> entry :meta :cursor)))
|
|
(mapcat (fn [{:keys [name] :as entry}]
|
|
[(-> name c/name str/camel str/capital) name]))))))
|