0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-01-25 07:58:49 -05:00

Remove unexpected lag on moving shape.

The lag happens when the shape is not initially selected.
This commit is contained in:
Andrey Antukh 2019-11-26 10:55:38 +01:00
parent 1357fed067
commit 792303a833
15 changed files with 106 additions and 121 deletions

View file

@ -6,6 +6,7 @@
(ns ^:figwheel-hooks uxbox.main
(:require
[cljs.spec.alpha :as s]
[rumext.alpha :as mf]
[uxbox.main.data.auth :refer [logout]]
[uxbox.main.data.users :as udu]
@ -27,6 +28,7 @@
;; --- i18n
(declare reinit)
(s/check-asserts true)
(i18n/update-locales! (fn [locales]
(-> locales

View file

@ -20,29 +20,23 @@
;; --- Initialize
(defrecord Initialize []
ptk/UpdateEvent
(update [_ state]
(assoc-in state [:dashboard :icons] {:selected #{}})))
(defn initialize
[]
(Initialize.))
(def initialize
(ptk/reify ::initialize
ptk/UpdateEvent
(update [_ state]
(assoc-in state [:dashboard :icons] {:selected #{}}))))
;; --- Select a Collection
(defrecord SelectCollection [type id]
ptk/WatchEvent
(watch [_ state stream]
(rx/of (r/navigate :dashboard/icons
{:type type :id id}))))
(defn select-collection
([type]
(select-collection type nil))
([type id]
{:pre [(keyword? type)]}
(SelectCollection. type id)))
(ptk/reify ::select-collection
ptk/WatchEvent
(watch [_ state stream]
(rx/of (r/navigate :dashboard/icons {:type type :id id}))))))
;; --- Collections Fetched
@ -61,6 +55,10 @@
state
items))))
(defn collections-fetched?
[v]
(= ::collections-fetched (ptk/type v)))
;; --- Fetch Collections
(def fetch-collections
@ -72,48 +70,37 @@
;; --- Collection Created
(defrecord CollectionCreated [item]
ptk/UpdateEvent
(update [_ state]
(let [{:keys [id] :as item} (assoc item :type :own)]
(update state :icons-collections assoc id item)))
ptk/WatchEvent
(watch [_ state stream]
(rx/of (select-collection :own (:id item)))))
(defn collection-created
[item]
(CollectionCreated. item))
(ptk/reify ::collection-created
ptk/UpdateEvent
(update [_ state]
(let [{:keys [id] :as item} (assoc item :type :own)]
(update state :icons-collections assoc id item)))
ptk/WatchEvent
(watch [_ state stream]
(rx/of (select-collection :own (:id item))))))
;; --- Create Collection
(defrecord CreateCollection []
ptk/WatchEvent
(watch [_ state s]
(let [name (tr "ds.default-library-title" (gensym "c"))
data {:name name}]
(->> (rp/mutation! :create-icons-collection data)
(rx/map collection-created)))))
(defn create-collection
[]
(CreateCollection.))
(defn collections-fetched?
[v]
(= ::collections-fetched (ptk/type v)))
(def create-collection
(ptk/reify ::create-collection
ptk/WatchEvent
(watch [_ state s]
(let [name (tr "ds.default-library-title" (gensym "c"))
data {:name name}]
(->> (rp/mutation! :create-icons-collection data)
(rx/map collection-created))))))
;; --- Collection Updated
(defrecord CollectionUpdated [item]
ptk/UpdateEvent
(update [_ state]
(update-in state [:icons-collections (:id item)] merge item)))
(defn collection-updated
[item]
(CollectionUpdated. item))
(ptk/reify ::collection-updated
ptk/UpdateEvent
(update [_ state]
(update-in state [:icons-collections (:id item)] merge item))))
;; --- Update Collection

View file

@ -245,31 +245,17 @@
{:pre [(or (uuid? id) (nil? id)) (fn? on-uploaded)]}
(CreateImages. id files on-uploaded)))
;; --- Image Updated
(defrecord ImagePersisted [id data]
ptk/UpdateEvent
(update [_ state]
(assoc-in state [:images id] data)))
(defn image-persisted
[{:keys [id] :as data}]
{:pre [(map? data) (uuid? id)]}
(ImagePersisted. id data))
;; --- Update Image
(defrecord PersistImage [id]
ptk/WatchEvent
(watch [_ state stream]
(let [data (get-in state [:images id])]
(->> (rp/mutation! :update-image data)
(rx/map image-persisted)))))
(defn persist-image
[id]
{:pre [(uuid? id)]}
(PersistImage. id))
(ptk/reify ::persist-image
ptk/WatchEvent
(watch [_ state stream]
(let [data (get-in state [:images id])]
(->> (rp/mutation! :update-image data)
(rx/ignore))))))
;; --- Images Fetched

View file

@ -378,38 +378,38 @@
(reduce ds/dissoc-shape state
(map #(get-in state [:shapes %]) ids)))))
(defrecord SelectShape [id]
ptk/UpdateEvent
(update [_ state]
(let [pid (get-in state [:workspace :current])
selected (get-in state [:workspace pid :selected])]
(if (contains? selected id)
(update-in state [:workspace pid :selected] disj id)
(update-in state [:workspace pid :selected] conj id))))
ptk/WatchEvent
(watch [_ state s]
(rx/of (activate-flag :element-options))))
(defn select-shape
"Mark a shape selected for drawing."
[id]
{:pre [(uuid? id)]}
(SelectShape. id))
(s/assert ::us/uuid id)
(ptk/reify ::select-shape
ptk/UpdateEvent
(update [_ state]
(prn "select-shape$update" id)
(let [pid (get-in state [:workspace :current])
selected (get-in state [:workspace pid :selected])]
(update-in state [:workspace pid :selected]
(fn [selected]
(if (contains? selected id)
(disj selected id)
(conj selected id))))))
(defrecord DeselectAll []
ptk/UpdateEvent
(update [_ state]
(let [pid (get-in state [:workspace :current])]
(update-in state [:workspace pid] #(-> %
(assoc :selected #{})
(dissoc :selected-canvas))))))
ptk/WatchEvent
(watch [_ state s]
(prn "select-shape$watch" id)
(rx/of (activate-flag :element-options)))))
(defn deselect-all
(def deselect-all
"Clear all possible state of drawing, edition
or any similar action taken by the user."
[]
(DeselectAll.))
(ptk/reify ::deselect-all
ptk/UpdateEvent
(update [_ state]
(prn "deselect-all")
(let [pid (get-in state [:workspace :current])]
(update-in state [:workspace pid] #(-> %
(assoc :selected #{})
(dissoc :selected-canvas)))))))
;; --- Select First Shape
@ -1030,7 +1030,7 @@
(rx/buffer-time 300)
(rx/map #(into* #{} %))
(rx/filter (complement empty?))
(rx/tap #(prn "changed" %))
;; (rx/tap #(prn "changed" %))
(rx/mapcat (fn [items] (rx/from-coll
(map rehash-shape-relationship items))))
(rx/take-until stoper)))))))

View file

@ -425,7 +425,7 @@
:else (first colls))
id (:id selected-coll)]
(mf/use-effect #(st/emit! di/fetch-collections))
(mf/use-effect {:fn #(st/emit! (di/initialize)
(mf/use-effect {:fn #(st/emit! di/initialize
(di/fetch-icons id))
:deps #js [id type]})

View file

@ -32,7 +32,7 @@
shape (merge canvas-default-props shape)]
(letfn [(on-double-click [event]
(dom/prevent-default event)
(st/emit! (dw/deselect-all)
(st/emit! dw/deselect-all
(dw/select-shape (:id shape))))]
[:g.shape {:class (when selected? "selected")
:on-double-click on-double-click

View file

@ -4,6 +4,11 @@
;;
;; Copyright (c) 2016-2019 Andrey Antukh <niwi@niwi.nz>
;; TODO: we need to consider moving this under uxbox.ui.workspace
;; namespace because this is logic only related to workspace
;; manipulation. Staying here causes a lot of confusion and finding
;; this code is also very difficult.
(ns uxbox.main.ui.shapes.common
(:require
[potok.core :as ptk]
@ -13,26 +18,29 @@
[uxbox.main.store :as st]
[uxbox.main.ui.keyboard :as kbd]
[uxbox.main.ui.workspace.streams :as uws]
[uxbox.main.workers :as uwrk]
[uxbox.util.geom.matrix :as gmt]
[uxbox.util.geom.point :as gpt]
[uxbox.util.dom :as dom]))
;; --- Shape Movement (by mouse)
(def start-move-selected
(reify
(ptk/reify ::start-move-selected
ptk/WatchEvent
(watch [_ state stream]
(let [pid (get-in state [:workspace :current])
flags (get-in state [:workspace pid :flags])
selected (get-in state [:workspace pid :selected])
stoper (rx/filter uws/mouse-up? stream)]
stoper (rx/filter uws/mouse-up? stream)
position @uws/mouse-position]
(rx/concat
(when (refs/alignment-activated? flags)
(rx/of (dw/initial-selection-align selected)))
(->> uws/mouse-position-deltas
(->> (uws/mouse-position-deltas position)
(rx/map #(dw/apply-temporal-displacement-in-bulk selected %))
(rx/take-until stoper))
(rx/of (dw/materialize-current-modifier-in-bulk selected)))))))
(rx/of (dw/materialize-current-modifier-in-bulk selected)))))))
(defn on-mouse-down
[event {:keys [id type] :as shape} selected]
@ -51,7 +59,7 @@
(and (not selected?) (empty? selected))
(do
(dom/stop-propagation event)
(st/emit! (dw/deselect-all)
(st/emit! dw/deselect-all
(dw/select-shape id)
start-move-selected))
@ -60,7 +68,7 @@
(dom/stop-propagation event)
(if (kbd/shift? event)
(st/emit! (dw/select-shape id))
(st/emit! (dw/deselect-all)
(st/emit! dw/deselect-all
(dw/select-shape id)
start-move-selected)))
:else

View file

@ -154,10 +154,10 @@
[{:keys [shape modifiers zoom] :as props}]
(letfn [(on-mouse-down [event index]
(dom/stop-propagation event)
;; TODO: this need code ux refactor
(let [stoper (get-edition-stream-stoper)
stream (rx/take-until stoper ws/mouse-position-deltas)]
stream (->> (ws/mouse-position-deltas @ws/mouse-position)
(rx/take-until stoper))]
(when @refs/selected-alignment
(st/emit! (dw/initial-path-point-align (:id shape) index)))
(rx/subscribe stream #(on-handler-move % index))))

View file

@ -39,7 +39,7 @@
:ctrl+b #(st/emit! (dw/select-for-drawing :rect))
:ctrl+e #(st/emit! (dw/select-for-drawing :circle))
:ctrl+t #(st/emit! (dw/select-for-drawing :text))
:esc #(st/emit! (dw/deselect-all))
:esc #(st/emit! dw/deselect-all)
:delete #(st/emit! dw/delete-selected)
:ctrl+up #(st/emit! (dw/order-selected-shapes :up))
:ctrl+down #(st/emit! (dw/order-selected-shapes :down))

View file

@ -57,7 +57,7 @@
(dw/select-for-drawing tool)))
(toggle-ruler [event]
(st/emit! (dw/select-for-drawing nil)
(dw/deselect-all)
dw/deselect-all
(dw/toggle-ruler)))]
(let [selected (mf/deref refs/selected-drawing-tool)

View file

@ -100,10 +100,10 @@
(st/emit! (dw/select-shape id))
(> (count selected) 1)
(st/emit! (dw/deselect-all)
(st/emit! dw/deselect-all
(dw/select-shape id))
:else
(st/emit! (dw/deselect-all)
(st/emit! dw/deselect-all
(dw/select-shape id)))))
(on-drop [item monitor]
@ -161,10 +161,10 @@
(st/emit! (dw/select-shape id))
(> (count selected) 1)
(st/emit! (dw/deselect-all)
(st/emit! dw/deselect-all
(dw/select-shape id))
:else
(st/emit! (dw/deselect-all)
(st/emit! dw/deselect-all
(dw/select-shape id)))))
(on-drop [item monitor]

View file

@ -92,7 +92,6 @@
(mf/defc sitemap-toolbox
[{:keys [project-id current-page-id] :as props}]
(prn "sitemap-toolbox" props)
(let [project-iref (mf/use-memo {:deps #js [project-id]
:fn #(-> (l/in [:projects project-id])
(l/derive st/state))})

View file

@ -94,9 +94,11 @@
(rx/subscribe-with ob sub)
sub))
(defonce mouse-position-deltas
(->> mouse-position
(rx/sample 10)
(defn mouse-position-deltas
[current]
(->> (rx/concat (rx/of current)
(rx/sample 10 mouse-position))
(rx/map #(gpt/divide % @refs/selected-zoom))
(rx/mapcat (fn [point]
(if @refs/selected-alignment
@ -104,8 +106,7 @@
(rx/of point))))
(rx/buffer 2 1)
(rx/map (fn [[old new]]
(gpt/subtract new old)))
(rx/share)))
(gpt/subtract new old)))))
(defonce viewport-scroll
(let [sub (rx/behavior-subject nil)

View file

@ -90,7 +90,7 @@
(watch [_ state stream]
(let [stoper (rx/filter #(or (dw/interrupt? %) (uws/mouse-up? %)) stream)]
(rx/concat
(rx/of (dw/deselect-all))
(rx/of dw/deselect-all)
(->> uws/mouse-position
(rx/map (fn [pos] #(update-state % pos)))
(rx/take-until stoper))

View file

@ -50,7 +50,6 @@
(s/def ::email email?)
(s/def ::color color?)
(s/def ::string string?)
(s/def ::number number?)
(s/def ::positive pos?)
(s/def ::inst inst?)
(s/def ::keyword keyword?)
@ -62,15 +61,18 @@
(s/and string? #(not (str/empty? %))))
(defn- conform-number-str
(defn- conform-number
[v]
(cond
(re-matches number-rx v) (js/parseFloat v)
(number? v) v
(re-matches number-rx v) (js/parseFloat v)
:else ::s/invalid))
(s/def ::number-str
(s/conformer conform-number-str str))
(s/def ::number
(s/conformer conform-number str))
;; NOTE: backward compatibility (revisit the code and remove)
(s/def ::number-str ::number)
(s/def ::color color?)