mirror of
https://github.com/penpot/penpot.git
synced 2025-04-01 09:31:26 -05:00
✨ Selection area on rules
This commit is contained in:
parent
5cac5eb26b
commit
1dee767762
10 changed files with 148 additions and 54 deletions
|
@ -18,7 +18,7 @@
|
|||
- Improve file menu by adding semantically groups [Github #1203](https://github.com/penpot/penpot/issues/1203)
|
||||
- Add update components in bulk option in context menu [Taiga #1975](https://tree.taiga.io/project/penpot/us/1975)
|
||||
- Create first E2E tests [Taiga #2608](https://tree.taiga.io/project/penpot/task/2608), [Taiga #2608](https://tree.taiga.io/project/penpot/task/2608)
|
||||
- Refactor of workspace toolbars [Taiga #2319](https://tree.taiga.io/project/penpot/us/2319)
|
||||
- Redesign of workspace toolbars [Taiga #2319](https://tree.taiga.io/project/penpot/us/2319)
|
||||
|
||||
### :bug: Bugs fixed
|
||||
### :arrow_up: Deps updates
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
ul.palette-menu .color-bullet {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
|
@ -88,7 +87,8 @@ ul.palette-menu .color-bullet {
|
|||
border-radius: 50%;
|
||||
|
||||
& .color-bullet-wrapper {
|
||||
background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAADFJREFUOE9jZGBgEAFifOANPknGUQMYhkkYEEgG+NMJKAwIAbwJbdQABnBCIgRoG4gAIF8IsXB/Rs4AAAAASUVORK5CYII=") left center;
|
||||
background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAADFJREFUOE9jZGBgEAFifOANPknGUQMYhkkYEEgG+NMJKAwIAbwJbdQABnBCIgRoG4gAIF8IsXB/Rs4AAAAASUVORK5CYII=")
|
||||
left center;
|
||||
background-color: $color-white;
|
||||
clip-path: circle(50%);
|
||||
display: flex;
|
||||
|
@ -98,7 +98,8 @@ ul.palette-menu .color-bullet {
|
|||
}
|
||||
|
||||
&.is-gradient {
|
||||
background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAADFJREFUOE9jZGBgEAFifOANPknGUQMYhkkYEEgG+NMJKAwIAbwJbdQABnBCIgRoG4gAIF8IsXB/Rs4AAAAASUVORK5CYII=") left center;
|
||||
background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAADFJREFUOE9jZGBgEAFifOANPknGUQMYhkkYEEgG+NMJKAwIAbwJbdQABnBCIgRoG4gAIF8IsXB/Rs4AAAAASUVORK5CYII=")
|
||||
left center;
|
||||
background-color: $color-white;
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
display: grid;
|
||||
grid-template-columns: auto auto 1fr auto auto;
|
||||
|
||||
|
||||
z-index: 11;
|
||||
|
||||
& .right-arrow,
|
||||
|
|
|
@ -177,7 +177,6 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.element-list.pages-list {
|
||||
|
@ -214,24 +213,23 @@ button.collapse-sidebar {
|
|||
}
|
||||
|
||||
&.collapsed {
|
||||
background: $color-black;
|
||||
background: $color-gray-60;
|
||||
left: 48px;
|
||||
top: 48px;
|
||||
width: 18px;
|
||||
height: 24px;
|
||||
width: 28px;
|
||||
height: 48px;
|
||||
padding: 0;
|
||||
border-radius: 0px 4px 4px 0px;
|
||||
border-left: 1px solid $color-gray-50;
|
||||
|
||||
& svg {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#layers.tool-window {
|
||||
overflow: auto;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.layers-tab {
|
||||
|
|
|
@ -11,13 +11,15 @@
|
|||
color: $color-white;
|
||||
}
|
||||
|
||||
& .typography-font, & .typography-data {
|
||||
& .typography-font,
|
||||
& .typography-data {
|
||||
font-size: 16px;
|
||||
color: #7B7D85;
|
||||
color: $color-gray-30;
|
||||
}
|
||||
|
||||
.no-text & {
|
||||
& .typography-font, & .typography-data {
|
||||
& .typography-font,
|
||||
& .typography-data {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,9 +21,10 @@ $height-palette-max: 80px;
|
|||
user-select: none;
|
||||
|
||||
display: grid;
|
||||
grid-template-areas: "header header header header"
|
||||
"toolbar left-sidebar viewport right-sidebar"
|
||||
"toolbar left-sidebar color-palette right-sidebar";
|
||||
grid-template-areas:
|
||||
"header header header header"
|
||||
"toolbar left-sidebar viewport right-sidebar"
|
||||
"toolbar left-sidebar color-palette right-sidebar";
|
||||
|
||||
grid-template-rows: auto 1fr auto;
|
||||
grid-template-columns: auto auto 1fr auto;
|
||||
|
@ -48,7 +49,7 @@ $height-palette-max: 80px;
|
|||
.settings-bar.settings-bar-right {
|
||||
min-width: $width-settings-bar;
|
||||
max-width: 500px;
|
||||
width: var(--width, $width-settings-bar);
|
||||
width: $width-settings-bar;
|
||||
grid-area: right-sidebar;
|
||||
}
|
||||
|
||||
|
@ -68,7 +69,6 @@ $height-palette-max: 80px;
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
.workspace-context-menu {
|
||||
background-color: $color-white;
|
||||
border-radius: $br-small;
|
||||
|
|
|
@ -69,15 +69,9 @@
|
|||
::mf/wrap [mf/memo]}
|
||||
[props]
|
||||
(let [layout (obj/get props "layout")
|
||||
{:keys [on-pointer-down on-lost-pointer-capture on-mouse-move parent-ref size]}
|
||||
(use-resize-hook :right-sidebar 255 255 500 :x true :right)
|
||||
|
||||
drawing-tool (:tool (mf/deref refs/workspace-drawing))]
|
||||
[:aside.settings-bar.settings-bar-right {:ref parent-ref
|
||||
:style #js {"--width" (str size "px")}}
|
||||
[:div.resize-area {:on-pointer-down on-pointer-down
|
||||
:on-lost-pointer-capture on-lost-pointer-capture
|
||||
:on-mouse-move on-mouse-move}]
|
||||
|
||||
[:aside.settings-bar.settings-bar-right
|
||||
[:div.settings-bar-inside
|
||||
(cond
|
||||
(= drawing-tool :comments)
|
||||
|
|
|
@ -52,7 +52,6 @@
|
|||
[{:keys [local selected-ids current-file-id file-typographies shared-libs]}]
|
||||
|
||||
(let [state (mf/use-state {:show-menu false})
|
||||
|
||||
selected (mf/use-state :file)
|
||||
|
||||
file-id
|
||||
|
@ -116,18 +115,7 @@
|
|||
{:on-click #(reset! selected :file)}
|
||||
(when (= selected :file) i/tick)
|
||||
[:div.library-name (str (tr "workspace.libraries.colors.file-library")
|
||||
(str/format " (%s)" (count file-typographies)))]]
|
||||
|
||||
#_[:li.palette-library
|
||||
{:on-click #(st/emit! (mdc/change-palette-selected :recent))}
|
||||
(when (= selected :recent) i/tick)
|
||||
[:div.library-name (str (tr "workspace.libraries.colors.recent-colors")
|
||||
(str/format " (%s)" (count recent-colors)))]
|
||||
[:div.color-sample
|
||||
(for [[idx color] (map-indexed vector (take 7 (reverse recent-colors))) ]
|
||||
[:& cb/color-bullet {:key (str "color-" idx)
|
||||
:color color}])]]
|
||||
]]
|
||||
(str/format " (%s)" (count file-typographies)))]]]]
|
||||
|
||||
[:div.color-palette-actions
|
||||
{:on-click #(swap! state assoc :show-menu true)}
|
||||
|
@ -136,7 +124,7 @@
|
|||
[:span.left-arrow {:on-click on-left-arrow-click} i/arrow-slide]
|
||||
|
||||
[:div.color-palette-content {:ref container :on-wheel on-wheel}
|
||||
[:div.color-palette-inside {:style {:position "relative"}}
|
||||
[:div.color-palette-inside
|
||||
(for [[idx item] (map-indexed vector current-typographies)]
|
||||
[:& typography-item
|
||||
{:key idx
|
||||
|
@ -145,9 +133,7 @@
|
|||
:selected-ids selected-ids
|
||||
:typography item}])]]
|
||||
|
||||
[:span.right-arrow {:on-click on-right-arrow-click} i/arrow-slide]])
|
||||
|
||||
)
|
||||
[:span.right-arrow {:on-click on-right-arrow-click} i/arrow-slide]]))
|
||||
|
||||
(def local-data
|
||||
(l/derived #(select-keys % [:editors]) refs/workspace-local =))
|
||||
|
|
|
@ -367,7 +367,8 @@
|
|||
[:*
|
||||
[:& rules/rules
|
||||
{:zoom zoom
|
||||
:vbox vbox}]
|
||||
:vbox vbox
|
||||
:selected-shapes selected-shapes}]
|
||||
|
||||
[:& guides/viewport-guides
|
||||
{:zoom zoom
|
||||
|
|
|
@ -8,7 +8,9 @@
|
|||
(:require
|
||||
[app.common.colors :as colors]
|
||||
[app.common.data :as d]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.math :as mth]
|
||||
[app.main.ui.hooks :as hooks]
|
||||
[app.util.object :as obj]
|
||||
[rumext.alpha :as mf]))
|
||||
|
||||
|
@ -16,6 +18,11 @@
|
|||
(def rules-size 4)
|
||||
(def rules-width 1)
|
||||
|
||||
(def rule-area-size 22)
|
||||
(def rule-area-half-size (/ rule-area-size 2))
|
||||
|
||||
(def rules-background "var(--color-gray-50)")
|
||||
|
||||
;; ----------------
|
||||
;; RULES
|
||||
;; ----------------
|
||||
|
@ -59,12 +66,12 @@
|
|||
(let [x (:x vbox)
|
||||
y (:y vbox)
|
||||
width (:width vbox)
|
||||
height (/ 22 zoom)]
|
||||
height (/ rule-area-size zoom)]
|
||||
{:x x :y y :width width :height height})
|
||||
|
||||
(let [x (:x vbox)
|
||||
y (+ (:y vbox) (/ 22 zoom))
|
||||
width (/ 22 zoom)
|
||||
y (+ (:y vbox) (/ rule-area-size zoom))
|
||||
width (/ rule-area-size zoom)
|
||||
height (- (:height vbox) (/ 21 zoom))]
|
||||
{:x x :y y :width width :height height})))
|
||||
|
||||
|
@ -107,7 +114,7 @@
|
|||
|
||||
[:*
|
||||
(let [{:keys [x y width height]} (get-background-area vbox zoom axis)]
|
||||
[:rect {:x x :y y :width width :height height :style {:fill "#303236"}}])
|
||||
[:rect {:x x :y y :width width :height height :style {:fill rules-background}}])
|
||||
|
||||
[:g.rules {:clipPath (str "url(#" clip-id ")")}
|
||||
|
||||
|
@ -147,13 +154,118 @@
|
|||
:style {:stroke colors/gray-30
|
||||
:stroke-width rules-width}}]])))]]))
|
||||
|
||||
(def selection-area-color "var(--color-primary)")
|
||||
(def selection-area-opacity 0.3)
|
||||
(def over-number-size 50)
|
||||
(def over-number-opacity 0.7)
|
||||
|
||||
(mf/defc selection-area
|
||||
[{:keys [vbox zoom selection-rect]}]
|
||||
[:g.selection-area
|
||||
[:g
|
||||
[:rect {:x (:x selection-rect)
|
||||
:y (:y vbox)
|
||||
:width (:width selection-rect)
|
||||
:height (/ rule-area-size zoom)
|
||||
:style {:fill selection-area-color
|
||||
:fill-opacity selection-area-opacity}}]
|
||||
|
||||
[:rect {:x (- (:x selection-rect) (/ over-number-size zoom))
|
||||
:y (:y vbox)
|
||||
:width (/ over-number-size zoom)
|
||||
:height (/ rule-area-size zoom)
|
||||
:style {:fill rules-background
|
||||
:fill-opacity over-number-opacity}}]
|
||||
|
||||
[:text {:x (- (:x1 selection-rect) (/ 4 zoom))
|
||||
:y (+ (:y vbox) (/ 12 zoom))
|
||||
:text-anchor "end"
|
||||
:dominant-baseline "middle"
|
||||
:style {:font-size (/ 13 zoom)
|
||||
:font-family "sourcesanspro"
|
||||
:fill selection-area-color}}
|
||||
(str (mth/round (:x1 selection-rect)))]
|
||||
|
||||
[:rect {:x (:x2 selection-rect)
|
||||
:y (:y vbox)
|
||||
:width (/ over-number-size zoom)
|
||||
:height (/ rule-area-size zoom)
|
||||
:style {:fill rules-background
|
||||
:fill-opacity over-number-opacity}}]
|
||||
|
||||
[:text {:x (+ (:x2 selection-rect) (/ 4 zoom))
|
||||
:y (+ (:y vbox) (/ 12 zoom))
|
||||
:text-anchor "start"
|
||||
:dominant-baseline "middle"
|
||||
:style {:font-size (/ 13 zoom)
|
||||
:font-family "sourcesanspro"
|
||||
:fill selection-area-color}}
|
||||
(str (mth/round (:x2 selection-rect)))]]
|
||||
|
||||
(let [center-x (+ (:x vbox) (/ rule-area-half-size zoom))
|
||||
center-y (- (+ (:y selection-rect) (/ (:height selection-rect) 2)) (/ rule-area-half-size zoom))]
|
||||
|
||||
[:g {:transform (str "rotate(-90 " center-x "," center-y ")")}
|
||||
[:rect {:x (- center-x (/ (:height selection-rect) 2) (/ rule-area-half-size zoom))
|
||||
:y (- center-y (/ rule-area-half-size zoom))
|
||||
:width (:height selection-rect)
|
||||
:height (/ rule-area-size zoom)
|
||||
:style {:fill selection-area-color
|
||||
:fill-opacity selection-area-opacity}}]
|
||||
|
||||
[:rect {:x (- center-x (/ (:height selection-rect) 2) (/ rule-area-half-size zoom) (/ over-number-size zoom))
|
||||
:y (- center-y (/ rule-area-half-size zoom))
|
||||
:width (/ over-number-size zoom)
|
||||
:height (/ rule-area-size zoom)
|
||||
:style {:fill rules-background
|
||||
:fill-opacity over-number-opacity}}]
|
||||
|
||||
[:rect {:x (+ (- center-x (/ (:height selection-rect) 2) (/ rule-area-half-size zoom) ) (:height selection-rect))
|
||||
:y (- center-y (/ rule-area-half-size zoom))
|
||||
:width (/ over-number-size zoom)
|
||||
:height (/ rule-area-size zoom)
|
||||
:style {:fill rules-background
|
||||
:fill-opacity over-number-opacity}}]
|
||||
|
||||
[:text {:x (- center-x (/ (:height selection-rect) 2) (/ 15 zoom))
|
||||
:y center-y
|
||||
:text-anchor "end"
|
||||
:dominant-baseline "middle"
|
||||
:style {:font-size (/ 13 zoom)
|
||||
:font-family "sourcesanspro"
|
||||
:fill selection-area-color}}
|
||||
(str (mth/round (:y2 selection-rect)))]
|
||||
|
||||
[:text {:x (+ center-x (/ (:height selection-rect) 2) )
|
||||
:y center-y
|
||||
:text-anchor "start"
|
||||
:dominant-baseline "middle"
|
||||
:style {:font-size (/ 13 zoom)
|
||||
:font-family "sourcesanspro"
|
||||
:fill selection-area-color}}
|
||||
(str (mth/round (:y1 selection-rect)))]])])
|
||||
|
||||
(mf/defc rules
|
||||
{::mf/wrap-props false
|
||||
::mf/wrap [mf/memo]}
|
||||
::mf/wrap [#(mf/memo' % (mf/check-props ["zoom" "vbox" "selected-shapes"]))]}
|
||||
[props]
|
||||
(let [zoom (obj/get props "zoom")
|
||||
vbox (obj/get props "vbox")]
|
||||
(let [zoom (obj/get props "zoom")
|
||||
vbox (obj/get props "vbox")
|
||||
selected-shapes (-> (obj/get props "selected-shapes")
|
||||
(hooks/use-equal-memo))
|
||||
|
||||
selection-rect
|
||||
(mf/use-memo
|
||||
(mf/deps selected-shapes)
|
||||
#(when (d/not-empty? selected-shapes)
|
||||
(gsh/selection-rect selected-shapes)))]
|
||||
|
||||
(when (some? vbox)
|
||||
[:g.rules {:pointer-events "none"}
|
||||
[:& rules-axis {:zoom zoom :vbox vbox :axis :x}]
|
||||
[:& rules-axis {:zoom zoom :vbox vbox :axis :y}]])))
|
||||
[:& rules-axis {:zoom zoom :vbox vbox :axis :y}]
|
||||
|
||||
(when (some? selection-rect)
|
||||
[:& selection-area {:zoom zoom
|
||||
:vbox vbox
|
||||
:selection-rect selection-rect}])])))
|
||||
|
|
Loading…
Add table
Reference in a new issue