Skip to content

Commit

Permalink
Merge pull request #269 from idrawjs/dev-v0.4
Browse files Browse the repository at this point in the history
feat: optimize re-render of selector middleware
  • Loading branch information
chenshenhai authored Jan 20, 2024
2 parents 7cfa19e + 6868f01 commit dd6775d
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 33 deletions.
22 changes: 22 additions & 0 deletions packages/core/src/middleware/selector/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,28 @@ export const MiddlewareSelector: BoardMiddleware<DeepSelectorSharedStorage, Core
});
triggerCursor(target);

if (target.type === null) {
return;
}

if (
target.type === 'over-element' &&
sharer.getSharedStorage(keyActionType) === 'select' &&
target.elements.length === 1 &&
target.elements[0].uuid === getActiveElements()?.[0]?.uuid
) {
return;
}

if (
target.type === 'over-element' &&
sharer.getSharedStorage(keyActionType) === null &&
target.elements.length === 1 &&
target.elements[0].uuid === sharer.getSharedStorage(keyHoverElement)?.uuid
) {
return;
}

if (target.type === 'over-element' && target?.elements?.length === 1) {
sharer.setSharedStorage(keyHoverElement, target.elements[0]);
updateHoverElement(target.elements[0]);
Expand Down
65 changes: 64 additions & 1 deletion packages/idraw/dev/data.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Data } from '@idraw/types';
import { deepClone } from '@idraw/util';
import { deepClone, createUUID, parseSVGPath } from '@idraw/util';

// const data: Data = {
// background: '#ffffff',
Expand Down Expand Up @@ -225,6 +225,69 @@ const data: Data = {
textAlign: 'center',
verticalAlign: 'middle'
}
},
{
uuid: createUUID(),
x: 250,
y: 150,
w: 100,
h: 100,
// angle: 30,
type: 'rect',
detail: {
background: '#4caf50',
clipPath: {
commands: parseSVGPath(`
M 10,30
A 20,20 0,0,1 50,30
A 20,20 0,0,1 90,30
Q 90,60 50,90
Q 10,60 10,30 z`),
// fill: '#ff0000',
originX: 10,
originY: 10,
originH: 80,
originW: 80
// background: '#0000002A'
}
}
},
{
uuid: createUUID(),
x: 100,
y: 10,
w: 80,
h: 80,
// angle: 30,
type: 'path',
detail: {
commands: parseSVGPath(`
M 10,30
A 20,20 0,0,1 50,30
A 20,20 0,0,1 90,30
Q 90,60 50,90
Q 10,60 10,30 z`),
fill: 'red',
originX: 10,
originY: 10,
originH: 80,
originW: 80,
background: '#0000002A'

// clipPath: {
// commands: parseSVGPath(`
// M 10,30
// A 20,20 0,0,1 50,30
// A 20,20 0,0,1 90,30
// Q 90,60 50,90
// Q 10,60 10,30 z`),
// fill: '#ff0000',
// originX: 10,
// originY: 10,
// originH: 80,
// originW: 80
// }
}
}
]
};
Expand Down
1 change: 1 addition & 0 deletions packages/idraw/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export {
delay,
compose,
throttle,
debounce,
downloadImageFromCanvas,
parseFileToBase64,
pickFile,
Expand Down
5 changes: 3 additions & 2 deletions packages/renderer/src/draw/box.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export function drawBox(
});
}

// TODO
function drawClipPath(
ctx: ViewContext2D,
viewElem: Element<ElementType>,
Expand All @@ -55,8 +56,8 @@ function drawClipPath(
viewSizeInfo: ViewSizeInfo;
}
) {
const { renderContent, originElem, calcElemSize, viewScaleInfo, viewSizeInfo } = opts;
const totalScale = viewScaleInfo.scale * viewSizeInfo.devicePixelRatio;
const { renderContent, originElem, calcElemSize, viewSizeInfo } = opts;
const totalScale = viewSizeInfo.devicePixelRatio;
const { clipPath } = originElem?.detail || {};
if (clipPath && calcElemSize && clipPath.commands) {
const { x, y, w, h } = calcElemSize;
Expand Down
47 changes: 24 additions & 23 deletions packages/renderer/src/draw/circle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,34 +41,35 @@ export function drawCircle(ctx: ViewContext2D, elem: Element<'circle'>, opts: Re
}
}

const opacity = getOpacity(viewElem) * parentOpacity;
if (a >= 0 && b >= 0) {
const opacity = getOpacity(viewElem) * parentOpacity;
ctx.globalAlpha = opacity;

ctx.globalAlpha = opacity;
// draw border
if (typeof borderWidth === 'number' && borderWidth > 0) {
const ba = borderWidth / 2 + a;
const bb = borderWidth / 2 + b;
ctx.beginPath();
ctx.strokeStyle = borderColor;
ctx.lineWidth = borderWidth;
ctx.circle(centerX, centerY, ba, bb, 0, 0, 2 * Math.PI);
ctx.closePath();
ctx.stroke();
}

// draw border
if (typeof borderWidth === 'number' && borderWidth > 0) {
const ba = borderWidth / 2 + a;
const bb = borderWidth / 2 + b;
// draw content
ctx.beginPath();
ctx.strokeStyle = borderColor;
ctx.lineWidth = borderWidth;
ctx.circle(centerX, centerY, ba, bb, 0, 0, 2 * Math.PI);
const fillStyle = createColorStyle(ctx, background, {
viewElementSize: { x, y, w, h },
viewScaleInfo,
opacity: ctx.globalAlpha
});
ctx.fillStyle = fillStyle;
ctx.circle(centerX, centerY, a, b, 0, 0, 2 * Math.PI);
ctx.closePath();
ctx.stroke();
ctx.fill();
ctx.globalAlpha = parentOpacity;
}

// draw content
ctx.beginPath();
const fillStyle = createColorStyle(ctx, background, {
viewElementSize: { x, y, w, h },
viewScaleInfo,
opacity: ctx.globalAlpha
});
ctx.fillStyle = fillStyle;
ctx.circle(centerX, centerY, a, b, 0, 0, 2 * Math.PI);
ctx.closePath();
ctx.fill();
ctx.globalAlpha = parentOpacity;
}
});
});
Expand Down
6 changes: 6 additions & 0 deletions packages/renderer/src/draw/group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ export function drawElement(ctx: ViewContext2D, elem: Element<ElementType>, opts
if (elem?.operations?.invisible === true) {
return;
}
const { w, h } = elem;
const { scale } = opts.viewScaleInfo;
if ((scale < 1 && (w * scale < 1 || h * scale < 1)) || opts.parentOpacity === 0) {
return;
}

try {
switch (elem.type) {
case 'rect': {
Expand Down
2 changes: 1 addition & 1 deletion packages/util/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export { delay, compose, throttle } from './lib/time';
export { delay, compose, throttle, debounce } from './lib/time';
export { downloadImageFromCanvas, parseFileToBase64, pickFile, parseFileToText, downloadFileFromText } from './lib/file';
export { toColorHexStr, toColorHexNum, isColorStr, colorNameToHex, colorToCSS, colorToLinearGradientCSS, mergeHexColorAlpha } from './lib/color';
export { createUUID, isAssetId, createAssetId } from './lib/uuid';
Expand Down
23 changes: 17 additions & 6 deletions packages/util/src/lib/time.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
type Middleware = (ctx: any, next: Middleware) => any;
type Middleware = (ctx: any, next: Middleware) => any;

export function compose (middleware: Middleware[]): (context: any, next?: Middleware) => any {
export function compose(middleware: Middleware[]): (context: any, next?: Middleware) => any {
return function (context: any, next?: Middleware) {
// let index = -1;
return dispatch(0);

function dispatch (i: number): Promise<any> {
function dispatch(i: number): Promise<any> {
// index = i
let fn: Middleware = middleware[i];
if (i === middleware.length && next) {
Expand All @@ -21,7 +21,6 @@ export function compose (middleware: Middleware[]): (context: any, next?: Middle
};
}


export function delay(time: number): Promise<void> {
return new Promise((resolve) => {
setTimeout(() => {
Expand All @@ -32,8 +31,8 @@ export function delay(time: number): Promise<void> {

export function throttle(fn: (...args: any[]) => any, timeout: number): (...args: any[]) => any {
let timer: any = -1;
return function(...args: any[]) {
if (timer > 0) {
return function (...args: any[]) {
if (timer >= 0) {
return;
}
timer = setTimeout(() => {
Expand All @@ -43,3 +42,15 @@ export function throttle(fn: (...args: any[]) => any, timeout: number): (...args
};
}

export function debounce(fn: (...args: any[]) => any, timeout: number): (...args: any[]) => any {
let timer: any = -1;
return function (...args: any[]) {
if (timer >= 0) {
window.clearTimeout(timer);
}
timer = setTimeout(() => {
fn(...args);
timer = -1;
}, timeout);
};
}

0 comments on commit dd6775d

Please sign in to comment.