diff --git a/frontend/src/uxbox/util/geom/matrix.cljs b/frontend/src/uxbox/util/geom/matrix.cljs index 83c6d4a52..3ac18958e 100644 --- a/frontend/src/uxbox/util/geom/matrix.cljs +++ b/frontend/src/uxbox/util/geom/matrix.cljs @@ -7,9 +7,12 @@ (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])) +;; --- Matrix Impl + (defrecord Matrix [a b c d tx ty]) (defprotocol ICoerce @@ -84,7 +87,7 @@ (defn translate-matrix ([pt] - (let [pt (gpt/-point pt)] + (let [pt (gpt/point pt)] (Matrix. 1 0 0 1 (:x pt) (:y pt)))) ([x y] (translate-matrix (gpt/point x y)))) @@ -156,7 +159,7 @@ (translate m (gpt/point x y)))) ;; ([m pt] - ;; (let [pt (gpt/-point pt)] + ;; (let [pt (gpt/point pt)] ;; (assoc m ;; :tx (+ (:tx m) (* (:x pt) (:a m)) (* (:y pt) (:b m))) ;; :ty (+ (:ty m) (* (:x pt) (:c m)) (* (:y pt) (:d m)))))) @@ -180,3 +183,16 @@ (/ a det) (/ (- (* c ty) (* d tx)) det) (/ (- (* b tx) (* a ty)) det))))) + +;; --- 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)))) + diff --git a/frontend/src/uxbox/util/geom/path.cljs b/frontend/src/uxbox/util/geom/path.cljs index 76422c581..d552daee2 100644 --- a/frontend/src/uxbox/util/geom/path.cljs +++ b/frontend/src/uxbox/util/geom/path.cljs @@ -2,7 +2,7 @@ ;; 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) 2016 Andrey Antukh +;; Copyright (c) 2016-2017 Andrey Antukh (ns uxbox.util.geom.path (:require [uxbox.util.geom.path-impl-simplify :as impl-simplify])) diff --git a/frontend/src/uxbox/util/geom/point.cljs b/frontend/src/uxbox/util/geom/point.cljs index b2c05325e..7add1510a 100644 --- a/frontend/src/uxbox/util/geom/point.cljs +++ b/frontend/src/uxbox/util/geom/point.cljs @@ -2,39 +2,18 @@ ;; 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-2016 Andrey Antukh -;; Copyright (c) 2015-2016 Juan de la Cruz +;; Copyright (c) 2015-2017 Andrey Antukh +;; Copyright (c) 2015-2017 Juan de la Cruz (ns uxbox.util.geom.point (:refer-clojure :exclude [divide]) - (:require [uxbox.util.math :as mth])) + (:require [uxbox.util.math :as mth] + [cognitect.transit :as t])) + +;; --- Point Impl (defrecord Point [x y]) -(defprotocol ICoerce - "Point coersion protocol." - (-point [v] "Return a pont instance.")) - -(extend-protocol ICoerce - nil - (-point [_] - (Point. 0 0)) - - number - (-point [v] - (Point. v v)) - - Point - (-point [v] v) - - cljs.core/PersistentVector - (-point [v] - (Point. (first v) (second v))) - - cljs.core/IndexedSeq - (-point [v] - (Point. (first v) (second v)))) - (defn ^boolean point? "Return true if `v` is Point instance." [v] @@ -43,7 +22,20 @@ (defn point "Create a Point instance." ([] (Point. 0 0)) - ([v] (-point v)) + ([v] + (cond + (point? v) + v + + (or (vector? v) + (seq? v)) + (Point. (first v) (second v)) + + (number? v) + (Point. v v) + + :else + (throw (ex-info "Invalid arguments" {:v v})))) ([x y] (Point. x y))) (defn rotate @@ -64,7 +56,7 @@ coordinates of the point as a new point." [p other] {:pre [(point? p)]} - (let [other (-point other)] + (let [other (point other)] (Point. (+ (:x p) (:x other)) (+ (:y p) (:y other))))) @@ -73,7 +65,7 @@ coordinates of the point as a new point." [p other] {:pre [(point? p)]} - (let [other (-point other)] + (let [other (point other)] (Point. (- (:x p) (:x other)) (- (:y p) (:y other))))) @@ -83,27 +75,27 @@ coordinates of the point as a new point." [p other] {:pre [(point? p)]} - (let [other (-point other)] + (let [other (point other)] (Point. (* (:x p) (:x other)) (* (:y p) (:y other))))) (defn divide [p other] {:pre [(point? p)]} - (let [other (-point other)] + (let [other (point other)] (Point. (/ (:x p) (:x other)) (/ (:y p) (:y other))))) (defn negate [p] {:pre [(point? p)]} - (let [{:keys [x y]} (-point p)] + (let [{:keys [x y]} (point p)] (Point. (- x) (- y)))) (defn distance "Calculate the distance between two points." [p other] - (let [other (-point other) + (let [other (point other) dx (- (:x p) (:x other)) dy (- (:y p) (:y other))] (-> (mth/sqrt (+ (mth/pow dx 2) @@ -125,7 +117,7 @@ (-> (mth/atan2 (:y p) (:x p)) (mth/degrees))) ([p center] - (let [center (-point center)] + (let [center (point center)] (angle (subtract p center))))) (defn angle-with-other @@ -133,7 +125,7 @@ the angle between two vectors." [p other] {:pre [(point? p)]} - (let [other (-point other) + (let [other (point other) a (/ (+ (* (:x p) (:x other)) (* (:y p) (:y other))) (* (length p) (length other))) @@ -171,3 +163,16 @@ (let [{:keys [x y]} (point pt)] (Point. (+ (* x a) (* y c) tx) (+ (* x b) (* y d) ty)))) + + +;; --- 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)))) diff --git a/frontend/src/uxbox/util/time.cljs b/frontend/src/uxbox/util/time.cljs index 7eee8a7ba..6e758f5d4 100644 --- a/frontend/src/uxbox/util/time.cljs +++ b/frontend/src/uxbox/util/time.cljs @@ -5,9 +5,10 @@ ;; Copyright (c) 2015-2016 Andrey Antukh (ns uxbox.util.time - (:require [cljsjs.moment])) + (:require [cljsjs.moment] + [cognitect.transit :as t])) -;; A simplified immutable date time representation type. +;; --- Instant Impl (deftype Instant [^number v] IComparable @@ -16,24 +17,28 @@ (compare v (.-v other)) (throw (js/Error. (str "Cannot compare " this " to " other))))) + IEquiv + (-equiv [this other] + (if (instance? Instant other) + (-equiv v (.-v other)) + false)) + IPrintWithWriter (-pr-writer [_ writer _] (let [m (js/moment v) ms (.toISOString m)] (-write writer (str "#instant \"" ms "\"")))) + IHash + (-hash [_] v) + Object (toString [this] (let [m (js/moment v)] (.toISOString m))) (equiv [this other] - (-equiv this other)) - - IHash - (-hash [_] v)) - -(alter-meta! #'->Instant assoc :private true) + (-equiv this other))) (defn instant "Create a new Instant instance from @@ -92,12 +97,12 @@ vm (js/moment (.-v dt))] (.fromNow vm))) -;; (defn day -;; [v] -;; (let [dt (parse v) -;; vm (js/moment (.-v dt)) -;; fmt #js {:sameDay "[Today]" -;; :sameElse "[Today]" -;; :lastDay "[Yesterday]" -;; :lastWeek "[Last] dddd"}] -;; (.calendar vm nil fmt))) +;; --- Transit Adapter + +(def instant-write-handler + (t/write-handler + (constantly "m") + #(str (format % :offset)))) + +(def instant-read-handler + (t/read-handler #(instant (js/parseInt % 10)))) diff --git a/frontend/src/uxbox/util/transit.cljs b/frontend/src/uxbox/util/transit.cljs index 4398d3fb9..4d1e5030d 100644 --- a/frontend/src/uxbox/util/transit.cljs +++ b/frontend/src/uxbox/util/transit.cljs @@ -2,59 +2,27 @@ ;; 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) 2016 Andrey Antukh +;; Copyright (c) 2016-2017 Andrey Antukh (ns uxbox.util.transit "A lightweight abstraction for transit serialization." (:require [cognitect.transit :as t] - [com.cognitect.transit :as tr] - [uxbox.util.data :refer (parse-int)] [uxbox.util.geom.point :as gpt] [uxbox.util.geom.matrix :as gmt] [uxbox.util.time :as dt])) ;; --- Transit Handlers -(def instant-write-handler - (t/write-handler (constantly "m") - #(str (dt/format % :offset)))) - -(def instant-read-handler - (t/read-handler - #(dt/instant (parse-int %)))) - -(def point-write-handler - (t/write-handler - (constantly "point") - (fn [v] (into {} v)))) - -(def point-read-handler - (t/read-handler - (fn [value] - (if (array? value) - (gpt/point (vec 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)))) - (def ^:privare +read-handlers+ {"u" uuid - "m" instant-read-handler - "matrix" matrix-read-handler - "point" point-read-handler}) + "m" dt/instant-read-handler + "matrix" gmt/matrix-read-handler + "point" gpt/point-read-handler}) (def ^:privare +write-handlers+ - {dt/Instant instant-write-handler - gmt/Matrix matrix-write-handler - gpt/Point point-write-handler}) + {dt/Instant dt/instant-write-handler + gmt/Matrix gmt/matrix-write-handler + gpt/Point gpt/point-write-handler}) ;; --- Public Api