0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-03-13 16:21:57 -05:00

Merge pull request #224 from uxbox/refactor_shapes

Moved math and some geom namespaces to common
This commit is contained in:
Andrey Antukh 2020-05-21 15:38:45 +02:00 committed by GitHub
commit 524089e051
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
60 changed files with 172 additions and 761 deletions

View file

@ -102,6 +102,9 @@
(subvec v 0 index)
(subvec v (inc index)))))
(defn zip [col1 col2]
(map vector col1 col2))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Data Parsing / Conversion
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

View file

@ -5,13 +5,13 @@
;; This Source Code Form is "Incompatible With Secondary Licenses", as
;; defined by the Mozilla Public License, v. 2.0.
;;
;; Copyright (c) 2015-2020 Andrey Antukh <niwi@niwi.nz>
;; Copyright (c) 2020 UXBOX Labs SL
(ns uxbox.util.geom.matrix
(:require [cuerdas.core :as str]
[cognitect.transit :as t]
[uxbox.util.math :as mth]
[uxbox.util.geom.point :as gpt]))
(ns uxbox.common.geom.matrix
(:require
[cuerdas.core :as str]
[uxbox.common.math :as mth]
[uxbox.common.geom.point :as gpt]))
;; --- Matrix Impl
@ -121,14 +121,3 @@
([m angle-x angle-y p]
(multiply m (skew-matrix angle-x angle-y p))))
;; --- Transit Adapter
(def matrix-write-handler
(t/write-handler
(constantly "matrix")
(fn [v] (into {} v))))
(def matrix-read-handler
(t/read-handler
(fn [value]
(map->Matrix value))))

View file

@ -5,15 +5,15 @@
;; This Source Code Form is "Incompatible With Secondary Licenses", as
;; defined by the Mozilla Public License, v. 2.0.
;;
;; Copyright (c) 2015-2020 Andrey Antukh <niwi@niwi.nz>
;; Copyright (c) 2020 UXBOX Labs SL
(ns uxbox.util.geom.point
(ns uxbox.common.geom.point
(:refer-clojure :exclude [divide min max])
(:require
[cljs.core :as c]
#?(:cljs [cljs.core :as c]
:clj [clj.core :as c])
[cuerdas.core :as str]
[uxbox.util.math :as mth]
[cognitect.transit :as t]))
[uxbox.common.math :as mth]))
;; --- Point Impl
@ -165,19 +165,6 @@
(Point. (+ (* x a) (* y c) e)
(+ (* x b) (* y d) f)))
;; --- Transit Adapter
(def point-write-handler
(t/write-handler
(constantly "point")
(fn [v] (into {} v))))
(def point-read-handler
(t/read-handler
(fn [value]
(map->Point value))))
;; Vector functions
(defn to-vec [p1 p2]
(subtract p2 p1))
@ -195,4 +182,3 @@
(multiply
v2-unit
(point scalar-projection scalar-projection))))

View file

@ -7,16 +7,15 @@
;;
;; Copyright (c) 2020 UXBOX Labs SL
(ns uxbox.util.geom.shapes
(ns uxbox.common.geom.shapes
(:require
[clojure.spec.alpha :as s]
[uxbox.common.pages :as cp]
[uxbox.common.spec :as us]
[uxbox.util.geom.matrix :as gmt]
[uxbox.util.geom.point :as gpt]
[uxbox.util.math :as mth]
[uxbox.util.data :as d]
[uxbox.util.debug :as debug]))
[uxbox.common.geom.matrix :as gmt]
[uxbox.common.geom.point :as gpt]
[uxbox.common.math :as mth]
[uxbox.common.data :as d]))
;; --- Relative Movement

View file

@ -7,46 +7,55 @@
;;
;; Copyright (c) 2020 UXBOX Labs SL
(ns uxbox.util.math
(ns uxbox.common.math
"A collection of math utils."
(:require [goog.math :as math]))
#?(:cljs
(:require [goog.math :as math])))
(defn ^boolean nan?
[v]
(js/isNaN v))
#?(:cljs (js/isNaN v)
:clj (Double/isNaN v)))
(defn ^boolean finite?
[v]
(js/isFinite v))
#?(:cljs (js/isFinite v)
:clj (Double/isFinite v)))
(defn abs
[^number v]
(js/Math.abs v))
#?(:cljs (js/Math.abs v)
:clj (Math/abs v)))
(defn sin
"Returns the sine of a number"
[^number v]
(js/Math.sin v))
#?(:cljs (js/Math.sin v)
:clj (Math/sin)))
(defn cos
"Returns the cosine of a number."
[^number v]
(js/Math.cos v))
#?(:cljs (js/Math.cos v)
:clj (Math/cos v)))
(defn acos
"Returns the arccosine of a number."
[^number v]
(js/Math.acos v))
#?(:cljs (js/Math.acos v)
:clj (Math/acos v)))
(defn tan
"Returns the tangent of a number."
[^number v]
(js/Math.tan v))
#?(:cljs (js/Math.tan v)
:clj (Math/tan v)))
(defn atan2
"Returns the arctangent of the quotient of its arguments."
[^number x ^number y]
(js/Math.atan2 x y))
#?(:cljs (js/Math.atan2 x y)
:clj (Math/atan2 x y)))
(defn neg
"Negate the number"
@ -56,51 +65,53 @@
(defn sqrt
"Returns the square root of a number."
[v]
(js/Math.sqrt v))
#?(:cljs (js/Math.sqrt v)
:clj (Math/sqrt v)))
(defn pow
"Returns the base to the exponent power."
[b e]
(js/Math.pow b e))
#?(:cljs (js/Math.pow b e)
:clj (Math/pow b e)))
(defn floor
"Returns the largest integer less than or
equal to a given number."
[^number v]
(js/Math.floor v))
#?(:cljs (js/Math.floor v)
:clj (Math/floor)))
(defn round
"Returns the value of a number rounded to
the nearest integer."
[^number v]
(js/Math.round v))
#?(:cljs (js/Math.round v)
:clj (Math/round v)))
(defn ceil
"Returns the smallest integer greater than
or equal to a given number."
[^number v]
(js/Math.ceil v))
#?(:cljs (js/Math.ceil v)
:clj (Math/ceil v)))
(defn precision
[^number v ^number n]
(when (and (number? v) (number? n))
(js/parseFloat (.toFixed v n))))
(defn precision-or-0
[^number v ^number n]
(if (.-toFixed v)
(js/parseFloat (.toFixed v n))
0))
#?(:cljs (js/parseFloat (.toFixed v n))
:clj (.. (BigDecimal/valueOf v) (setScale n java.math.RoundingMode/HALF_UP) (doubleValue)))))
(defn radians
"Converts degrees to radians."
[^number degrees]
(math/toRadians degrees))
#?(:cljs (math/toRadians degrees)
:clj (Math/toRadians degrees)))
(defn degrees
"Converts radians to degrees."
[^number radiants]
(math/toDegrees radiants))
[^number radians]
#?(:cljs (math/toDegrees radians)
:clj (Math/toDegrees radians)))
(defn distance
"Calculate the distance between two points."

View file

@ -29,10 +29,10 @@
[uxbox.main.store :as st]
[uxbox.main.streams :as ms]
[uxbox.main.worker :as uw]
[uxbox.util.geom.matrix :as gmt]
[uxbox.util.geom.point :as gpt]
[uxbox.util.geom.shapes :as geom]
[uxbox.util.math :as mth]
[uxbox.common.geom.matrix :as gmt]
[uxbox.common.geom.point :as gpt]
[uxbox.common.geom.shapes :as geom]
[uxbox.common.math :as mth]
[uxbox.util.router :as rt]
[uxbox.util.transit :as t]
[uxbox.util.webapi :as wapi]))

View file

@ -19,7 +19,7 @@
[uxbox.common.uuid :as uuid]
[uxbox.main.worker :as uw]
[uxbox.util.timers :as ts]
[uxbox.util.geom.shapes :as geom]))
[uxbox.common.geom.shapes :as geom]))
;; --- Protocols

View file

@ -21,7 +21,7 @@
[uxbox.main.data.workspace.common :as dwc]
[uxbox.main.data.workspace.persistence :as dwp]
[uxbox.util.avatars :as avatars]
[uxbox.util.geom.point :as gpt]
[uxbox.common.geom.point :as gpt]
[uxbox.util.time :as dt]
[uxbox.util.transit :as t]
[uxbox.util.websockets :as ws]))

View file

@ -19,7 +19,7 @@
[uxbox.main.data.workspace.common :as dwc]
[uxbox.main.repo :as rp]
[uxbox.main.store :as st]
[uxbox.util.geom.point :as gpt]
[uxbox.common.geom.point :as gpt]
[uxbox.util.router :as rt]
[uxbox.util.time :as dt]
[uxbox.util.transit :as t]))

View file

@ -1,95 +0,0 @@
;; 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) 2015-2017 Andrey Antukh <niwi@niwi.nz>
(ns uxbox.main.data.workspace.ruler
"Workspace ruler related events. Mostly or all events
are related to UI logic."
#_(:require [beicon.core :as rx]
[potok.core :as ptk]
[uxbox.main.refs :as refs]
[uxbox.main.streams :as streams]
[uxbox.main.user-events :as uev]
[uxbox.util.dom :as dom]
[uxbox.util.geom.point :as gpt]))
;; --- Constants
;; (declare stop-ruler?)
;; (declare clear-ruler)
;; (declare update-ruler)
;; (def ^:private immanted-zones
;; (let [transform #(vector (- % 7) (+ % 7) %)
;; right (map transform (range 0 181 15))
;; left (map (comp transform -) (range 0 181 15))]
;; (vec (concat right left))))
;; (defn- align-position
;; [pos]
;; (let [angle (gpt/angle pos)]
;; (reduce (fn [pos [a1 a2 v]]
;; (if (< a1 angle a2)
;; (reduced (gpt/update-angle pos v))
;; pos))
;; pos
;; immanted-zones)))
;; ;; --- Start Ruler
;; (deftype StartRuler []
;; ptk/UpdateEvent
;; (update [_ state]
;; (let [pid (get-in state [:workspace :current])
;; pos (get-in state [:workspace :pointer :viewport])]
;; (assoc-in state [:workspace pid :ruler] {:start pos :end pos})))
;; ptk/WatchEvent
;; (watch [_ state stream]
;; (let [stoper (->> (rx/filter #(= ::uev/interrupt %) stream)
;; (rx/take 1))]
;; (->> streams/mouse-position
;; (rx/take-until stoper)
;; (rx/map (juxt :viewport :ctrl))
;; (rx/map (fn [[pt ctrl?]]
;; (update-ruler pt ctrl?)))))))
;; (defn start-ruler
;; []
;; (StartRuler.))
;; ;; --- Update Ruler
;; (deftype UpdateRuler [point ctrl?]
;; ptk/UpdateEvent
;; (update [_ state]
;; (let [pid (get-in state [:workspace :current])
;; ruler (get-in state [:workspace pid :ruler])]
;; (if-not ctrl?
;; (assoc-in state [:workspace pid :ruler :end] point)
;; (let [start (get-in state [:workspace pid :ruler :start])
;; end (-> (gpt/subtract point start)
;; (align-position)
;; (gpt/add start))]
;; (assoc-in state [:workspace pid :ruler :end] end))))))
;; (defn update-ruler
;; [point ctrl?]
;; {:pre [(gpt/point? point)
;; (boolean? ctrl?)]}
;; (UpdateRuler. point ctrl?))
;; ;; --- Clear Ruler
;; (deftype ClearRuler []
;; ptk/UpdateEvent
;; (update [_ state]
;; (let [pid (get-in state [:workspace :current])]
;; (update-in state [:workspace pid] dissoc :ruler))))
;; (defn clear-ruler
;; []
;; (ClearRuler.))

View file

@ -21,9 +21,9 @@
[uxbox.main.refs :as refs]
[uxbox.main.store :as st]
[uxbox.main.streams :as ms]
[uxbox.util.geom.matrix :as gmt]
[uxbox.util.geom.point :as gpt]
[uxbox.util.geom.shapes :as gsh]
[uxbox.common.geom.matrix :as gmt]
[uxbox.common.geom.point :as gpt]
[uxbox.common.geom.shapes :as gsh]
[uxbox.main.snap :as snap]))
;; -- Declarations

View file

@ -13,10 +13,10 @@
[rumext.alpha :as mf]
[uxbox.common.uuid :as uuid]
[uxbox.common.pages :as cp]
[uxbox.util.math :as mth]
[uxbox.util.geom.shapes :as geom]
[uxbox.util.geom.point :as gpt]
[uxbox.util.geom.matrix :as gmt]
[uxbox.common.math :as mth]
[uxbox.common.geom.shapes :as geom]
[uxbox.common.geom.point :as gpt]
[uxbox.common.geom.matrix :as gmt]
[uxbox.main.ui.shapes.frame :as frame]
[uxbox.main.ui.shapes.circle :as circle]
[uxbox.main.ui.shapes.icon :as icon]

View file

@ -11,8 +11,8 @@
(:require
[beicon.core :as rx]
[uxbox.common.uuid :refer [zero]]
[uxbox.util.math :as mth]
[uxbox.util.geom.point :as gpt]
[uxbox.common.math :as mth]
[uxbox.common.geom.point :as gpt]
[uxbox.main.worker :as uw]
[uxbox.util.geom.snap-points :as sp]))

View file

@ -10,7 +10,7 @@
[beicon.core :as rx]
[uxbox.main.store :as st]
[uxbox.main.refs :as refs]
[uxbox.util.geom.point :as gpt]))
[uxbox.common.geom.point :as gpt]))
;; --- User Events

View file

@ -12,7 +12,7 @@
[rumext.alpha :as mf]
[uxbox.main.ui.shapes.attrs :as attrs]
[uxbox.main.ui.shapes.custom-stroke :refer [shape-custom-stroke]]
[uxbox.util.geom.shapes :as geom]
[uxbox.common.geom.shapes :as geom]
[uxbox.util.object :as obj]))
(mf/defc circle-shape

View file

@ -7,7 +7,7 @@
(ns uxbox.main.ui.shapes.custom-stroke
(:require
[rumext.alpha :as mf]
[uxbox.util.geom.shapes :as geom]
[uxbox.common.geom.shapes :as geom]
[uxbox.util.object :as obj]))
; The SVG standard does not implement yet the 'stroke-alignment'

View file

@ -12,7 +12,7 @@
[rumext.alpha :as mf]
[uxbox.common.data :as d]
[uxbox.main.ui.shapes.attrs :as attrs]
[uxbox.util.geom.shapes :as geom]
[uxbox.common.geom.shapes :as geom]
[uxbox.util.object :as obj]))
(def frame-default-props {:fill-color "#ffffff"})

View file

@ -12,7 +12,7 @@
[rumext.alpha :as mf]
[uxbox.main.ui.shapes.attrs :as attrs]
[uxbox.util.debug :refer [debug?]]
[uxbox.util.geom.shapes :as geom]))
[uxbox.common.geom.shapes :as geom]))
(defn group-shape
[shape-wrapper]

View file

@ -10,7 +10,7 @@
(ns uxbox.main.ui.shapes.icon
(:require
[rumext.alpha :as mf]
[uxbox.util.geom.shapes :as geom]
[uxbox.common.geom.shapes :as geom]
[uxbox.main.ui.shapes.attrs :as attrs]
[uxbox.util.object :as obj]))

View file

@ -10,7 +10,7 @@
(ns uxbox.main.ui.shapes.image
(:require
[rumext.alpha :as mf]
[uxbox.util.geom.shapes :as geom]
[uxbox.common.geom.shapes :as geom]
[uxbox.main.ui.shapes.attrs :as attrs]
[uxbox.util.object :as obj]))

View file

@ -13,7 +13,7 @@
[rumext.alpha :as mf]
[uxbox.main.ui.shapes.attrs :as attrs]
[uxbox.main.ui.shapes.custom-stroke :refer [shape-custom-stroke]]
[uxbox.util.geom.shapes :as geom]
[uxbox.common.geom.shapes :as geom]
[uxbox.util.object :as obj]))
;; --- Path Shape

View file

@ -12,7 +12,7 @@
[rumext.alpha :as mf]
[uxbox.main.ui.shapes.attrs :as attrs]
[uxbox.main.ui.shapes.custom-stroke :refer [shape-custom-stroke]]
[uxbox.util.geom.shapes :as geom]
[uxbox.common.geom.shapes :as geom]
[uxbox.util.object :as obj]))
(mf/defc rect-shape

View file

@ -8,10 +8,10 @@
(:require
[rumext.alpha :as mf]
[uxbox.common.data :as d]
[uxbox.common.geom.shapes :as geom]
[uxbox.common.geom.matrix :as gmt]
[uxbox.main.fonts :as fonts]
[uxbox.util.geom.shapes :as geom]
[uxbox.util.object :as obj]
[uxbox.util.geom.matrix :as gmt]))
[uxbox.util.object :as obj]))
;; --- Text Editor Rendering

View file

@ -20,7 +20,7 @@
[uxbox.util.dom :as dom]
[uxbox.util.i18n :as i18n :refer [t]]
[uxbox.util.router :as rt]
[uxbox.util.math :as mth]
[uxbox.common.math :as mth]
[uxbox.common.uuid :as uuid]
[uxbox.util.webapi :as wapi]))

View file

@ -24,9 +24,9 @@
[uxbox.main.ui.shapes.rect :as rect]
[uxbox.main.ui.shapes.text :as text]
[uxbox.util.object :as obj]
[uxbox.util.geom.matrix :as gmt]
[uxbox.util.geom.point :as gpt]
[uxbox.util.geom.shapes :as geom]))
[uxbox.common.geom.matrix :as gmt]
[uxbox.common.geom.point :as gpt]
[uxbox.common.geom.shapes :as geom]))
(defn on-mouse-down
[event {:keys [interactions] :as shape}]

View file

@ -22,10 +22,10 @@
[uxbox.main.exports :as exports]
[uxbox.util.data :refer [classnames]]
[uxbox.util.dom :as dom]
[uxbox.util.geom.matrix :as gmt]
[uxbox.util.geom.point :as gpt]
[uxbox.common.geom.matrix :as gmt]
[uxbox.common.geom.point :as gpt]
[uxbox.util.i18n :as i18n :refer [t tr]]
[uxbox.util.math :as mth]
[uxbox.common.math :as mth]
[uxbox.util.router :as rt]
[uxbox.main.data.viewer :as vd])
(:import goog.events.EventType

View file

@ -34,7 +34,7 @@
[uxbox.main.ui.workspace.left-toolbar :refer [left-toolbar]]
[uxbox.util.data :refer [classnames]]
[uxbox.util.dom :as dom]
[uxbox.util.geom.point :as gpt]))
[uxbox.common.geom.point :as gpt]))
;; --- Workspace

View file

@ -12,17 +12,17 @@
[rumext.alpha :as mf]
[uxbox.main.constants :as c]
[uxbox.main.data.workspace :as dw]
[uxbox.util.geom.shapes :as geom]
[uxbox.main.refs :as refs]
[uxbox.main.store :as st]
[uxbox.main.streams :as ms]
[uxbox.main.ui.workspace.shapes :as shapes]
[uxbox.util.math :as mth]
[uxbox.common.math :as mth]
[uxbox.util.dom :as dom]
[uxbox.util.data :refer [seek]]
[uxbox.util.geom.matrix :as gmt]
[uxbox.common.geom.shapes :as geom]
[uxbox.common.geom.matrix :as gmt]
[uxbox.common.geom.point :as gpt]
[uxbox.util.geom.path :as path]
[uxbox.util.geom.point :as gpt]
[uxbox.util.i18n :as i18n :refer [t]]
[uxbox.main.snap :as snap]
[uxbox.common.uuid :as uuid]))

View file

@ -12,7 +12,7 @@
[rumext.alpha :as mf]
[uxbox.main.refs :as refs]
[uxbox.common.pages :as cp]
[uxbox.util.geom.shapes :as gsh]
[uxbox.common.geom.shapes :as gsh]
[uxbox.util.geom.grid :as gg]))
(mf/defc square-grid [{:keys [frame zoom grid] :as props}]

View file

@ -23,7 +23,7 @@
[uxbox.main.ui.workspace.presence :as presence]
[uxbox.util.i18n :as i18n :refer [t]]
[uxbox.util.data :refer [classnames]]
[uxbox.util.math :as mth]
[uxbox.common.math :as mth]
[uxbox.util.router :as rt]))
;; --- Zoom Widget

View file

@ -10,7 +10,7 @@
(ns uxbox.main.ui.workspace.rules
(:require
[rumext.alpha :as mf]
[uxbox.util.math :as mth]
[uxbox.common.math :as mth]
[uxbox.util.object :as obj]))
(defn- calculate-step-size

View file

@ -11,7 +11,7 @@
[potok.core :as ptk]
[uxbox.main.refs :as refs]
[uxbox.util.dom :as dom]
[uxbox.util.geom.point :as gpt]))
[uxbox.common.geom.point :as gpt]))
;; FIXME: revisit this ns in order to find a better location for its functions
;; TODO: this need a good refactor (probably move to events with access to the state)

View file

@ -15,14 +15,14 @@
[rumext.alpha :as mf]
[rumext.util :refer [map->obj]]
[uxbox.main.data.workspace :as dw]
[uxbox.util.geom.shapes :as geom]
[uxbox.main.refs :as refs]
[uxbox.main.store :as st]
[uxbox.main.streams :as ms]
[uxbox.util.dom :as dom]
[uxbox.util.object :as obj]
[uxbox.util.geom.point :as gpt]
[uxbox.util.geom.matrix :as gmt]
[uxbox.common.geom.shapes :as geom]
[uxbox.common.geom.point :as gpt]
[uxbox.common.geom.matrix :as gmt]
[uxbox.util.debug :refer [debug?]]))
(defn rotation-cursor [angle]
@ -161,7 +161,7 @@
(mf/defc resize-side-handler [{:keys [x y length angle zoom position transform on-resize]}]
[:rect {:x (+ x (/ resize-point-rect-size zoom))
:y (- y (/ resize-side-height 2 zoom))
:width (- length (/ (* resize-point-rect-size 2) zoom))
:width (max 0 (- length (/ (* resize-point-rect-size 2) zoom)))
:height (/ resize-side-height zoom)
:transform (gmt/multiply transform
(gmt/rotate-matrix angle (gpt/point x y)))

View file

@ -26,7 +26,7 @@
[uxbox.main.ui.workspace.shapes.group :as group]
[uxbox.main.ui.workspace.shapes.path :as path]
[uxbox.main.ui.workspace.shapes.text :as text]
[uxbox.util.geom.shapes :as geom]))
[uxbox.common.geom.shapes :as geom]))
(declare group-wrapper)
(declare frame-wrapper)

View file

@ -9,9 +9,9 @@
[cuerdas.core :as str]
[rumext.alpha :as mf]
[uxbox.util.debug :as debug]
[uxbox.util.geom.shapes :as geom]
[uxbox.util.geom.matrix :as gmt]
[uxbox.util.geom.point :as gpt]
[uxbox.common.geom.shapes :as geom]
[uxbox.common.geom.matrix :as gmt]
[uxbox.common.geom.point :as gpt]
[uxbox.util.debug :refer [debug?]]
["randomcolor" :as rdcolor]))

View file

@ -15,9 +15,9 @@
[uxbox.main.store :as st]
[uxbox.main.ui.keyboard :as kbd]
[uxbox.util.dom :as dom]
[uxbox.util.geom.matrix :as gmt]
[uxbox.util.geom.point :as gpt]
[uxbox.util.geom.shapes :as geom]))
[uxbox.common.geom.matrix :as gmt]
[uxbox.common.geom.point :as gpt]
[uxbox.common.geom.shapes :as geom]))
(defn- on-mouse-down
[event {:keys [id type] :as shape}]

View file

@ -17,9 +17,9 @@
[uxbox.main.store :as st]
[uxbox.main.ui.workspace.shapes.common :as common]
[uxbox.main.ui.shapes.frame :as frame]
[uxbox.util.geom.matrix :as gmt]
[uxbox.util.geom.point :as gpt]
[uxbox.util.geom.shapes :as geom]
[uxbox.common.geom.matrix :as gmt]
[uxbox.common.geom.point :as gpt]
[uxbox.common.geom.shapes :as geom]
[uxbox.util.dom :as dom]
[uxbox.main.streams :as ms]
[uxbox.util.timers :as ts]))

View file

@ -14,13 +14,12 @@
[cuerdas.core :as str]
[uxbox.util.data :as dt]
[uxbox.util.dom :as dom]
[uxbox.util.geom.point :as gpt]
[uxbox.util.geom.shapes :as geom]
[uxbox.common.geom.point :as gpt]
[uxbox.common.geom.shapes :as geom]
[uxbox.main.store :as st]
[uxbox.main.refs :as refs]
[uxbox.main.data.workspace :as dw]
[uxbox.main.ui.keyboard :as kbd]
))
[uxbox.main.ui.keyboard :as kbd]))
(defn- get-click-interaction
[shape]

View file

@ -19,9 +19,6 @@
[uxbox.main.ui.shapes.path :as path]
[uxbox.main.ui.workspace.shapes.common :as common]
[uxbox.util.dom :as dom]
[uxbox.util.geom.matrix :as gmt]
[uxbox.util.geom.point :as gpt]
[uxbox.util.geom.shapes :as geom]
[uxbox.util.interop :as itr]
[uxbox.main.streams :as ms]
[uxbox.util.timers :as ts]))

View file

@ -22,9 +22,8 @@
[uxbox.main.fonts :as fonts]
[uxbox.util.color :as color]
[uxbox.util.dom :as dom]
[uxbox.util.geom.shapes :as geom]
[uxbox.common.geom.shapes :as geom]
[uxbox.util.object :as obj]
[uxbox.util.geom.matrix :as gmt]
["slate" :as slate]
["slate-react" :as rslate])
(:import

View file

@ -13,9 +13,9 @@
[rumext.alpha :as mf]
[uxbox.common.data :as d]
[uxbox.util.dom :as dom]
[uxbox.util.geom.point :as gpt]
[uxbox.common.geom.point :as gpt]
[uxbox.util.i18n :refer [tr]]
[uxbox.util.math :as math]
[uxbox.common.math :as math]
[uxbox.main.store :as st]
[uxbox.main.data.workspace :as udw]
[uxbox.main.ui.icons :as i]

View file

@ -12,7 +12,7 @@
[rumext.alpha :as mf]
[uxbox.util.dom :as dom]
[uxbox.util.data :as d]
[uxbox.util.math :as mth]
[uxbox.common.math :as mth]
[uxbox.common.data :refer [parse-integer]]
[uxbox.main.store :as st]
[uxbox.main.refs :as refs]

View file

@ -15,10 +15,10 @@
[uxbox.main.refs :as refs]
[uxbox.common.data :as d]
[uxbox.util.dom :as dom]
[uxbox.util.geom.shapes :as gsh]
[uxbox.util.geom.point :as gpt]
[uxbox.common.geom.shapes :as gsh]
[uxbox.common.geom.point :as gpt]
[uxbox.main.data.workspace :as udw]
[uxbox.util.math :as math]
[uxbox.common.math :as math]
[uxbox.util.i18n :refer [t] :as i18n]))
;; -- User/drawing coords

View file

@ -10,7 +10,7 @@
(ns uxbox.main.ui.workspace.sidebar.options.rows.color-row
(:require
[rumext.alpha :as mf]
[uxbox.util.math :as math]
[uxbox.common.math :as math]
[uxbox.util.dom :as dom]
[uxbox.main.ui.modal :as modal]
[uxbox.main.ui.workspace.colorpicker :refer [colorpicker-modal]]

View file

@ -19,7 +19,7 @@
[uxbox.util.dom :as dom]
[uxbox.util.object :as obj]
[uxbox.util.i18n :as i18n :refer [tr t]]
[uxbox.util.math :as math]
[uxbox.common.math :as math]
[uxbox.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row]]))
(defn- stroke-menu-memo-equals?

View file

@ -5,7 +5,7 @@
[uxbox.main.refs :as refs]
[uxbox.main.snap :as snap]
[uxbox.util.geom.snap-points :as sp]
[uxbox.util.geom.point :as gpt]))
[uxbox.common.geom.point :as gpt]))
(def ^:private line-color "#D383DA")

View file

@ -30,10 +30,10 @@
[uxbox.main.ui.workspace.presence :as presence]
[uxbox.main.ui.workspace.snap-feedback :refer [snap-feedback]]
[uxbox.main.ui.workspace.frame-grid :refer [frame-grid]]
[uxbox.util.math :as mth]
[uxbox.common.math :as mth]
[uxbox.util.dom :as dom]
[uxbox.util.object :as obj]
[uxbox.util.geom.point :as gpt]
[uxbox.common.geom.point :as gpt]
[uxbox.util.perf :as perf]
[uxbox.common.uuid :as uuid])
(:import goog.events.EventType))

View file

@ -11,7 +11,7 @@
"Color conversion utils."
(:require
[cuerdas.core :as str]
[uxbox.util.math :as math]
[uxbox.common.math :as math]
[goog.color :as gcolor]))
(defn rgb->str

View file

@ -111,9 +111,6 @@
not-found))
not-found coll)))
(defn zip [col1 col2]
(map vector col1 col2))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Numbers Parsing
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

View file

@ -13,7 +13,7 @@
[cuerdas.core :as str]
[beicon.core :as rx]
[cuerdas.core :as str]
[uxbox.util.geom.point :as gpt]
[uxbox.common.geom.point :as gpt]
[uxbox.util.blob :as blob]
[uxbox.util.transit :as ts]))

View file

@ -1,229 +0,0 @@
/*
* 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 Andrey Antukh <niwi@niwi.nz>
*/
// NOTE: this code is unused, but is preserved for the case when we
// note that the cljs impl has not not enough performance.
goog.provide("uxbox.util.geom.matrix_impl");
goog.provide("uxbox.util.geom.matrix_impl.Matrix");
goog.require("goog.math");
goog.require("uxbox.util.geom.point_impl");
goog.scope(function() {
const self = uxbox.util.geom.matrix_impl;
const gpt = uxbox.util.geom.point_impl;
const math = goog.math;
/**
* @param {number} a
* @param {number} b
* @param {number} c
* @param {number} d
* @param {number} e
* @param {number} f
* @struct
*/
class Matrix {
constructor(a, b, c, d, e, f) {
this.a = a;
this.b = b;
this.c = c;
this.d = d;
this.e = e;
this.f = f;
}
[Symbol.iterator]() {
return [["a", this.a]
["b", this.b]];
}
toString() {
return `matrix(${this.a},${this.b},${this.c},${this.d},${this.e},${this.f})`;
}
copy() {
return new Matrix(
this.a,
this.b,
this.c,
this.d,
this.e,
this.f
);
}
}
self.Matrix = Matrix;
/**
* @param {number?} a
* @param {number?} b
* @param {number?} c
* @param {number?} d
* @param {number?} e
* @param {number?} f
* @return {Matrix}
*/
self.matrix = function(a, b, c, d, e, f) {
if (a === undefined) {
return new Matrix(1,0,0,1,0,0);
} else {
return new Matrix(a,b,c,d,e,f);
}
};
/**
* @param {?} m
* @return {boolean}
*/
function isMatrix(m) {
return m instanceof Matrix;
}
self.isMatrix = isMatrix
/**
* @param {Matrix} m1
* @param {Matrix} m2
* @return {Matrix}
*/
self.multiplyUnsafe = function(m1, m2) {
const a = m1.a * m2.a + m1.c * m2.b;
const b = m1.b * m2.a + m1.d * m2.b;
const c = m1.a * m2.c + m1.c * m2.d;
const d = m1.b * m2.c + m1.d * m2.d;
const e = m1.a * m2.e + m1.c * m2.f + m1.e;
const f = m1.b * m2.e + m1.d * m2.f + m1.f;
m1.a = a;
m1.b = b;
m1.c = c;
m1.d = d;
m1.e = e;
m1.f = f;
return m1;
}
/**
* @param {Matrix} m1
* @param {Matrix} m2
* @return {Matrix}
*/
self.multiply = function(m1, m2) {
m1 = m1.copy();
return self.multiplyUnsafe(m1, m2);
}
/**
* @param {...Matrix} matrices
* @return {Matrix}
*/
self.compose = function(...matrices) {
switch (matrices.length) {
case 0:
throw new Error('no matrices provided')
case 1:
return matrices[0]
case 2:
return self.multiply(matrices[0], matrices[1])
default: {
let result = matrices[0].copy();
for (let i=1; i<matrices.length; i++) {
result = self.multiplyUnsafe(result, matrices[i]);
}
return result;
}
}
};
/**
* @param {gpt.Point} p
* @return {Matrix}
*/
self.translateMatrix = function(p) {
return new Matrix(1, 0, 0, 1, p.x, p.y);
};
/**
* @param {gpt.Point} p
* @return {Matrix}
*/
self.scaleMatrix = function(p) {
return new Matrix(p.x, 0, 0, p.y, 0, 0);
};
/**
* @param {number} angle
* @return {Matrix}
*/
self.rotateMatrix = function(angle) {
const r = math.toRadiants(angle);
return new Matrix(
Math.cos(r),
Math.sin(r),
-Math.sin(r),
Math.cos(r),
0,
0
);
};
/**
* @param {Matrix} m
* @param {gpt.Point} p
* @return {Matrix}
*/
self.translate = function(m, p) {
return self.multiply(m, self.translateMatrix(p));
}
/**
* @param {Matrix} m
* @param {angle} angle
* @param {gpt.Point?} center
* @return {Matrix}
*/
self.rotate = function(m, angle, center) {
if (center === undefined) {
return self.multiply(m, self.rotateMatrix(angle));
} else {
return self.compose(
m,
self.translateMatrix(center),
self.rotateMatrix(angle),
self.translateMatrix(gpt.negate(center))
);
}
};
/**
* @param {Matrix} m
* @param {gpt.Point} scale
* @param {gpt.Point?} center
* @return {Matrix}
*/
self.scale = function(m, scale, center) {
if (center === undefined) {
return self.multiply(m, self.scaleMatrix(scale));
} else {
return self.compose(
m,
self.translateMatrix(center),
self.scaleMatrix(scale),
self.translateMatrix(gpt.negate(center))
);
}
};
});

View file

@ -1,242 +0,0 @@
/*
* 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 Andrey Antukh <niwi@niwi.nz>
*/
// NOTE: this code is unused, but is preserved for the case when we
// note that the cljs impl has not not enough performance.
goog.provide("uxbox.util.geom.point_impl");
goog.provide("uxbox.util.geom.point_impl.Point");
goog.require("goog.math");
goog.scope(function() {
const self = uxbox.util.geom.point_impl;
const math = goog.math;
/**
* @param {number} x
* @param {number} y
* @struct
*/
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return "point(" + this.x + ", " + this.y + ")";
}
}
self.Point = Point;
self.point = function(x, y) {
let xv = null;
let yv = null;
if (x === undefined) {
return new Point(0, 0);
} else {
xv = x;
}
if (y === undefined) {
yv = x;
} else {
yv = y;
}
return new Point(xv, yv);
};
function isPoint(p) {
return p instanceof Point;
}
self.isPoint = isPoint;
/**
* @param {Point} p
* @param {number} angle
* @return {Point}
*/
self.rotate = function(p, angle) {
const r = math.toRadians(angle);
const sin = Math.sin(r);
const cos = Math.cos(r);
const x = p.x;
const y = p.y;
const point = new Point(
x * cos - y * sin,
x * sin + y * cos
);
return self.roundTo(point, 6)
};
/**
* @param {Point} p
* @param {Point} other
* @return {Point}
*/
self.add = function(p, other) {
return new Point(
p.x + other.x,
p.y + other.y
);
};
/**
* @param {Point} p
* @param {Point} other
* @return {Point}
*/
self.subtract = function(p, other) {
return new Point(
p.x - other.x,
p.y - other.y
);
};
/**
* @param {Point} p
* @param {Point} other
* @return {Point}
*/
self.multiply = function(p, other) {
return new Point(
p.x * other.x,
p.y * other.y
);
};
/**
* @param {Point} p
* @param {Point} other
* @return {Point}
*/
self.divide = function(p, other) {
return new Point(
p.x / other.x,
p.y / other.y
);
};
/**
* @param {Point} p
* @return {Point}
*/
self.negate = function(p) {
const x = p.x, y = p.y;
return new Point(
x === 0 ? x : x * -1,
y === 0 ? y : y * -1
);
};
/**
* @param {Point} p
* @param {Point} other
* @return {number}
*/
self.distance = function(p, other) {
const dx = p.x - other.x;
const dy = p.y - other.y;
return Math.sqrt(Math.pow(dx, 2),
Math.pow(dy, 2));
};
/**
* @param {Point} p
* @param {Point} center
* @return {number}
*/
self.angle = function(p, center) {
if (center !== undefined) {
p = self.subtract(p, center);
}
return math.toDegrees(Math.atan2(p.y, p.x));
};
/**
* @param {Point} p
* @param {Point} other
* @return {number}
*/
self.length = function(p) {
return Math.sqrt(Math.pow(p.x, 2) + Math.pow(p.y, 2));
};
/**
* @param {Point} p
* @return {number}
*/
self.angle2other = function(p, other) {
let angle = ((p.x * other.x) + (p.y * other.y)) / (self.length(p) * self.length(other));
if (angle < -1) {
angle = -1;
} else if (angle > 1) {
angle = 1;
}
angle = Math.acos(angle);
angle = math.toDegrees(angle);
return parseFloat(angle.toFixed(6));
};
/**
* @param {Point} p
* @param {number} angle
* @return {Point}
*/
self.updateAngle = function(p, angle) {
const len = self.length(p);
const r = math.toRadiants(angle);
return new Point(
Math.cos(r) * len,
Math.sin(r) * len
);
};
/**
* @param {Point} p
* @param {number} decimals
* @return {Point}
*/
self.roundTo = function(p, decimals) {
return new Point(
parseFloat(p.x.toFixed(decimals)),
parseFloat(p.y.toFixed(decimals))
);
};
// class Matrix {
// constructor() {
// this.a = 1;
// this.b = 0;
// this.c = 0;
// this.d = 1;
// this.e = 0;
// this.f = 0;
// }
// }
// self = uxbox.util.geom.matrix_impl;
// self.Matrix = Matrix;
// self.sayHello = function() {
// console.log("hello");
// }
});

View file

@ -9,8 +9,8 @@
(ns uxbox.util.geom.grid
(:require
[uxbox.util.math :as mth]
[uxbox.util.geom.point :as gpt]))
[uxbox.common.math :as mth]
[uxbox.common.geom.point :as gpt]))
(def ^:private default-items 12)

View file

@ -1,25 +0,0 @@
;; 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.util.geom.range-tree
(:require
[cljs.spec.alpha :as s]))
(defn make-tree [objects])
(defn add-shape [shape])
(defn remove-shape [shape])
(defn update-shape [old-shape new-shape])
(defn query [point match-dist]) ;; Return {:x => [(point, distance, shape-id)]}
;;

View file

@ -11,8 +11,8 @@
(:require
[cljs.spec.alpha :as s]
[clojure.set :as set]
[uxbox.util.geom.shapes :as gsh]
[uxbox.util.geom.point :as gpt]))
[uxbox.common.geom.shapes :as gsh]
[uxbox.common.geom.point :as gpt]))
(defn- frame-snap-points [{:keys [x y width height] :as frame}]
(into #{(gpt/point x y)

View file

@ -7,11 +7,12 @@
(ns uxbox.util.perf
"Performance profiling for react components."
(:require-macros [uxbox.util.perf])
(:require [uxbox.util.math :as math]
[rumext.alpha :as mf]
[goog.functions :as f]
["react" :as react]
["tdigest" :as td]))
(:require
[uxbox.common.math :as math]
[rumext.alpha :as mf]
[goog.functions :as f]
["react" :as react]
["tdigest" :as td]))
;; For use it, just wrap the component you want to profile with
;; `perf/profiler` component and pass a label for debug purpose.

View file

@ -7,8 +7,8 @@
(ns uxbox.util.transit
"A lightweight abstraction for transit serialization."
(:require [cognitect.transit :as t]
[uxbox.util.geom.point :as gpt]
[uxbox.util.geom.matrix :as gmt]
[uxbox.common.geom.point :as gpt]
[uxbox.common.geom.matrix :as gmt]
[uxbox.util.time :as dt]))
(deftype Blob [content]
@ -29,18 +29,40 @@
(fn [value]
(->Blob (js/JSON.parse value)))))
;; --- Transit adapters
(def point-write-handler
(t/write-handler
(constantly "point")
(fn [v] (into {} v))))
(def point-read-handler
(t/read-handler
(fn [value]
(gpt/map->Point value))))
(def matrix-write-handler
(t/write-handler
(constantly "matrix")
(fn [v] (into {} v))))
(def matrix-read-handler
(t/read-handler
(fn [value]
(gmt/map->Matrix value))))
;; --- Transit Handlers
(def ^:privare +read-handlers+
{"u" uuid
"jsonblob" blob-read-handler
"matrix" gmt/matrix-read-handler
"point" gpt/point-read-handler})
"matrix" matrix-read-handler
"point" point-read-handler})
(def ^:privare +write-handlers+
{gmt/Matrix gmt/matrix-write-handler
{gmt/Matrix matrix-write-handler
Blob blob-write-handler
gpt/Point gpt/point-write-handler})
gpt/Point point-write-handler})
;; --- Public Api
@ -56,4 +78,3 @@
(t/write w data))
(catch :default e
(throw e))))

View file

@ -16,7 +16,7 @@
[uxbox.common.pages :as cp]
[uxbox.common.uuid :as uuid]
[uxbox.worker.impl :as impl]
[uxbox.util.geom.shapes :as geom]
[uxbox.common.geom.shapes :as geom]
[uxbox.util.quadtree :as qdt]))
(defonce state (l/atom {}))

View file

@ -1,8 +1,8 @@
(ns uxbox.test-util-geom
(:require [cljs.test :as t :include-macros true]
[cljs.pprint :refer [pprint]]
[uxbox.util.geom.point :as gpt]
[uxbox.util.geom.matrix :as gmt]))
[uxbox.common.geom.point :as gpt]
[uxbox.common.geom.matrix :as gmt]))
(t/deftest point-constructors-test
(let [p (gpt/point 1 2)]

View file

@ -1,7 +1,7 @@
(ns uxbox.test-util-range-tree
(:require [cljs.test :as t :include-macros true]
[cljs.pprint :refer [pprint]]
[uxbox.util.geom.point :as gpt]
[uxbox.common.geom.point :as gpt]
[uxbox.util.range-tree :as rt]))
(defn check-max-height [tree num-nodes])