mirror of
https://github.com/idrawjs/idraw
synced 2026-05-23 01:28:31 +00:00
feat: support custom style for middleware layout selector
This commit is contained in:
parent
6cbf7673a8
commit
e2eaa25a97
13 changed files with 79 additions and 97 deletions
|
|
@ -1,3 +1,5 @@
|
|||
import type { MiddlewareLayoutSelectorStyle } from '@idraw/types';
|
||||
|
||||
export const key = 'LAYOUT_SELECT';
|
||||
// export const keyHoverElement = Symbol(`${key}_hoverElementSize`);
|
||||
export const keyLayoutActionType = Symbol(`${key}_layoutActionType`); // 'resize' | null = null;
|
||||
|
|
@ -6,7 +8,11 @@ export const keyLayoutController = Symbol(`${key}_layoutController`); // Element
|
|||
export const keyLayoutIsHover = Symbol(`${key}_layoutIsHover`); // boolean | null
|
||||
export const keyLayoutIsSelected = Symbol(`${key}_layoutIsSelected`); // boolean | null
|
||||
|
||||
// export const selectColor = '#1973ba';
|
||||
export const selectColor = '#b331c9';
|
||||
export const disableColor = '#5b5959b5';
|
||||
// const selectColor = '#b331c9';
|
||||
// const disabledColor = '#5b5959b5';
|
||||
|
||||
export const controllerSize = 10;
|
||||
|
||||
export const defaultStyle: MiddlewareLayoutSelectorStyle = {
|
||||
activeColor: '#b331c9'
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,16 +1,22 @@
|
|||
import type { BoardMiddleware, ElementSize, Point } from '@idraw/types';
|
||||
import type { BoardMiddleware, ElementSize, Point, MiddlewareLayoutSelectorConfig } from '@idraw/types';
|
||||
import { calcLayoutSizeController, isViewPointInVertexes, getViewScaleInfoFromSnapshot, isViewPointInElementSize, calcViewElementSize } from '@idraw/util';
|
||||
import type { LayoutSelectorSharedStorage, ControlType } from './types';
|
||||
import { keyLayoutActionType, keyLayoutController, keyLayoutControlType, keyLayoutIsHover, keyLayoutIsSelected, controllerSize } from './config';
|
||||
import { keyLayoutActionType, keyLayoutController, keyLayoutControlType, keyLayoutIsHover, keyLayoutIsSelected, controllerSize, defaultStyle } from './config';
|
||||
import { keyActionType as keyElementActionType, keyHoverElement, middlewareEventSelectClear } from '../selector';
|
||||
import { drawLayoutController, drawLayoutHover } from './util';
|
||||
import { eventChange } from '../../config';
|
||||
|
||||
export { keyLayoutIsSelected };
|
||||
|
||||
export const MiddlewareLayoutSelector: BoardMiddleware<LayoutSelectorSharedStorage> = (opts) => {
|
||||
export const MiddlewareLayoutSelector: BoardMiddleware<LayoutSelectorSharedStorage, any, MiddlewareLayoutSelectorConfig> = (opts, config) => {
|
||||
const { sharer, boardContent, calculator, viewer, eventHub } = opts;
|
||||
const { overlayContext } = boardContent;
|
||||
const innerConfig = {
|
||||
...defaultStyle,
|
||||
...config
|
||||
};
|
||||
const { activeColor } = innerConfig;
|
||||
const style = { activeColor };
|
||||
|
||||
let prevPoint: Point | null = null;
|
||||
let prevIsHover: boolean | null = null;
|
||||
|
|
@ -327,11 +333,11 @@ export const MiddlewareLayoutSelector: BoardMiddleware<LayoutSelectorSharedStora
|
|||
|
||||
if (layoutIsHover === true) {
|
||||
const viewSize = calcViewElementSize(size, { viewScaleInfo });
|
||||
drawLayoutHover(overlayContext, { layoutSize: viewSize });
|
||||
drawLayoutHover(overlayContext, { layoutSize: viewSize, style });
|
||||
}
|
||||
|
||||
if ((layoutActionType && ['resize'].includes(layoutActionType)) || layoutIsSelected === true) {
|
||||
drawLayoutController(overlayContext, { controller, operations: activeStore.data.layout.operations || {} });
|
||||
drawLayoutController(overlayContext, { controller, style });
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import type { ViewContext2D, LayoutSizeController, DataLayout, ViewRectVertexes, PointSize, ElementSize } from '@idraw/types';
|
||||
import { selectColor, disableColor } from './config';
|
||||
import type { ViewContext2D, LayoutSizeController, ViewRectVertexes, PointSize, ElementSize, MiddlewareLayoutSelectorStyle } from '@idraw/types';
|
||||
|
||||
function drawControllerBox(ctx: ViewContext2D, boxVertexes: ViewRectVertexes) {
|
||||
function drawControllerBox(ctx: ViewContext2D, boxVertexes: ViewRectVertexes, style: MiddlewareLayoutSelectorStyle) {
|
||||
const { activeColor } = style;
|
||||
ctx.setLineDash([]);
|
||||
ctx.fillStyle = '#FFFFFF';
|
||||
ctx.beginPath();
|
||||
|
|
@ -12,7 +12,7 @@ function drawControllerBox(ctx: ViewContext2D, boxVertexes: ViewRectVertexes) {
|
|||
ctx.closePath();
|
||||
ctx.fill();
|
||||
|
||||
ctx.strokeStyle = selectColor;
|
||||
ctx.strokeStyle = activeColor;
|
||||
ctx.lineWidth = 2;
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(boxVertexes[0].x, boxVertexes[0].y);
|
||||
|
|
@ -23,30 +23,14 @@ function drawControllerBox(ctx: ViewContext2D, boxVertexes: ViewRectVertexes) {
|
|||
ctx.stroke();
|
||||
}
|
||||
|
||||
function drawControllerCross(ctx: ViewContext2D, opts: { vertexes: ViewRectVertexes; strokeStyle: string; lineWidth: number }) {
|
||||
const { vertexes, strokeStyle, lineWidth } = opts;
|
||||
|
||||
ctx.setLineDash([]);
|
||||
ctx.strokeStyle = strokeStyle;
|
||||
ctx.lineWidth = lineWidth;
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(vertexes[0].x, vertexes[0].y);
|
||||
ctx.lineTo(vertexes[2].x, vertexes[2].y);
|
||||
ctx.closePath();
|
||||
ctx.stroke();
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(vertexes[1].x, vertexes[1].y);
|
||||
ctx.lineTo(vertexes[3].x, vertexes[3].y);
|
||||
ctx.closePath();
|
||||
ctx.stroke();
|
||||
}
|
||||
|
||||
function drawControllerLine(ctx: ViewContext2D, opts: { start: PointSize; end: PointSize; centerVertexes: ViewRectVertexes; disabled: boolean }) {
|
||||
const { start, end, centerVertexes, disabled } = opts;
|
||||
const lineWidth = disabled === true ? 1 : 2;
|
||||
const strokeStyle = disabled === true ? disableColor : selectColor;
|
||||
function drawControllerLine(
|
||||
ctx: ViewContext2D,
|
||||
opts: { start: PointSize; end: PointSize; centerVertexes: ViewRectVertexes; style: MiddlewareLayoutSelectorStyle }
|
||||
) {
|
||||
const { start, end, style } = opts;
|
||||
const { activeColor } = style;
|
||||
const lineWidth = 2;
|
||||
const strokeStyle = activeColor;
|
||||
ctx.setLineDash([]);
|
||||
ctx.strokeStyle = strokeStyle;
|
||||
ctx.lineWidth = lineWidth;
|
||||
|
|
@ -55,71 +39,41 @@ function drawControllerLine(ctx: ViewContext2D, opts: { start: PointSize; end: P
|
|||
ctx.lineTo(end.x, end.y);
|
||||
ctx.closePath();
|
||||
ctx.stroke();
|
||||
|
||||
if (disabled === true) {
|
||||
drawControllerCross(ctx, {
|
||||
vertexes: centerVertexes,
|
||||
lineWidth,
|
||||
strokeStyle
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function drawLayoutController(
|
||||
ctx: ViewContext2D,
|
||||
opts: {
|
||||
controller: LayoutSizeController;
|
||||
operations: DataLayout['operations'];
|
||||
style: MiddlewareLayoutSelectorStyle;
|
||||
}
|
||||
) {
|
||||
// TODO
|
||||
const { controller, operations } = opts;
|
||||
const { controller, style } = opts;
|
||||
const { topLeft, topRight, bottomLeft, bottomRight, topMiddle, rightMiddle, bottomMiddle, leftMiddle } = controller;
|
||||
|
||||
drawControllerLine(ctx, { start: topLeft.center, end: topRight.center, centerVertexes: topMiddle.vertexes, disabled: !!operations?.disabledTop });
|
||||
drawControllerLine(ctx, { start: topRight.center, end: bottomRight.center, centerVertexes: rightMiddle.vertexes, disabled: !!operations?.disabledRight });
|
||||
drawControllerLine(ctx, { start: bottomRight.center, end: bottomLeft.center, centerVertexes: bottomMiddle.vertexes, disabled: !!operations?.disabledBottom });
|
||||
drawControllerLine(ctx, { start: bottomLeft.center, end: topLeft.center, centerVertexes: leftMiddle.vertexes, disabled: !!operations?.disabledLeft });
|
||||
drawControllerLine(ctx, { start: topLeft.center, end: topRight.center, centerVertexes: topMiddle.vertexes, style });
|
||||
drawControllerLine(ctx, { start: topRight.center, end: bottomRight.center, centerVertexes: rightMiddle.vertexes, style });
|
||||
drawControllerLine(ctx, { start: bottomRight.center, end: bottomLeft.center, centerVertexes: bottomMiddle.vertexes, style });
|
||||
drawControllerLine(ctx, { start: bottomLeft.center, end: topLeft.center, centerVertexes: leftMiddle.vertexes, style });
|
||||
|
||||
const disabledOpts = {
|
||||
lineWidth: 1,
|
||||
strokeStyle: disableColor
|
||||
};
|
||||
if (operations?.disabledTopLeft === true) {
|
||||
drawControllerCross(ctx, { vertexes: topLeft.vertexes, ...disabledOpts });
|
||||
} else {
|
||||
drawControllerBox(ctx, topLeft.vertexes);
|
||||
}
|
||||
|
||||
if (operations?.disabledTopRight === true) {
|
||||
drawControllerCross(ctx, { vertexes: topRight.vertexes, ...disabledOpts });
|
||||
} else {
|
||||
drawControllerBox(ctx, topRight.vertexes);
|
||||
}
|
||||
|
||||
if (operations?.disabledBottomRight === true) {
|
||||
drawControllerCross(ctx, { vertexes: bottomRight.vertexes, ...disabledOpts });
|
||||
} else {
|
||||
drawControllerBox(ctx, bottomRight.vertexes);
|
||||
}
|
||||
|
||||
if (operations?.disabledBottomLeft === true) {
|
||||
drawControllerCross(ctx, { vertexes: bottomLeft.vertexes, ...disabledOpts });
|
||||
} else {
|
||||
drawControllerBox(ctx, bottomLeft.vertexes);
|
||||
}
|
||||
drawControllerBox(ctx, topLeft.vertexes, style);
|
||||
drawControllerBox(ctx, topRight.vertexes, style);
|
||||
drawControllerBox(ctx, bottomRight.vertexes, style);
|
||||
drawControllerBox(ctx, bottomLeft.vertexes, style);
|
||||
}
|
||||
|
||||
export function drawLayoutHover(
|
||||
ctx: ViewContext2D,
|
||||
opts: {
|
||||
layoutSize: ElementSize;
|
||||
style: MiddlewareLayoutSelectorStyle;
|
||||
}
|
||||
) {
|
||||
const { layoutSize } = opts;
|
||||
const { layoutSize, style } = opts;
|
||||
const { activeColor } = style;
|
||||
const { x, y, w, h } = layoutSize;
|
||||
ctx.setLineDash([]);
|
||||
ctx.strokeStyle = selectColor;
|
||||
ctx.strokeStyle = activeColor;
|
||||
ctx.lineWidth = 1;
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(x, y);
|
||||
|
|
|
|||
|
|
@ -191,7 +191,6 @@ export const MiddlewareSelector: BoardMiddleware<DeepSelectorSharedStorage, Core
|
|||
sharer.setSharedStorage(keySelectedElementController, null);
|
||||
sharer.setSharedStorage(keySelectedElementPosition, []);
|
||||
sharer.setSharedStorage(keyIsMoving, null);
|
||||
sharer.setSharedStorage(keyEnableSelectInGroup, null);
|
||||
};
|
||||
|
||||
clear();
|
||||
|
|
|
|||
|
|
@ -62,8 +62,8 @@ export function nodeToBaseDetail(node: FigmaNode<FigmaNodeType>): ElementBaseDet
|
|||
opacity
|
||||
} = node as FigmaNode<'ROUNDED_RECTANGLE'>;
|
||||
const background = figmaPaintsToColor(fillPaints, {
|
||||
w: node.size.x,
|
||||
h: node.size.y
|
||||
w: node?.size?.x || 0,
|
||||
h: node?.size?.y || 0
|
||||
});
|
||||
if (background) {
|
||||
detail.background = background;
|
||||
|
|
|
|||
|
|
@ -80,16 +80,18 @@ async function nestedNodeToGroupElement<T extends 'CANVAS' | 'FRAME' | 'SYMBOL'
|
|||
const overrideData = mergeNodeOverrideData<T>(figmaNode as any, opts);
|
||||
const node: FigmaNode = { ...figmaNode, ...overrideData } as FigmaNode;
|
||||
const elemBase = nodeToElementBase(node);
|
||||
const baseDetail = nodeToBaseDetail(node);
|
||||
|
||||
let group: Element<'group'> = {
|
||||
...elemBase,
|
||||
type: 'group',
|
||||
detail: {
|
||||
...baseDetail,
|
||||
children: [],
|
||||
overflow: 'visible'
|
||||
},
|
||||
operations: nodeToOperations(node)
|
||||
};
|
||||
// const baseDetail = nodeToBaseDetail(treeNode.node);
|
||||
if ((node as unknown as FigmaNode<'FRAME'>).type === 'FRAME') {
|
||||
// const background = figmaPaintsToHexColor(node.fillPaints);
|
||||
const background = figmaPaintsToColor(node.fillPaints, { w: elemBase.w, h: elemBase.h });
|
||||
|
|
@ -117,7 +119,7 @@ async function nestedNodeToGroupElement<T extends 'CANVAS' | 'FRAME' | 'SYMBOL'
|
|||
}
|
||||
|
||||
if (['FRAME', 'BOOLEAN_OPERATION'].includes(node.type)) {
|
||||
if (group.x === 0 || group.y === 0) {
|
||||
if (group.w === 0 || group.h === 0) {
|
||||
const size = resetGroupSize(group);
|
||||
group = {
|
||||
...size,
|
||||
|
|
|
|||
|
|
@ -62,8 +62,8 @@ export async function figmaMapToIDrawData(figmaMap: FigmaMap): Promise<Data> {
|
|||
const canvasFig: FigmaMap['canvas.fig'] = figmaMap['canvas.fig'];
|
||||
const { root } = canvasFig;
|
||||
|
||||
// // TODO
|
||||
// console.log('root =', root);
|
||||
// TODO
|
||||
console.log('root =', root);
|
||||
|
||||
if (Array.isArray(root.children)) {
|
||||
for (let i = 0; i < root.children.length; i++) {
|
||||
|
|
|
|||
|
|
@ -33,6 +33,9 @@ const opts = {
|
|||
hoverThumbBorderColor: '#FF0000EE',
|
||||
activeThumbBackground: '#FF00005E',
|
||||
activeThumbBorderColor: '#FF0000F0'
|
||||
},
|
||||
layoutSelector: {
|
||||
activeColor: '#00FF00'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -21,7 +21,8 @@ export function getDefaultStorage(): IDrawStorage {
|
|||
selector: {},
|
||||
info: {},
|
||||
ruler: {},
|
||||
scroller: {}
|
||||
scroller: {},
|
||||
layoutSelector: {}
|
||||
}
|
||||
};
|
||||
return storage;
|
||||
|
|
@ -32,11 +33,12 @@ export function parseStyles(opts: IDrawSettings) {
|
|||
selector: {},
|
||||
ruler: {},
|
||||
info: {},
|
||||
scroller: {}
|
||||
scroller: {},
|
||||
layoutSelector: {}
|
||||
};
|
||||
if (opts.styles) {
|
||||
// selector
|
||||
const { selector, info, ruler, scroller } = opts.styles;
|
||||
const { selector, info, ruler, scroller, layoutSelector } = opts.styles;
|
||||
if (istype.string(selector?.activeColor)) {
|
||||
styles.selector.activeColor = selector?.activeColor;
|
||||
}
|
||||
|
|
@ -100,6 +102,11 @@ export function parseStyles(opts: IDrawSettings) {
|
|||
if (istype.string(scroller?.activeThumbBorderColor)) {
|
||||
styles.scroller.activeThumbBorderColor = scroller?.activeThumbBorderColor;
|
||||
}
|
||||
|
||||
// layoutSelector
|
||||
if (istype.string(layoutSelector?.activeColor)) {
|
||||
styles.layoutSelector.activeColor = layoutSelector?.activeColor;
|
||||
}
|
||||
}
|
||||
return styles;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -122,7 +122,8 @@ export {
|
|||
calcElementViewRectInfo,
|
||||
calcElementOriginRectInfo,
|
||||
calcElementViewRectInfoMap,
|
||||
sortElementsViewVisiableInfoMap
|
||||
sortElementsViewVisiableInfoMap,
|
||||
flatElementList
|
||||
} from '@idraw/util';
|
||||
export { iDraw } from './idraw';
|
||||
export { eventKeys } from './event';
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ export function runMiddlewares(core: Core<IDrawEvent>, store: Store<IDrawStorage
|
|||
}
|
||||
|
||||
if (enableSelect === true) {
|
||||
core.use(MiddlewareLayoutSelector);
|
||||
core.use(MiddlewareLayoutSelector, styles?.layoutSelector);
|
||||
core.use(MiddlewareSelector, styles?.selector);
|
||||
} else if (enableSelect === false) {
|
||||
core.disuse(MiddlewareLayoutSelector);
|
||||
|
|
@ -72,7 +72,7 @@ export function changeMode(mode: IDrawMode, core: Core<IDrawEvent>, store: Store
|
|||
let enableTextEdit: boolean = false;
|
||||
let enableDrag: boolean = false;
|
||||
let enableRuler: boolean = false;
|
||||
const enableInfo: boolean = true;
|
||||
let enableInfo: boolean = false;
|
||||
|
||||
let innerMode: IDrawMode = 'select';
|
||||
store.set('mode', innerMode);
|
||||
|
|
@ -87,6 +87,7 @@ export function changeMode(mode: IDrawMode, core: Core<IDrawEvent>, store: Store
|
|||
enableScale = true;
|
||||
enableScroll = true;
|
||||
enableSelect = true;
|
||||
enableInfo = true;
|
||||
enableTextEdit = true;
|
||||
enableDrag = false;
|
||||
enableRuler = true;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import type { CoreOptions } from './core';
|
||||
import type { MiddlewareSelectorStyle, MiddlewareInfoStyle, MiddlewareRulerStyle, MiddlewareScrollerStyle } from './middleware';
|
||||
import type { MiddlewareSelectorStyle, MiddlewareInfoStyle, MiddlewareRulerStyle, MiddlewareScrollerStyle, MiddlewareLayoutSelectorStyle } from './middleware';
|
||||
|
||||
export type IDrawMode = 'select' | 'drag' | 'readOnly';
|
||||
|
||||
|
|
@ -12,6 +12,7 @@ export interface IDrawSettings {
|
|||
info?: Partial<MiddlewareInfoStyle>;
|
||||
ruler?: Partial<MiddlewareRulerStyle>;
|
||||
scroller?: Partial<MiddlewareScrollerStyle>;
|
||||
layoutSelector?: Partial<MiddlewareLayoutSelectorStyle>;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ export type MiddlewareInfoStyle = {
|
|||
textBackground: string;
|
||||
textColor: string;
|
||||
};
|
||||
|
||||
export type MiddlewareInfoConfig = MiddlewareInfoStyle & {};
|
||||
|
||||
export type MiddlewareRulerStyle = {
|
||||
|
|
@ -28,7 +27,6 @@ export type MiddlewareRulerStyle = {
|
|||
gridPrimaryColor: string;
|
||||
selectedAreaColor: string;
|
||||
};
|
||||
|
||||
export type MiddlewareRulerConfig = MiddlewareRulerStyle & {};
|
||||
|
||||
export type MiddlewareScrollerStyle = {
|
||||
|
|
@ -39,5 +37,9 @@ export type MiddlewareScrollerStyle = {
|
|||
activeThumbBackground: string;
|
||||
activeThumbBorderColor: string;
|
||||
};
|
||||
|
||||
export type MiddlewareScrollerConfig = MiddlewareScrollerStyle & {};
|
||||
|
||||
export type MiddlewareLayoutSelectorStyle = {
|
||||
activeColor: string;
|
||||
};
|
||||
export type MiddlewareLayoutSelectorConfig = MiddlewareLayoutSelectorStyle & {};
|
||||
|
|
|
|||
Loading…
Reference in a new issue