Skip to content

Commit 9ee0c72

Browse files
committed
feat: add displayAroundControls, controlPadding #837
1 parent af20f7e commit 9ee0c72

File tree

9 files changed

+180
-100
lines changed

9 files changed

+180
-100
lines changed

.editorconfig

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ end_of_line = lf
77
indent_style = space
88
indent_size = 4
99
insert_final_newline = true
10-
max_line_length = 80
10+
max_line_length = 120
1111
trim_trailing_whitespace = true
1212

1313
[{package.json,.travis.yml}]

packages/react-moveable/src/MoveableManager.tsx

+5
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ export default class MoveableManager<T = {}>
5656
portalContainer: null,
5757
useResizeObserver: false,
5858
linePadding: 0,
59+
controlPadding: 0,
5960
ables: [],
6061
pinchThreshold: 20,
6162
dragArea: false,
@@ -134,6 +135,7 @@ export default class MoveableManager<T = {}>
134135
portalContainer,
135136
groupable,
136137
linePadding,
138+
controlPadding,
137139
} = props;
138140

139141
this._checkUpdateRootContainer();
@@ -178,6 +180,9 @@ export default class MoveableManager<T = {}>
178180
if (linePadding) {
179181
style["--moveable-line-padding"] = linePadding;
180182
}
183+
if (controlPadding) {
184+
style["--moveable-control-padding"] = controlPadding;
185+
}
181186
return (
182187
<ControlBoxElement
183188
cspNonce={cspNonce}

packages/react-moveable/src/ables/Default.ts

+2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ export default {
2929
useAccuratePosition: Boolean,
3030
firstRenderState: Object,
3131
linePadding: Boolean,
32+
displayAroundControls: Boolean,
33+
controlPadding: Number,
3234
} as const,
3335
events: {
3436
onChangeTargets: "changeTargets",

packages/react-moveable/src/ables/Rotatable.tsx

+3-44
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ import {
3939
getDirectionByPos,
4040
} from "../gesto/GestoUtils";
4141
import { DirectionControlInfo, renderAroundControls, renderDirectionControlsByInfos } from "../renderDirections";
42-
import { DIRECTIONS, DIRECTION_REGION_TO_DIRECTION } from "../consts";
42+
import { DIRECTION_REGION_TO_DIRECTION } from "../consts";
4343
import Resizable from "./Resizable";
4444
import Draggable from "./Draggable";
4545

@@ -212,7 +212,7 @@ export function dragControlCondition(moveable: MoveableManagerInterface<Rotatabl
212212
const target = e.inputEvent.target as HTMLElement;
213213
if (
214214
hasClass(target, prefix("rotation-control"))
215-
|| hasClass(target, prefix("around-control"))
215+
|| (moveable.props.rotateAroundControls && hasClass(target, prefix("around-control")))
216216
|| (hasClass(target, prefix("control")) && hasClass(target, prefix("rotatable")))
217217
) {
218218
return true;
@@ -230,33 +230,6 @@ export function dragControlCondition(moveable: MoveableManagerInterface<Rotatabl
230230
return false;
231231
}
232232

233-
const directionCSS = DIRECTIONS.map(dir => {
234-
let top = "";
235-
let left = "";
236-
let originX = "center";
237-
let originY = "center";
238-
239-
if (dir.indexOf("n") > -1) {
240-
top = "top: -20px;";
241-
originY = "bottom";
242-
}
243-
if (dir.indexOf("s") > -1) {
244-
top = "top: 0px;";
245-
originY = "top";
246-
}
247-
if (dir.indexOf("w") > -1) {
248-
left = "left: -20px;";
249-
originX = "right";
250-
}
251-
if (dir.indexOf("e") > -1) {
252-
left = "left: 0px;";
253-
originX = "left";
254-
}
255-
return `.around-control[data-direction*="${dir}"] {
256-
${left}${top}
257-
transform-origin: ${originX} ${originY};
258-
}`;
259-
}).join("\n");
260233
const css = `.rotation {
261234
position: absolute;
262235
height: 40px;
@@ -283,23 +256,9 @@ const css = `.rotation {
283256
:global .view-rotation-dragging, .rotatable.direction.control {
284257
cursor: alias;
285258
}
286-
.around-control {
287-
position: absolute;
288-
will-change: transform;
289-
width: 20px;
290-
height: 20px;
291-
left: -10px;
292-
top: -10px;
293-
box-sizing: border-box;
294-
background: transparent;
295-
z-index: 8;
296-
cursor: alias;
297-
transform-origin: center center;
298-
}
299259
.rotatable.direction.control.move {
300260
cursor: move;
301261
}
302-
${directionCSS}
303262
`;
304263
export default {
305264
name: "rotatable",
@@ -563,7 +522,7 @@ export default {
563522
if (datas.isControl && datas.resolveAble) {
564523
const resolveAble = datas.resolveAble;
565524

566-
if (resolveAble === "resizable") {
525+
if (resolveAble === "resizable") {
567526
resizeStart = Resizable.dragControlStart(moveable, {
568527
...(new CustomGesto("resizable").dragStart([0, 0], e)),
569528
parentPosition: datas.controlPosition,

packages/react-moveable/src/consts.ts

+49-4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@ import getAgent from "@egjs/agent";
22
import { IObject } from "@daybrush/utils";
33
import { MoveableInterface } from "./types";
44

5+
6+
export const DIRECTIONS4 = ["n", "w", "s", "e"];
7+
export const DIRECTIONS = ["n", "w", "s", "e", "nw", "ne", "sw", "se"];
8+
9+
510
function getSVGCursor(scale: number, degree: number) {
611
return `data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="${32 * scale}px" height="${32 * scale}px" viewBox="0 0 32 32" ><path d="M 16,5 L 12,10 L 14.5,10 L 14.5,22 L 12,22 L 16,27 L 20,22 L 17.5,22 L 17.5,10 L 20, 10 L 16,5 Z" stroke-linejoin="round" stroke-width="1.2" fill="black" stroke="white" style="transform:rotate(${degree}deg);transform-origin: 16px 16px"></path></svg>`;
712
}
@@ -42,6 +47,36 @@ export const IS_SAFARI_ABOVE15
4247
|| parseInt(agent.browser.version, 10) >= 15;
4348

4449
export const PREFIX = "moveable-";
50+
51+
52+
const directionCSS = DIRECTIONS.map(dir => {
53+
let top = "";
54+
let left = "";
55+
let originX = "center";
56+
let originY = "center";
57+
58+
if (dir.indexOf("n") > -1) {
59+
top = "top: -20px;";
60+
originY = "bottom";
61+
}
62+
if (dir.indexOf("s") > -1) {
63+
top = "top: 0px;";
64+
originY = "top";
65+
}
66+
if (dir.indexOf("w") > -1) {
67+
left = "left: -20px;";
68+
originX = "right";
69+
}
70+
if (dir.indexOf("e") > -1) {
71+
left = "left: 0px;";
72+
originX = "left";
73+
}
74+
return `.around-control[data-direction*="${dir}"] {
75+
${left}${top}
76+
transform-origin: ${originX} ${originY};
77+
}`;
78+
}).join("\n");
79+
4580
export const MOVEABLE_CSS = `
4681
{
4782
position: absolute;
@@ -78,6 +113,20 @@ export const MOVEABLE_CSS = `
78113
border: 2px solid #fff;
79114
z-index: 10;
80115
}
116+
.around-control {
117+
position: absolute;
118+
will-change: transform;
119+
width: calc(var(--moveable-control-padding, 20) * 1px);
120+
height: calc(var(--moveable-control-padding, 20) * 1px);
121+
left: -10px;
122+
top: -10px;
123+
box-sizing: border-box;
124+
background: transparent;
125+
z-index: 8;
126+
cursor: alias;
127+
transform-origin: center center;
128+
}
129+
${directionCSS}
81130
.padding {
82131
position: absolute;
83132
top: 0px;
@@ -189,10 +238,6 @@ export const MIN_SCALE = 0.000000001;
189238
export const MAX_NUM = Math.pow(10, 10);
190239
export const MIN_NUM = -MAX_NUM;
191240

192-
193-
export const DIRECTIONS4 = ["n", "w", "s", "e"];
194-
export const DIRECTIONS = ["n", "w", "s", "e", "nw", "ne", "sw", "se"];
195-
196241
export const DIRECTION_REGION_TO_DIRECTION: Record<string, number[]> = {
197242
n: [0, -1],
198243
e: [1, 0],

packages/react-moveable/src/renderDirections.tsx

+67-48
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ export interface DirectionControlInfo {
1111
classNames: string[];
1212
dir: string;
1313
}
14+
15+
1416
export function renderDirectionControlsByInfos(
1517
moveable: MoveableManagerInterface<Partial<RenderDirections>>,
1618
ableName: string,
@@ -74,61 +76,29 @@ export function renderDirectionControls(
7476
): any[] {
7577
const {
7678
renderDirections: directions = defaultDirections,
79+
displayAroundControls,
7780
} = getProps(moveable.props, ableName as any);
7881

7982
if (!directions) {
8083
return [];
8184
}
8285
const renderDirections = directions === true ? DIRECTIONS : directions;
8386

84-
return renderDirectionControlsByInfos(
85-
moveable,
86-
ableName,
87-
renderDirections.map(dir => {
88-
return {
89-
data: {},
90-
classNames: [],
91-
dir,
92-
};
93-
}),
94-
React,
95-
);
96-
}
97-
export function renderAroundControls(
98-
moveable: MoveableManagerInterface<Partial<RenderDirections>>,
99-
React: Renderer,
100-
): any[] {
101-
const renderState = moveable.renderState;
102-
if (!renderState.renderDirectionMap) {
103-
renderState.renderDirectionMap = {};
104-
}
105-
const {
106-
renderPoses,
107-
rotation: rotationRad,
108-
direction,
109-
} = moveable.getState();
110-
111-
const renderDirectionMap = renderState.renderDirectionMap;
112-
113-
const {
114-
zoom,
115-
} = moveable.props;
116-
const sign = (direction > 0 ? 1 : -1);
117-
const degRotation = rotationRad / Math.PI * 180;
118-
119-
return getKeys(renderDirectionMap).map(dir => {
120-
const indexes = DIRECTION_INDEXES[dir];
121-
122-
if (!indexes) {
123-
return null;
124-
}
125-
const directionRotation = (throttle(degRotation, 15) + sign * DIRECTION_ROTATIONS[dir] + 720) % 180;
126-
127-
return (
128-
<div className={prefix("around-control")} data-rotation={directionRotation} data-direction={dir} key={`direction-around-${dir}`}
129-
style={getControlTransform(rotationRad, zoom!, ...indexes.map(index => renderPoses[index]))}></div>
130-
);
131-
});
87+
return [
88+
...(displayAroundControls ? renderAroundControls(moveable, React, ableName, renderDirections) : []),
89+
...renderDirectionControlsByInfos(
90+
moveable,
91+
ableName,
92+
renderDirections.map(dir => {
93+
return {
94+
data: {},
95+
classNames: [],
96+
dir,
97+
};
98+
}),
99+
React,
100+
),
101+
];
132102
}
133103

134104
export function renderLine(
@@ -168,6 +138,7 @@ export function renderEdgeLines(
168138
return renderLine(React, direction, poses[index1], poses[index2], zoom, `${ableName}Edge${i}`, ableName);
169139
}).filter(Boolean);
170140
}
141+
171142
export function getRenderDirections(ableName: string) {
172143
return (
173144
moveable: MoveableManagerInterface<Partial<RenderDirections>>,
@@ -190,17 +161,65 @@ export function getRenderDirections(ableName: string) {
190161
return renderAllDirections(moveable, ableName, React);
191162
};
192163
}
164+
193165
export function renderAllDirections(
194166
moveable: MoveableManagerInterface<Partial<RenderDirections>>,
195167
ableName: string,
196168
React: Renderer,
197169
) {
198170
return renderDirectionControls(moveable, DIRECTIONS, ableName, React);
199171
}
172+
200173
export function renderDiagonalDirections(
201174
moveable: MoveableManagerInterface<Partial<RenderDirections>>,
202175
ableName: string,
203176
React: Renderer,
204177
): any[] {
205178
return renderDirectionControls(moveable, ["nw", "ne", "sw", "se"], ableName, React);
206179
}
180+
181+
export function renderAroundControls(
182+
moveable: MoveableManagerInterface<Partial<RenderDirections>>,
183+
React: Renderer,
184+
ableName?: string,
185+
renderDirections?: string[],
186+
): any[] {
187+
const renderState = moveable.renderState;
188+
if (!renderState.renderDirectionMap) {
189+
renderState.renderDirectionMap = {};
190+
}
191+
const {
192+
renderPoses,
193+
rotation: rotationRad,
194+
direction,
195+
} = moveable.getState();
196+
197+
const renderDirectionMap = renderState.renderDirectionMap;
198+
199+
const {
200+
zoom,
201+
} = moveable.props;
202+
const sign = (direction > 0 ? 1 : -1);
203+
const degRotation = rotationRad / Math.PI * 180;
204+
205+
return (renderDirections || getKeys(renderDirectionMap)).map(dir => {
206+
const indexes = DIRECTION_INDEXES[dir];
207+
208+
if (!indexes) {
209+
return null;
210+
}
211+
const directionRotation = (throttle(degRotation, 15) + sign * DIRECTION_ROTATIONS[dir] + 720) % 180;
212+
213+
const classNames: string[] = ["around-control"];
214+
215+
if (ableName) {
216+
classNames.push("direction", ableName);
217+
}
218+
return (
219+
<div
220+
className={prefix(...classNames)}
221+
data-rotation={directionRotation} data-direction={dir} key={`direction-around-${dir}`}
222+
style={getControlTransform(rotationRad, zoom!, ...indexes.map(index => renderPoses[index]))}></div>
223+
);
224+
});
225+
}

0 commit comments

Comments
 (0)