mirror of
https://github.com/penpot/penpot.git
synced 2025-03-15 17:21:17 -05:00
Merge pull request #206 from uxbox/238/infinite-viewport-3
Viewport Improvements and Fixes
This commit is contained in:
commit
0befd25ab7
22 changed files with 211 additions and 145 deletions
|
@ -95,6 +95,7 @@ function readLocales() {
|
||||||
|
|
||||||
function readConfig(data) {
|
function readConfig(data) {
|
||||||
const publicURL = process.env.UXBOX_PUBLIC_URL;
|
const publicURL = process.env.UXBOX_PUBLIC_URL;
|
||||||
|
const backendURL = process.env.UXBOX_BACKEND_URL;
|
||||||
const demoWarn = process.env.UXBOX_DEMO_WARNING;
|
const demoWarn = process.env.UXBOX_DEMO_WARNING;
|
||||||
const deployDate = process.env.UXBOX_DEPLOY_DATE;
|
const deployDate = process.env.UXBOX_DEPLOY_DATE;
|
||||||
const deployCommit = process.env.UXBOX_DEPLOY_COMMIT;
|
const deployCommit = process.env.UXBOX_DEPLOY_COMMIT;
|
||||||
|
@ -107,6 +108,10 @@ function readConfig(data) {
|
||||||
cfg.publicURL = publicURL;
|
cfg.publicURL = publicURL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (backendURL !== undefined) {
|
||||||
|
cfg.backendURL = backendURL;
|
||||||
|
}
|
||||||
|
|
||||||
if (deployDate !== undefined) {
|
if (deployDate !== undefined) {
|
||||||
cfg.deployDate = deployDate;
|
cfg.deployDate = deployDate;
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,7 +71,7 @@
|
||||||
|
|
||||||
.zoom-dropdown {
|
.zoom-dropdown {
|
||||||
top: 45px;
|
top: 45px;
|
||||||
left: -30px;
|
left: -40px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -93,10 +93,10 @@
|
||||||
.coordinates {
|
.coordinates {
|
||||||
background-color: $color-dark-bg;
|
background-color: $color-dark-bg;
|
||||||
border-radius: $br-small;
|
border-radius: $br-small;
|
||||||
bottom: 0px;
|
bottom: -10px;
|
||||||
padding-left: 5px;
|
padding-left: 5px;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
right: 240px;
|
right: 248px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
width: 100px;
|
width: 100px;
|
||||||
padding-bottom: 2px;
|
padding-bottom: 2px;
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
.zoom-dropdown {
|
.zoom-dropdown {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 12;
|
z-index: 12;
|
||||||
width: 150px;
|
width: 160px;
|
||||||
|
|
||||||
background-color: $color-white;
|
background-color: $color-white;
|
||||||
border-radius: $br-small;
|
border-radius: $br-small;
|
||||||
|
|
|
@ -12,9 +12,12 @@
|
||||||
|
|
||||||
(this-as global
|
(this-as global
|
||||||
(let [config (obj/get global "uxboxConfig")
|
(let [config (obj/get global "uxboxConfig")
|
||||||
url (obj/get config "publicURL" "http://localhost:6060")
|
purl (obj/get config "publicURL" "http://localhost:3449")
|
||||||
|
burl (obj/get config "backendURL" "http://localhost:6060")
|
||||||
warn (obj/get config "demoWarning" true)]
|
warn (obj/get config "demoWarning" true)]
|
||||||
(def default-language "en")
|
(def default-language "en")
|
||||||
(def demo-warning warn)
|
(def demo-warning warn)
|
||||||
(def url url)
|
(def url burl)
|
||||||
|
(def backend-url burl)
|
||||||
|
(def public-url purl)
|
||||||
(def default-theme "default")))
|
(def default-theme "default")))
|
||||||
|
|
|
@ -36,16 +36,16 @@
|
||||||
profile (:profile storage)
|
profile (:profile storage)
|
||||||
authed? (and (not (nil? profile))
|
authed? (and (not (nil? profile))
|
||||||
(not= (:id profile) uuid/zero))]
|
(not= (:id profile) uuid/zero))]
|
||||||
|
|
||||||
(cond
|
(cond
|
||||||
(and (or (= path "")
|
(and (or (= path "")
|
||||||
(nil? match))
|
(nil? match))
|
||||||
(not authed?))
|
(not authed?))
|
||||||
(st/emit! (rt/nav :login))
|
(st/emit! (rt/nav :login))
|
||||||
|
|
||||||
(and (= path "") authed?)
|
(and (nil? match) authed?)
|
||||||
(st/emit! (rt/nav :dashboard-team {:team-id (:default-team-id profile)}))
|
(st/emit! (rt/nav :dashboard-team {:team-id (:default-team-id profile)}))
|
||||||
|
|
||||||
|
|
||||||
(nil? match)
|
(nil? match)
|
||||||
(st/emit! (rt/nav :not-found))
|
(st/emit! (rt/nav :not-found))
|
||||||
|
|
||||||
|
|
|
@ -23,8 +23,8 @@
|
||||||
[uxbox.main.data.workspace.common :as dwc]
|
[uxbox.main.data.workspace.common :as dwc]
|
||||||
[uxbox.main.data.workspace.notifications :as dwn]
|
[uxbox.main.data.workspace.notifications :as dwn]
|
||||||
[uxbox.main.data.workspace.persistence :as dwp]
|
[uxbox.main.data.workspace.persistence :as dwp]
|
||||||
[uxbox.main.data.workspace.transforms :as dwt]
|
|
||||||
[uxbox.main.data.workspace.texts :as dwtxt]
|
[uxbox.main.data.workspace.texts :as dwtxt]
|
||||||
|
[uxbox.main.data.workspace.transforms :as dwt]
|
||||||
[uxbox.main.repo :as rp]
|
[uxbox.main.repo :as rp]
|
||||||
[uxbox.main.store :as st]
|
[uxbox.main.store :as st]
|
||||||
[uxbox.main.streams :as ms]
|
[uxbox.main.streams :as ms]
|
||||||
|
@ -224,8 +224,8 @@
|
||||||
(update-in state [:workspace-local :vbox]
|
(update-in state [:workspace-local :vbox]
|
||||||
(fn [vbox]
|
(fn [vbox]
|
||||||
(-> vbox
|
(-> vbox
|
||||||
(update :x (comp mth/round x))
|
(update :x x)
|
||||||
(update :y (comp mth/round y))))))))
|
(update :y y)))))))
|
||||||
|
|
||||||
;; TODO: add spec
|
;; TODO: add spec
|
||||||
|
|
||||||
|
@ -328,15 +328,16 @@
|
||||||
;; --- Zoom Management
|
;; --- Zoom Management
|
||||||
|
|
||||||
(defn- impl-update-zoom
|
(defn- impl-update-zoom
|
||||||
[{:keys [vbox vport] :as local} zoom]
|
[{:keys [vbox vport] :as local} center zoom]
|
||||||
(let [zoom (if (fn? zoom)
|
(let [new-zoom (if (fn? zoom) (zoom (:zoom local)) zoom)
|
||||||
(zoom (:zoom local))
|
old-zoom (:zoom local)
|
||||||
zoom)
|
center (if center center (geom/center vbox))
|
||||||
width (/ (:width vport) zoom)
|
scale (/ old-zoom new-zoom)
|
||||||
height (/ (:height vport) zoom)]
|
mtx (gmt/scale-matrix (gpt/point scale) center)
|
||||||
|
vbox' (geom/transform vbox mtx)]
|
||||||
(-> local
|
(-> local
|
||||||
(assoc :zoom zoom)
|
(assoc :zoom new-zoom)
|
||||||
(update :vbox assoc :width width :height height))))
|
(update :vbox merge (select-keys vbox' [:x :y :width :height])))))
|
||||||
|
|
||||||
(defn increase-zoom
|
(defn increase-zoom
|
||||||
[center]
|
[center]
|
||||||
|
@ -344,7 +345,7 @@
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(update state :workspace-local
|
(update state :workspace-local
|
||||||
#(impl-update-zoom % (fn [z] (* z 1.1)))))))
|
#(impl-update-zoom % center (fn [z] (min (* z 1.1) 200)))))))
|
||||||
|
|
||||||
(defn decrease-zoom
|
(defn decrease-zoom
|
||||||
[center]
|
[center]
|
||||||
|
@ -352,28 +353,14 @@
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(update state :workspace-local
|
(update state :workspace-local
|
||||||
#(impl-update-zoom % (fn [z] (* z 0.9)))))))
|
#(impl-update-zoom % center (fn [z] (max (* z 0.9) 0.01)))))))
|
||||||
|
|
||||||
(def reset-zoom
|
(def reset-zoom
|
||||||
(ptk/reify ::reset-zoom
|
(ptk/reify ::reset-zoom
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(update state :workspace-local
|
(update state :workspace-local
|
||||||
#(impl-update-zoom % 1)))))
|
#(impl-update-zoom % nil 1)))))
|
||||||
|
|
||||||
(def zoom-to-50
|
|
||||||
(ptk/reify ::zoom-to-50
|
|
||||||
ptk/UpdateEvent
|
|
||||||
(update [_ state]
|
|
||||||
(update state :workspace-local
|
|
||||||
#(impl-update-zoom % 0.5)))))
|
|
||||||
|
|
||||||
(def zoom-to-200
|
|
||||||
(ptk/reify ::zoom-to-200
|
|
||||||
ptk/UpdateEvent
|
|
||||||
(update [_ state]
|
|
||||||
(update state :workspace-local
|
|
||||||
#(impl-update-zoom % 2)))))
|
|
||||||
|
|
||||||
(def zoom-to-fit-all
|
(def zoom-to-fit-all
|
||||||
(ptk/reify ::zoom-to-fit-all
|
(ptk/reify ::zoom-to-fit-all
|
||||||
|
@ -1514,10 +1501,8 @@
|
||||||
"-" #(st/emit! decrease-zoom)
|
"-" #(st/emit! decrease-zoom)
|
||||||
"ctrl+g" #(st/emit! create-group)
|
"ctrl+g" #(st/emit! create-group)
|
||||||
"ctrl+shift+g" #(st/emit! remove-group)
|
"ctrl+shift+g" #(st/emit! remove-group)
|
||||||
"shift+0" #(st/emit! zoom-to-50)
|
"shift+0" #(st/emit! reset-zoom)
|
||||||
;; "shift+1" #(st/emit! reset-zoom)
|
|
||||||
"shift+1" #(st/emit! zoom-to-fit-all)
|
"shift+1" #(st/emit! zoom-to-fit-all)
|
||||||
;; "shift+2" #(st/emit! zoom-to-200)
|
|
||||||
"shift+2" #(st/emit! zoom-to-selected-shape)
|
"shift+2" #(st/emit! zoom-to-selected-shape)
|
||||||
"ctrl+d" #(st/emit! duplicate-selected)
|
"ctrl+d" #(st/emit! duplicate-selected)
|
||||||
"ctrl+z" #(st/emit! dwc/undo)
|
"ctrl+z" #(st/emit! dwc/undo)
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
(when (not= stroke-style :none)
|
(when (not= stroke-style :none)
|
||||||
(obj/merge! attrs
|
(obj/merge! attrs
|
||||||
#js {:stroke (:stroke-color shape nil)
|
#js {:stroke (:stroke-color shape nil)
|
||||||
:strokeWidth (:stroke-width shape nil)
|
:strokeWidth (:stroke-width shape 1)
|
||||||
:strokeOpacity (:stroke-opacity shape nil)
|
:strokeOpacity (:stroke-opacity shape nil)
|
||||||
:strokeDasharray (stroke-type->dasharray stroke-style)}))
|
:strokeDasharray (stroke-type->dasharray stroke-style)}))
|
||||||
attrs))
|
attrs))
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
{:keys [id x y width height]} (geom/shape->rect-shape shape)
|
{:keys [id x y width height]} (geom/shape->rect-shape shape)
|
||||||
stroke-style (:stroke-style shape :none)
|
stroke-style (:stroke-style shape :none)
|
||||||
stroke-position (:stroke-alignment shape :center)]
|
stroke-position (:stroke-alignment shape :center)]
|
||||||
|
|
||||||
(cond
|
(cond
|
||||||
;; Center alignment (or no stroke): the default in SVG
|
;; Center alignment (or no stroke): the default in SVG
|
||||||
(or (= stroke-style :none) (= stroke-position :center))
|
(or (= stroke-style :none) (= stroke-position :center))
|
||||||
|
@ -43,7 +42,7 @@
|
||||||
:fill "white"
|
:fill "white"
|
||||||
:fillOpacity 1}))
|
:fillOpacity 1}))
|
||||||
|
|
||||||
stroke-width (.-strokeWidth base-props)
|
stroke-width (obj/get base-props "strokeWidth")
|
||||||
shape-props (-> (obj/merge! #js {} base-props)
|
shape-props (-> (obj/merge! #js {} base-props)
|
||||||
(obj/merge! #js {:strokeWidth (* stroke-width 2)
|
(obj/merge! #js {:strokeWidth (* stroke-width 2)
|
||||||
:clipPath (str "url('#" clip-id "')")}))]
|
:clipPath (str "url('#" clip-id "')")}))]
|
||||||
|
|
|
@ -16,14 +16,41 @@
|
||||||
[uxbox.main.refs :as refs]
|
[uxbox.main.refs :as refs]
|
||||||
[uxbox.main.store :as st]
|
[uxbox.main.store :as st]
|
||||||
[uxbox.main.ui.components.dropdown :refer [dropdown]]
|
[uxbox.main.ui.components.dropdown :refer [dropdown]]
|
||||||
[uxbox.main.ui.workspace.header :refer [zoom-widget]]
|
|
||||||
[uxbox.util.data :refer [classnames]]
|
[uxbox.util.data :refer [classnames]]
|
||||||
[uxbox.util.dom :as dom]
|
[uxbox.util.dom :as dom]
|
||||||
[uxbox.util.i18n :as i18n :refer [t]]
|
[uxbox.util.i18n :as i18n :refer [t]]
|
||||||
[uxbox.util.router :as rt]
|
[uxbox.util.router :as rt]
|
||||||
|
[uxbox.util.math :as mth]
|
||||||
[uxbox.common.uuid :as uuid]
|
[uxbox.common.uuid :as uuid]
|
||||||
[uxbox.util.webapi :as wapi]))
|
[uxbox.util.webapi :as wapi]))
|
||||||
|
|
||||||
|
(mf/defc zoom-widget
|
||||||
|
{:wrap [mf/memo]}
|
||||||
|
[{:keys [zoom
|
||||||
|
on-increase
|
||||||
|
on-decrease
|
||||||
|
on-zoom-to-50
|
||||||
|
on-zoom-to-100
|
||||||
|
on-zoom-to-200]
|
||||||
|
:as props}]
|
||||||
|
(let [show-dropdown? (mf/use-state false)]
|
||||||
|
[:div.zoom-widget {:on-click #(reset! show-dropdown? true)}
|
||||||
|
[:span {} (str (mth/round (* 100 zoom)) "%")]
|
||||||
|
[:span.dropdown-button i/arrow-down]
|
||||||
|
[:& dropdown {:show @show-dropdown?
|
||||||
|
:on-close #(reset! show-dropdown? false)}
|
||||||
|
[:ul.zoom-dropdown
|
||||||
|
[:li {:on-click on-increase}
|
||||||
|
"Zoom in" [:span "+"]]
|
||||||
|
[:li {:on-click on-decrease}
|
||||||
|
"Zoom out" [:span "-"]]
|
||||||
|
[:li {:on-click on-zoom-to-50}
|
||||||
|
"Zoom to 50%" [:span "Shift + 0"]]
|
||||||
|
[:li {:on-click on-zoom-to-100}
|
||||||
|
"Zoom to 100%" [:span "Shift + 1"]]
|
||||||
|
[:li {:on-click on-zoom-to-200}
|
||||||
|
"Zoom to 200%" [:span "Shift + 2"]]]]]))
|
||||||
|
|
||||||
(mf/defc interactions-menu
|
(mf/defc interactions-menu
|
||||||
[{:keys [interactions-mode] :as props}]
|
[{:keys [interactions-mode] :as props}]
|
||||||
(let [show-dropdown? (mf/use-state false)
|
(let [show-dropdown? (mf/use-state false)
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
[uxbox.main.ui.keyboard :as kbd]
|
[uxbox.main.ui.keyboard :as kbd]
|
||||||
[uxbox.main.ui.hooks :as hooks]
|
[uxbox.main.ui.hooks :as hooks]
|
||||||
[uxbox.main.ui.messages :refer [messages]]
|
[uxbox.main.ui.messages :refer [messages]]
|
||||||
[uxbox.main.ui.workspace.viewport :refer [viewport]]
|
[uxbox.main.ui.workspace.viewport :refer [viewport coordinates]]
|
||||||
[uxbox.main.ui.workspace.colorpalette :refer [colorpalette]]
|
[uxbox.main.ui.workspace.colorpalette :refer [colorpalette]]
|
||||||
[uxbox.main.ui.workspace.context-menu :refer [context-menu]]
|
[uxbox.main.ui.workspace.context-menu :refer [context-menu]]
|
||||||
[uxbox.main.ui.workspace.header :refer [header]]
|
[uxbox.main.ui.workspace.header :refer [header]]
|
||||||
|
@ -65,7 +65,9 @@
|
||||||
:vport (:vport local)}]
|
:vport (:vport local)}]
|
||||||
[:& vertical-rule {:zoom (:zoom local 1)
|
[:& vertical-rule {:zoom (:zoom local 1)
|
||||||
:vbox (:vbox local)
|
:vbox (:vbox local)
|
||||||
:vport (:vport local)}]])
|
:vport (:vport local)}]
|
||||||
|
[:& coordinates]])
|
||||||
|
|
||||||
|
|
||||||
[:& viewport {:page page
|
[:& viewport {:page page
|
||||||
:key (:id page)
|
:key (:id page)
|
||||||
|
|
|
@ -276,7 +276,6 @@
|
||||||
(ptk/reify ::handle-drawing-curve
|
(ptk/reify ::handle-drawing-curve
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state stream]
|
(watch [_ state stream]
|
||||||
(prn "handle-drawing-curve")
|
|
||||||
(let [{:keys [flags]} (:workspace-local state)
|
(let [{:keys [flags]} (:workspace-local state)
|
||||||
stoper (rx/filter stoper-event? stream)
|
stoper (rx/filter stoper-event? stream)
|
||||||
mouse (rx/sample 10 ms/mouse-position)]
|
mouse (rx/sample 10 ms/mouse-position)]
|
||||||
|
@ -323,14 +322,14 @@
|
||||||
(declare path-draw-area)
|
(declare path-draw-area)
|
||||||
|
|
||||||
(mf/defc draw-area
|
(mf/defc draw-area
|
||||||
[{:keys [shape] :as props}]
|
[{:keys [shape zoom] :as props}]
|
||||||
(when (:id shape)
|
(when (:id shape)
|
||||||
(case (:type shape)
|
(case (:type shape)
|
||||||
(:path :curve) [:& path-draw-area {:shape shape}]
|
(:path :curve) [:& path-draw-area {:shape shape}]
|
||||||
[:& generic-draw-area {:shape shape}])))
|
[:& generic-draw-area {:shape shape :zoom zoom}])))
|
||||||
|
|
||||||
(mf/defc generic-draw-area
|
(mf/defc generic-draw-area
|
||||||
[{:keys [shape]}]
|
[{:keys [shape zoom]}]
|
||||||
(let [{:keys [x y width height]} (geom/selection-rect-shape shape)]
|
(let [{:keys [x y width height]} (geom/selection-rect-shape shape)]
|
||||||
(when (and x y)
|
(when (and x y)
|
||||||
[:g
|
[:g
|
||||||
|
@ -340,7 +339,7 @@
|
||||||
:height height
|
:height height
|
||||||
:style {:stroke "#1FDEA7"
|
:style {:stroke "#1FDEA7"
|
||||||
:fill "transparent"
|
:fill "transparent"
|
||||||
:stroke-width "1"}}]])))
|
:stroke-width (/ 1 zoom)}}]])))
|
||||||
|
|
||||||
(mf/defc path-draw-area
|
(mf/defc path-draw-area
|
||||||
[{:keys [shape] :as props}]
|
[{:keys [shape] :as props}]
|
||||||
|
|
|
@ -33,9 +33,9 @@
|
||||||
[{:keys [zoom
|
[{:keys [zoom
|
||||||
on-increase
|
on-increase
|
||||||
on-decrease
|
on-decrease
|
||||||
on-zoom-to-50
|
on-zoom-reset
|
||||||
on-zoom-to-100
|
on-zoom-fit
|
||||||
on-zoom-to-200]
|
on-zoom-selected]
|
||||||
:as props}]
|
:as props}]
|
||||||
(let [show-dropdown? (mf/use-state false)]
|
(let [show-dropdown? (mf/use-state false)]
|
||||||
[:div.zoom-widget {:on-click #(reset! show-dropdown? true)}
|
[:div.zoom-widget {:on-click #(reset! show-dropdown? true)}
|
||||||
|
@ -48,12 +48,12 @@
|
||||||
"Zoom in" [:span "+"]]
|
"Zoom in" [:span "+"]]
|
||||||
[:li {:on-click on-decrease}
|
[:li {:on-click on-decrease}
|
||||||
"Zoom out" [:span "-"]]
|
"Zoom out" [:span "-"]]
|
||||||
[:li {:on-click on-zoom-to-50}
|
[:li {:on-click on-zoom-reset}
|
||||||
"Zoom to 50%" [:span "Shift + 0"]]
|
"Zoom to 100%" [:span "Shift + 0"]]
|
||||||
[:li {:on-click on-zoom-to-100}
|
[:li {:on-click on-zoom-fit}
|
||||||
"Zoom to 100%" [:span "Shift + 1"]]
|
"Zoom to fit all" [:span "Shift + 1"]]
|
||||||
[:li {:on-click on-zoom-to-200}
|
[:li {:on-click on-zoom-selected}
|
||||||
"Zoom to 200%" [:span "Shift + 2"]]]]]))
|
"Zoom to selected" [:span "Shift + 2"]]]]]))
|
||||||
|
|
||||||
;; --- Header Users
|
;; --- Header Users
|
||||||
|
|
||||||
|
@ -145,9 +145,9 @@
|
||||||
{:zoom zoom
|
{:zoom zoom
|
||||||
:on-increase #(st/emit! dw/increase-zoom)
|
:on-increase #(st/emit! dw/increase-zoom)
|
||||||
:on-decrease #(st/emit! dw/decrease-zoom)
|
:on-decrease #(st/emit! dw/decrease-zoom)
|
||||||
:on-zoom-to-50 #(st/emit! dw/zoom-to-50)
|
:on-zoom-reset #(st/emit! dw/reset-zoom)
|
||||||
:on-zoom-to-100 #(st/emit! dw/reset-zoom)
|
:on-zoom-fit #(st/emit! dw/zoom-to-fit-all)
|
||||||
:on-zoom-to-200 #(st/emit! dw/zoom-to-200)}]
|
:on-zoom-selected #(st/emit! dw/zoom-to-selected-shape)}]
|
||||||
|
|
||||||
[:a.btn-icon-dark.btn-small
|
[:a.btn-icon-dark.btn-small
|
||||||
{;; :target "__blank"
|
{;; :target "__blank"
|
||||||
|
|
|
@ -13,15 +13,30 @@
|
||||||
[uxbox.util.math :as mth]
|
[uxbox.util.math :as mth]
|
||||||
[uxbox.util.object :as obj]))
|
[uxbox.util.object :as obj]))
|
||||||
|
|
||||||
|
(defn- calculate-step-size
|
||||||
|
[zoom]
|
||||||
|
(cond
|
||||||
|
(< 0 zoom 0.008) 10000
|
||||||
|
(< 0.008 zoom 0.015) 5000
|
||||||
|
(< 0.015 zoom 0.04) 2500
|
||||||
|
(< 0.04 zoom 0.07) 1000
|
||||||
|
(< 0.07 zoom 0.2) 500
|
||||||
|
(< 0.2 zoom 0.5) 250
|
||||||
|
(< 0.5 zoom 1) 100
|
||||||
|
(<= 1 zoom 2) 50
|
||||||
|
(< 2 zoom 4) 25
|
||||||
|
(< 4 zoom 6) 10
|
||||||
|
(< 6 zoom 15) 5
|
||||||
|
(< 15 zoom 25) 2
|
||||||
|
(< 25 zoom) 1
|
||||||
|
:else 1))
|
||||||
|
|
||||||
(defn draw-rule!
|
(defn draw-rule!
|
||||||
[dctx {:keys [zoom size start count type] :or {count 200}}]
|
[dctx {:keys [zoom size start count type] :or {count 200}}]
|
||||||
(let [txfm (- (* (- 0 start) zoom) 20)
|
(let [txfm (- (* (- 0 start) zoom) 20)
|
||||||
minv (mth/round start)
|
minv (mth/round start)
|
||||||
maxv (mth/round (+ start (/ size zoom)))
|
maxv (mth/round (+ start (/ size zoom)))
|
||||||
|
step (calculate-step-size zoom)]
|
||||||
step (mth/round (/ (mth/abs (- maxv minv)) count))
|
|
||||||
step (max (* 1 (* 10 step)) 1)]
|
|
||||||
|
|
||||||
(obj/set! dctx "fillStyle" "#E8E9EA")
|
(obj/set! dctx "fillStyle" "#E8E9EA")
|
||||||
(if (= type :horizontal)
|
(if (= type :horizontal)
|
||||||
(do
|
(do
|
||||||
|
@ -31,7 +46,7 @@
|
||||||
(.fillRect dctx 0 0 20 size)
|
(.fillRect dctx 0 0 20 size)
|
||||||
(.translate dctx 0 txfm)))
|
(.translate dctx 0 txfm)))
|
||||||
|
|
||||||
(obj/set! dctx "font" "12px serif")
|
(obj/set! dctx "font" "12px sourcesanspro")
|
||||||
(obj/set! dctx "fillStyle" "#7B7D85")
|
(obj/set! dctx "fillStyle" "#7B7D85")
|
||||||
(obj/set! dctx "strokeStyle" "#7B7D85")
|
(obj/set! dctx "strokeStyle" "#7B7D85")
|
||||||
(obj/set! dctx "textAlign" "center")
|
(obj/set! dctx "textAlign" "center")
|
||||||
|
|
|
@ -113,13 +113,14 @@
|
||||||
|
|
||||||
[:g.controls
|
[:g.controls
|
||||||
(when (not (#{:move :rotate :resize} current-transform))
|
(when (not (#{:move :rotate :resize} current-transform))
|
||||||
[:rect.main {:transform transform
|
[:rect.main
|
||||||
:x (- x 1) :y (- y 1)
|
{:transform transform
|
||||||
:width (+ width 2)
|
:x x :y y
|
||||||
:height (+ height 2)
|
:width width
|
||||||
:style {:stroke "#1FDEA7"
|
:height height
|
||||||
:stroke-width (/ 1 zoom)
|
:style {:stroke "#1FDEA7"
|
||||||
:fill "transparent"}}])
|
:stroke-width (/ 1 zoom)
|
||||||
|
:fill "transparent"}}])
|
||||||
|
|
||||||
(when (not (#{:move :rotate} current-transform))
|
(when (not (#{:move :rotate} current-transform))
|
||||||
(for [[position [cx cy]] resize-handlers]
|
(for [[position [cx cy]] resize-handlers]
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
;; --- Coordinates Widget
|
;; --- Coordinates Widget
|
||||||
|
|
||||||
(mf/defc coordinates
|
(mf/defc coordinates
|
||||||
[{:keys [zoom] :as props}]
|
[]
|
||||||
(let [coords (some-> (hooks/use-rxsub ms/mouse-position)
|
(let [coords (some-> (hooks/use-rxsub ms/mouse-position)
|
||||||
(gpt/round 0))]
|
(gpt/round 0))]
|
||||||
[:ul.coordinates
|
[:ul.coordinates
|
||||||
|
@ -268,21 +268,27 @@
|
||||||
on-mouse-wheel
|
on-mouse-wheel
|
||||||
(mf/use-callback
|
(mf/use-callback
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(dom/prevent-default event)
|
(let [node (mf/ref-val viewport-ref)
|
||||||
(dom/stop-propagation event)
|
target (dom/get-target event)]
|
||||||
|
(cond
|
||||||
|
(kbd/ctrl? event)
|
||||||
|
(let [event (.getBrowserEvent event)
|
||||||
|
pos @ms/mouse-position]
|
||||||
|
(dom/prevent-default event)
|
||||||
|
(dom/stop-propagation event)
|
||||||
|
(if (pos? (.-deltaY event))
|
||||||
|
(st/emit! (dw/decrease-zoom pos))
|
||||||
|
(st/emit! (dw/increase-zoom pos))))
|
||||||
|
|
||||||
(if (kbd/ctrl? event)
|
(.contains ^js node target)
|
||||||
(let [event (.getBrowserEvent event)
|
(let [event (.getBrowserEvent event)
|
||||||
pos @ms/mouse-position]
|
delta (.-deltaY ^js event)
|
||||||
(if (pos? (.-deltaY event))
|
delta (/ delta @refs/selected-zoom)]
|
||||||
(st/emit! (dw/decrease-zoom pos))
|
(dom/prevent-default event)
|
||||||
(st/emit! (dw/increase-zoom pos))))
|
(dom/stop-propagation event)
|
||||||
(let [event (.getBrowserEvent event)
|
(if (kbd/shift? event)
|
||||||
delta (.-deltaY ^js event)
|
(st/emit! (dw/update-viewport-position {:x #(+ % delta)}))
|
||||||
delta (/ delta @refs/selected-zoom)]
|
(st/emit! (dw/update-viewport-position {:y #(+ % delta)}))))))))
|
||||||
(if (kbd/shift? event)
|
|
||||||
(st/emit! (dw/update-viewport-position {:x #(+ % delta)}))
|
|
||||||
(st/emit! (dw/update-viewport-position {:y #(+ % delta)})))))))
|
|
||||||
|
|
||||||
on-drag-over
|
on-drag-over
|
||||||
;; Should prevent only events that we'll handle on-drop
|
;; Should prevent only events that we'll handle on-drop
|
||||||
|
@ -331,52 +337,50 @@
|
||||||
]
|
]
|
||||||
|
|
||||||
(mf/use-effect on-mount)
|
(mf/use-effect on-mount)
|
||||||
[:*
|
[:svg.viewport
|
||||||
[:& coordinates {:zoom zoom}]
|
{:preserveAspectRatio "xMidYMid meet"
|
||||||
[:svg.viewport
|
:width (:width vport 0)
|
||||||
{:preserveAspectRatio "xMidYMid meet"
|
:height (:height vport 0)
|
||||||
:width (:width vport 0)
|
:view-box (str/join " " [(:x vbox 0)
|
||||||
:height (:height vport 0)
|
(:y vbox 0)
|
||||||
:view-box (str/join " " [(:x vbox 0)
|
(:width vbox 0 )
|
||||||
(:y vbox 0)
|
(:height vbox 0)])
|
||||||
(:width vbox 0 )
|
:ref viewport-ref
|
||||||
(:height vbox 0)])
|
:class (when drawing-tool "drawing")
|
||||||
:ref viewport-ref
|
:on-context-menu on-context-menu
|
||||||
:class (when drawing-tool "drawing")
|
:on-click on-click
|
||||||
:on-context-menu on-context-menu
|
:on-double-click on-double-click
|
||||||
:on-click on-click
|
:on-mouse-down on-mouse-down
|
||||||
:on-double-click on-double-click
|
:on-mouse-up on-mouse-up
|
||||||
:on-mouse-down on-mouse-down
|
:on-drag-over on-drag-over
|
||||||
:on-mouse-up on-mouse-up
|
:on-drop on-drop}
|
||||||
:on-drag-over on-drag-over
|
[:g
|
||||||
:on-drop on-drop}
|
[:& frames {:key (:id page)}]
|
||||||
[:g
|
|
||||||
[:& frames {:key (:id page)}]
|
|
||||||
|
|
||||||
(when (seq selected)
|
(when (seq selected)
|
||||||
[:& selection-handlers {:selected selected
|
[:& selection-handlers {:selected selected
|
||||||
:zoom zoom
|
:zoom zoom
|
||||||
:edition edition}])
|
:edition edition}])
|
||||||
|
|
||||||
|
|
||||||
(when-let [drawing-shape (:drawing local)]
|
(when-let [drawing-shape (:drawing local)]
|
||||||
[:& draw-area {:shape drawing-shape
|
[:& draw-area {:shape drawing-shape
|
||||||
:zoom zoom
|
:zoom zoom
|
||||||
:modifiers (:modifiers local)}])
|
:modifiers (:modifiers local)}])
|
||||||
|
|
||||||
[:& snap-feedback]
|
[:& snap-feedback]
|
||||||
|
|
||||||
(when (contains? flags :grid)
|
(when (contains? flags :grid)
|
||||||
[:& grid])]
|
[:& grid])]
|
||||||
|
|
||||||
(when tooltip
|
(when tooltip
|
||||||
[:& cursor-tooltip {:zoom zoom :tooltip tooltip}])
|
[:& cursor-tooltip {:zoom zoom :tooltip tooltip}])
|
||||||
|
|
||||||
(when (contains? flags :ruler)
|
(when (contains? flags :ruler)
|
||||||
[:& ruler {:zoom zoom :ruler (:ruler local)}])
|
[:& ruler {:zoom zoom :ruler (:ruler local)}])
|
||||||
|
|
||||||
[:& presence/active-cursors {:page page}]
|
[:& presence/active-cursors {:page page}]
|
||||||
[:& selection-rect {:data (:selrect local)}]
|
[:& selection-rect {:data (:selrect local)}]
|
||||||
(when (= options-mode :prototype)
|
(when (= options-mode :prototype)
|
||||||
[:& interactions {:selected selected}])]]))
|
[:& interactions {:selected selected}])]))
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,9 @@
|
||||||
[cljs.spec.alpha :as s]
|
[cljs.spec.alpha :as s]
|
||||||
[uxbox.config :as cfg]
|
[uxbox.config :as cfg]
|
||||||
[uxbox.common.spec :as us]
|
[uxbox.common.spec :as us]
|
||||||
[uxbox.util.worker :as uw]))
|
[uxbox.util.worker :as uw])
|
||||||
|
(:import
|
||||||
|
goog.Uri))
|
||||||
|
|
||||||
(defn on-error
|
(defn on-error
|
||||||
[instance error]
|
[instance error]
|
||||||
|
@ -20,7 +22,10 @@
|
||||||
|
|
||||||
(defonce instance
|
(defonce instance
|
||||||
(when (not= *target* "nodejs")
|
(when (not= *target* "nodejs")
|
||||||
(uw/init "js/worker.js" on-error)))
|
(let [uri (Uri. cfg/public-url)]
|
||||||
|
(.setPath uri "js/worker.js")
|
||||||
|
(.setParameterValue uri "backendURL" cfg/backend-url)
|
||||||
|
(uw/init (.toString uri) on-error))))
|
||||||
|
|
||||||
(defn ask!
|
(defn ask!
|
||||||
[message]
|
[message]
|
||||||
|
|
|
@ -43,8 +43,8 @@
|
||||||
for rect-like shapes."
|
for rect-like shapes."
|
||||||
[shape {dx :x dy :y}]
|
[shape {dx :x dy :y}]
|
||||||
(assoc shape
|
(assoc shape
|
||||||
:x (mth/round (+ (_chk (:x shape)) (_chk dx)))
|
:x (+ (_chk (:x shape)) (_chk dx))
|
||||||
:y (mth/round (+ (_chk (:y shape)) (_chk dy)))))
|
:y (+ (_chk (:y shape)) (_chk dy))))
|
||||||
|
|
||||||
(defn- move-path
|
(defn- move-path
|
||||||
"A specialized function for relative movement
|
"A specialized function for relative movement
|
||||||
|
|
|
@ -20,8 +20,20 @@
|
||||||
[uxbox.worker.selection]
|
[uxbox.worker.selection]
|
||||||
[uxbox.worker.thumbnails]
|
[uxbox.worker.thumbnails]
|
||||||
[uxbox.worker.snaps]
|
[uxbox.worker.snaps]
|
||||||
|
[uxbox.util.object :as obj]
|
||||||
[uxbox.util.transit :as t]
|
[uxbox.util.transit :as t]
|
||||||
[uxbox.util.worker :as w]))
|
[uxbox.util.worker :as w])
|
||||||
|
(:import goog.Uri))
|
||||||
|
|
||||||
|
;; --- Initialization
|
||||||
|
|
||||||
|
(this-as global
|
||||||
|
(let [location (obj/get global "location")
|
||||||
|
uri (Uri. (obj/get location "href"))
|
||||||
|
buri (.getParameterValue uri "backendURL")]
|
||||||
|
(swap! impl/config assoc :backend-url buri)))
|
||||||
|
|
||||||
|
;; --- Messages Handling
|
||||||
|
|
||||||
(s/def ::cmd keyword?)
|
(s/def ::cmd keyword?)
|
||||||
(s/def ::payload
|
(s/def ::payload
|
||||||
|
|
|
@ -5,10 +5,16 @@
|
||||||
;; Copyright (c) 2016 Andrey Antukh <niwi@niwi.nz>
|
;; Copyright (c) 2016 Andrey Antukh <niwi@niwi.nz>
|
||||||
|
|
||||||
(ns uxbox.worker.impl
|
(ns uxbox.worker.impl
|
||||||
(:require [uxbox.util.transit :as t]))
|
(:require
|
||||||
|
[okulary.core :as l]
|
||||||
|
[uxbox.util.transit :as t]))
|
||||||
|
|
||||||
(enable-console-print!)
|
(enable-console-print!)
|
||||||
|
|
||||||
|
;; --- Config
|
||||||
|
|
||||||
|
(defonce config (l/atom {}))
|
||||||
|
|
||||||
;; --- Handler
|
;; --- Handler
|
||||||
|
|
||||||
(defmulti handler :cmd)
|
(defmulti handler :cmd)
|
||||||
|
|
|
@ -33,16 +33,18 @@
|
||||||
|
|
||||||
(defn- request-page
|
(defn- request-page
|
||||||
[id]
|
[id]
|
||||||
(p/create
|
(let [url (get @impl/config :backend-url "http://localhost:6060")
|
||||||
(fn [resolve reject]
|
url (str url "/api/w/query/page")]
|
||||||
(->> (http/send! {:url "http://localhost:6060/api/w/query/page"
|
(p/create
|
||||||
:query {:id id}
|
(fn [resolve reject]
|
||||||
:method :get})
|
(->> (http/send! {:url url
|
||||||
(rx/mapcat handle-response)
|
:query {:id id}
|
||||||
(rx/subs (fn [body]
|
:method :get})
|
||||||
(resolve (:data body)))
|
(rx/mapcat handle-response)
|
||||||
(fn [error]
|
(rx/subs (fn [body]
|
||||||
(reject error)))))))
|
(resolve (:data body)))
|
||||||
|
(fn [error]
|
||||||
|
(reject error))))))))
|
||||||
|
|
||||||
(defmethod impl/handler :thumbnails/generate
|
(defmethod impl/handler :thumbnails/generate
|
||||||
[{:keys [id] :as message}]
|
[{:keys [id] :as message}]
|
||||||
|
|
|
@ -56,6 +56,7 @@ function build-frontend {
|
||||||
--mount source=${HOME}/.m2,type=bind,target=/home/uxbox/.m2 \
|
--mount source=${HOME}/.m2,type=bind,target=/home/uxbox/.m2 \
|
||||||
-w /home/uxbox/uxbox/frontend \
|
-w /home/uxbox/uxbox/frontend \
|
||||||
-e UXBOX_PUBLIC_URL=${UXBOX_PUBLIC_URL} \
|
-e UXBOX_PUBLIC_URL=${UXBOX_PUBLIC_URL} \
|
||||||
|
-e UXBOX_BACKEND_URL=${UXBOX_BACKEND_URL} \
|
||||||
-e UXBOX_DEMO_WARNING=${UXBOX_DEMO_WARNING} \
|
-e UXBOX_DEMO_WARNING=${UXBOX_DEMO_WARNING} \
|
||||||
-e UXBOX_DEPLOY_DATE=${UXBOX_DEPLOY_DATE} \
|
-e UXBOX_DEPLOY_DATE=${UXBOX_DEPLOY_DATE} \
|
||||||
-e UXBOX_DEPLOY_COMMIT=${UXBOX_DEPLOY_COMMIT} \
|
-e UXBOX_DEPLOY_COMMIT=${UXBOX_DEPLOY_COMMIT} \
|
||||||
|
|
Loading…
Add table
Reference in a new issue