mirror of
https://github.com/penpot/penpot.git
synced 2025-06-04 07:01:39 +02:00
✨ Add viewport information to the plugin
This commit is contained in:
parent
5e396010b3
commit
4a74862bf5
4 changed files with 150 additions and 22 deletions
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
(ns app.main.data.workspace.zoom
|
(ns app.main.data.workspace.zoom
|
||||||
(:require
|
(:require
|
||||||
|
[app.common.data :as d]
|
||||||
|
[app.common.data.macros :as dm]
|
||||||
[app.common.files.helpers :as cfh]
|
[app.common.files.helpers :as cfh]
|
||||||
[app.common.geom.align :as gal]
|
[app.common.geom.align :as gal]
|
||||||
[app.common.geom.matrix :as gmt]
|
[app.common.geom.matrix :as gmt]
|
||||||
|
@ -54,14 +56,20 @@
|
||||||
#(impl-update-zoom % center (fn [z] (max (/ z 1.3) 0.01)))))))))
|
#(impl-update-zoom % center (fn [z] (max (/ z 1.3) 0.01)))))))))
|
||||||
|
|
||||||
(defn set-zoom
|
(defn set-zoom
|
||||||
[center scale]
|
([scale]
|
||||||
(ptk/reify ::set-zoom
|
(set-zoom nil scale))
|
||||||
ptk/UpdateEvent
|
([center scale]
|
||||||
(update [_ state]
|
(ptk/reify ::set-zoom
|
||||||
(update state :workspace-local
|
ptk/UpdateEvent
|
||||||
#(impl-update-zoom % center (fn [z] (-> (* z scale)
|
(update [_ state]
|
||||||
(max 0.01)
|
(let [vp (dm/get-in state [:workspace-local :vbox])
|
||||||
(min 200))))))))
|
x (+ (:x vp) (/ (:width vp) 2))
|
||||||
|
y (+ (:y vp) (/ (:height vp) 2))
|
||||||
|
center (d/nilv center (gpt/point x y))]
|
||||||
|
(update state :workspace-local
|
||||||
|
#(impl-update-zoom % center (fn [z] (-> (* z scale)
|
||||||
|
(max 0.01)
|
||||||
|
(min 200))))))))))
|
||||||
|
|
||||||
(def reset-zoom
|
(def reset-zoom
|
||||||
(ptk/reify ::reset-zoom
|
(ptk/reify ::reset-zoom
|
||||||
|
@ -110,6 +118,32 @@
|
||||||
(assoc :zoom-inverse (/ 1 zoom))
|
(assoc :zoom-inverse (/ 1 zoom))
|
||||||
(update :vbox merge srect)))))))))))
|
(update :vbox merge srect)))))))))))
|
||||||
|
|
||||||
|
(defn fit-to-shapes
|
||||||
|
[ids]
|
||||||
|
(ptk/reify ::fit-to-shapes
|
||||||
|
ptk/UpdateEvent
|
||||||
|
(update [_ state]
|
||||||
|
(if (empty? ids)
|
||||||
|
state
|
||||||
|
(let [page-id (:current-page-id state)
|
||||||
|
objects (wsh/lookup-page-objects state page-id)
|
||||||
|
_ (prn "??" (->> ids (map #(get objects %)) (map :name)))
|
||||||
|
srect (->> ids
|
||||||
|
(map #(get objects %))
|
||||||
|
(gsh/shapes->rect))]
|
||||||
|
|
||||||
|
(update state :workspace-local
|
||||||
|
(fn [{:keys [vport] :as local}]
|
||||||
|
(let [srect (gal/adjust-to-viewport
|
||||||
|
vport srect
|
||||||
|
{:padding 40})
|
||||||
|
zoom (/ (:width vport)
|
||||||
|
(:width srect))]
|
||||||
|
(-> local
|
||||||
|
(assoc :zoom zoom)
|
||||||
|
(assoc :zoom-inverse (/ 1 zoom))
|
||||||
|
(update :vbox merge srect))))))))))
|
||||||
|
|
||||||
(defn start-zooming [pt]
|
(defn start-zooming [pt]
|
||||||
(ptk/reify ::start-zooming
|
(ptk/reify ::start-zooming
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
|
|
|
@ -17,7 +17,8 @@
|
||||||
[app.plugins.events :as events]
|
[app.plugins.events :as events]
|
||||||
[app.plugins.file :as file]
|
[app.plugins.file :as file]
|
||||||
[app.plugins.page :as page]
|
[app.plugins.page :as page]
|
||||||
[app.plugins.shape :as shape]))
|
[app.plugins.shape :as shape]
|
||||||
|
[app.plugins.viewport :as viewport]))
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; PLUGINS PUBLIC API - The plugins will able to access this functions
|
;; PLUGINS PUBLIC API - The plugins will able to access this functions
|
||||||
|
@ -28,12 +29,30 @@
|
||||||
(map val)
|
(map val)
|
||||||
(map shape/data->shape-proxy)))
|
(map shape/data->shape-proxy)))
|
||||||
|
|
||||||
|
(defn create-shape
|
||||||
|
[type]
|
||||||
|
(let [page-id (:current-page-id @st/state)
|
||||||
|
page (dm/get-in @st/state [:workspace-data :pages-index page-id])
|
||||||
|
shape (cts/setup-shape {:type :type
|
||||||
|
:x 0 :y 0 :width 100 :height 100})
|
||||||
|
changes
|
||||||
|
(-> (cb/empty-changes)
|
||||||
|
(cb/with-page page)
|
||||||
|
(cb/with-objects (:objects page))
|
||||||
|
(cb/add-object shape))]
|
||||||
|
(st/emit! (ch/commit-changes changes))
|
||||||
|
(shape/data->shape-proxy shape)))
|
||||||
|
|
||||||
(deftype PenpotContext []
|
(deftype PenpotContext []
|
||||||
Object
|
Object
|
||||||
(addListener
|
(addListener
|
||||||
[_ type callback]
|
[_ type callback]
|
||||||
(events/add-listener type callback))
|
(events/add-listener type callback))
|
||||||
|
|
||||||
|
(getViewport
|
||||||
|
[_]
|
||||||
|
(viewport/create-proxy))
|
||||||
|
|
||||||
(getFile
|
(getFile
|
||||||
[_]
|
[_]
|
||||||
(file/data->file-proxy (:workspace-file @st/state) (:workspace-data @st/state)))
|
(file/data->file-proxy (:workspace-file @st/state) (:workspace-data @st/state)))
|
||||||
|
@ -70,19 +89,13 @@
|
||||||
"dark"
|
"dark"
|
||||||
(get-in @st/state [:profile :theme]))))
|
(get-in @st/state [:profile :theme]))))
|
||||||
|
|
||||||
|
(createFrame
|
||||||
|
[_]
|
||||||
|
(create-shape :frame))
|
||||||
|
|
||||||
(createRectangle
|
(createRectangle
|
||||||
[_]
|
[_]
|
||||||
(let [page-id (:current-page-id @st/state)
|
(create-shape :rect)))
|
||||||
page (dm/get-in @st/state [:workspace-data :pages-index page-id])
|
|
||||||
shape (cts/setup-shape {:type :rect
|
|
||||||
:x 0 :y 0 :width 100 :height 100})
|
|
||||||
changes
|
|
||||||
(-> (cb/empty-changes)
|
|
||||||
(cb/with-page page)
|
|
||||||
(cb/with-objects (:objects page))
|
|
||||||
(cb/add-object shape))]
|
|
||||||
(st/emit! (ch/commit-changes changes))
|
|
||||||
(shape/data->shape-proxy shape))))
|
|
||||||
|
|
||||||
(defn create-context
|
(defn create-context
|
||||||
[]
|
[]
|
||||||
|
@ -90,4 +103,5 @@
|
||||||
(PenpotContext.)
|
(PenpotContext.)
|
||||||
{:name "root" :get #(.getRoot ^js %)}
|
{:name "root" :get #(.getRoot ^js %)}
|
||||||
{:name "currentPage" :get #(.getPage ^js %)}
|
{:name "currentPage" :get #(.getPage ^js %)}
|
||||||
{:name "selection" :get #(.getSelectedShapes ^js %)}))
|
{:name "selection" :get #(.getSelectedShapes ^js %)}
|
||||||
|
{:name "viewport" :get #(.getViewport ^js %)}))
|
||||||
|
|
|
@ -69,7 +69,8 @@
|
||||||
|
|
||||||
(clone [_] (.log js/console (clj->js _data)))
|
(clone [_] (.log js/console (clj->js _data)))
|
||||||
(delete [_] (.log js/console (clj->js _data)))
|
(delete [_] (.log js/console (clj->js _data)))
|
||||||
(appendChild [_] (.log js/console (clj->js _data))))
|
(appendChild [_ child] (.log js/console (clj->js _data)))
|
||||||
|
(insertChild [_ index child] (.log js/console (clj->js _data))))
|
||||||
|
|
||||||
(crc/define-properties!
|
(crc/define-properties!
|
||||||
ShapeProxy
|
ShapeProxy
|
||||||
|
|
79
frontend/src/app/plugins/viewport.cljs
Normal file
79
frontend/src/app/plugins/viewport.cljs
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
;; 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) KALEIDOS INC
|
||||||
|
|
||||||
|
(ns app.plugins.viewport
|
||||||
|
"RPC for plugins runtime."
|
||||||
|
(:require
|
||||||
|
[app.common.data.macros :as dm]
|
||||||
|
[app.common.geom.point :as gpt]
|
||||||
|
[app.common.record :as crc]
|
||||||
|
[app.common.record :as crc]
|
||||||
|
[app.common.uuid :as uuid]
|
||||||
|
[app.main.data.workspace.viewport :as dwv]
|
||||||
|
[app.main.data.workspace.zoom :as dwz]
|
||||||
|
[app.main.store :as st]
|
||||||
|
[app.plugins.page :as page]
|
||||||
|
[app.plugins.utils :refer [get-data-fn]]
|
||||||
|
[app.util.object :as obj]))
|
||||||
|
|
||||||
|
(deftype ViewportProxy []
|
||||||
|
Object
|
||||||
|
(zoomIntoView [_ shapes]
|
||||||
|
(let [ids
|
||||||
|
(->> shapes
|
||||||
|
(map (fn [v]
|
||||||
|
(if (string? v)
|
||||||
|
(uuid/uuid v)
|
||||||
|
(uuid/uuid (obj/get v "x"))))))]
|
||||||
|
(st/emit! (dwz/fit-to-shapes ids)))))
|
||||||
|
|
||||||
|
(crc/define-properties!
|
||||||
|
ViewportProxy
|
||||||
|
{:name js/Symbol.toStringTag
|
||||||
|
:get (fn [] (str "ViewportProxy"))})
|
||||||
|
|
||||||
|
(defn create-proxy
|
||||||
|
[]
|
||||||
|
(crc/add-properties!
|
||||||
|
(ViewportProxy.)
|
||||||
|
{:name "center"
|
||||||
|
:get
|
||||||
|
(fn [_]
|
||||||
|
(let [vp (dm/get-in @st/state [:workspace-local :vbox])
|
||||||
|
x (+ (:x vp) (/ (:width vp) 2))
|
||||||
|
y (+ (:y vp) (/ (:height vp) 2))]
|
||||||
|
(.freeze js/Object #js {:x x :y y})))
|
||||||
|
|
||||||
|
:set
|
||||||
|
(fn [_ value]
|
||||||
|
(let [new-x (obj/get value "x")
|
||||||
|
new-y (obj/get value "y")
|
||||||
|
vb (dm/get-in @st/state [:workspace-local :vbox])
|
||||||
|
old-x (+ (:x vb) (/ (:width vb) 2))
|
||||||
|
old-y (+ (:y vb) (/ (:height vb) 2))
|
||||||
|
delta-x (- new-x old-x)
|
||||||
|
delta-y (- new-y old-y)
|
||||||
|
to-position
|
||||||
|
{:x #(+ % delta-x)
|
||||||
|
:y #(+ % delta-y)}]
|
||||||
|
(st/emit! (dwv/update-viewport-position to-position))))}
|
||||||
|
|
||||||
|
{:name "zoom"
|
||||||
|
:get
|
||||||
|
(fn [_]
|
||||||
|
(dm/get-in @st/state [:workspace-local :zoom]))
|
||||||
|
:set
|
||||||
|
(fn [_ value]
|
||||||
|
(let [z (dm/get-in @st/state [:workspace-local :zoom])]
|
||||||
|
(st/emit! (dwz/set-zoom (/ value z)))))}
|
||||||
|
|
||||||
|
{:name "bounds"
|
||||||
|
:get
|
||||||
|
(fn [_]
|
||||||
|
(let [vport (dm/get-in @st/state [:workspace-local :vport])]
|
||||||
|
(.freeze js/Object (clj->js vport))))}))
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue