0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-03-11 15:21:18 -05:00

🎉 Adds infrastructure to add cursors

This commit is contained in:
alonso.torres 2020-06-01 14:57:39 +02:00
parent c4664ab7f9
commit b3237524bd
5 changed files with 156 additions and 3 deletions

View file

@ -33,6 +33,9 @@
thheller/shadow-cljs {:mvn/version "2.8.110"}
lambdaisland/uri {:mvn/version "1.3.45"
:exclusions [org.clojure/data.json]}
;; i18n parsing
carocad/parcera {:mvn/version "0.11.0"}
org.antlr/antlr4-runtime {:mvn/version "4.7"}}}

View file

@ -1,9 +1,14 @@
.debug-preview {
max-height: 100vh;
display: flex;
flex-direction: column;
overflow: scroll;
}
.debug-icons-preview {
display: flex;
flex-wrap: wrap;
overflow: scroll;
.icon-item {
.icon-item, .cursor-item {
padding: 10px;
display: flex;
flex-direction: column;
@ -17,4 +22,7 @@
height: 100%;
}
}
.cursor-item {
height: auto;
}
}

View file

@ -23,6 +23,7 @@
[uxbox.main.ui.auth :refer [auth verify-token]]
[uxbox.main.ui.dashboard :refer [dashboard]]
[uxbox.main.ui.icons :as i]
[uxbox.main.ui.cursors :as c]
[uxbox.main.ui.messages :as msgs]
[uxbox.main.ui.settings :as settings]
[uxbox.main.ui.static :refer [not-found-page not-authorized-page]]
@ -106,7 +107,12 @@
:debug-icons-preview
(when *assert*
[:& i/debug-icons-preview])
[:div.debug-preview
[:h1 "Cursors"]
[:& c/debug-preview]
[:h1 "Icons"]
[:& i/debug-icons-preview]
])
(:dashboard-search
:dashboard-team

View file

@ -0,0 +1,75 @@
;; 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/.
;;
;; This Source Code Form is "Incompatible With Secondary Licenses", as
;; defined by the Mozilla Public License, v. 2.0.
;;
;; Copyright (c) 2020 UXBOX Labs SL
(ns uxbox.main.ui.cursors
(:import java.net.URLEncoder)
(:require [rumext.alpha]
[clojure.java.io :as io]
[lambdaisland.uri.normalize :as uri]
[cuerdas.core :as str]))
(def cursor-folder "images/cursors")
(def default-hotspot-x 12)
(def default-hotspot-y 12)
(def default-rotation 0)
(defn parse-svg [svg-data]
(-> svg-data
;; Remove the <?xml ?> header
(str/replace #"(?i)<\?xml[^\?]*\?>", "")
;; Remove comments
(str/replace #"<\!\-\-(.*?(?=\-\->))\-\->" "")
;; Remofe 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]
(let [svg-path (str cursor-folder "/" (name id) ".svg")
data (-> svg-path io/resource slurp parse-svg uri/percent-encode)
transform (if rotation (str " transform='rotate(" rotation ")'") "")
data (clojure.pprint/cl-format
nil
"url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' width='24px' height='24px'~A%3E~A%3C/svg%3E\") ~A ~A, auto"
transform data x y)]
data))
(defmacro cursor-ref
([id] (encode-svg-cursor id default-rotation default-hotspot-x default-hotspot-y))
([id rotation] (encode-svg-cursor id rotation default-hotspot-x default-hotspot-y))
([id rotation x y] (encode-svg-cursor id rotation x y)))
(defmacro cursor-fn
[id initial]
(let [cursor (encode-svg-cursor id "{{rotation}}" default-hotspot-x default-hotspot-y)]
`(fn [rot#]
(str/replace ~cursor "{{rotation}}" (+ ~initial rot#)))))

View file

@ -0,0 +1,61 @@
;; 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/.
;;
;; This Source Code Form is "Incompatible With Secondary Licenses", as
;; defined by the Mozilla Public License, v. 2.0.
;;
;; Copyright (c) 2020 UXBOX Labs SL
(ns uxbox.main.ui.cursors
(:require-macros [uxbox.main.ui.cursors :refer [cursor-ref
cursor-fn]])
(:require [rumext.alpha :as mf]
[cuerdas.core :as str]
[uxbox.util.timers :as ts]))
(def create-artboard (cursor-ref :create-artboard))
(def create-ellipse (cursor-ref :create-ellipse))
(def create-polygon (cursor-ref :create-polygon))
(def create-rectangle (cursor-ref :create-reclangle))
(def create-shape (cursor-ref :create-shape))
(def duplicate (cursor-ref :duplicate 0 0 0))
(def hand (cursor-ref :hand))
(def move-pointer (cursor-ref :move-pointer))
(def pencil (cursor-ref :pencil 0 0 24))
(def pen (cursor-ref :pen 0 0 0))
(def pointer-inner (cursor-ref :pointer-inner 0 0 0))
(def resize-alt (cursor-ref :resize-alt))
#_(def resize-nesw (cursor-fn :resize-diagonal 90))
#_(def resize-nwse (cursor-fn :resize-diagonal 0))
(def resize-nesw (cursor-fn :resize-h 45))
(def resize-nwse (cursor-fn :resize-h 135))
(def resize-ew (cursor-fn :resize-h 0))
(def resize-ns (cursor-fn :resize-h 90))
(def rotate (cursor-fn :rotate 90))
(def text (cursor-ref :text))
(mf/defc debug-preview
{::mf/wrap-props false}
[props]
(let [rotation (mf/use-state 0)]
(mf/use-effect (fn [] (ts/interval 100 #(reset! rotation inc))))
[:section.debug-icons-preview
(for [[key val] (sort-by first (ns-publics 'uxbox.main.ui.cursors))]
(when (not= key 'debug-icons-preview)
(let [value (deref val)
value (if (fn? value) (value @rotation) value)]
[:div.cursor-item {:key key}
[:div {:style {:width "100px"
:height "100px"
:background-image (-> value (str/replace #"(url\(.*\)).*" "$1"))
:background-size "cover"
:cursor value}}]
[:span {:style {:white-space "nowrap"
:margin-right "1rem"}} (pr-str key)]])))]))