From 0e6fd84ab899ed8d97ca19e064aa6e725ce1aaa9 Mon Sep 17 00:00:00 2001 From: chenshenhai Date: Sun, 21 Apr 2024 21:44:17 +0800 Subject: [PATCH] feat: optimize render of circle element --- packages/renderer/src/draw/circle.ts | 43 ++++++++++++++++------------ packages/util/src/lib/view-box.ts | 7 +++-- 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/packages/renderer/src/draw/circle.ts b/packages/renderer/src/draw/circle.ts index f7e6e0a..ef5009b 100644 --- a/packages/renderer/src/draw/circle.ts +++ b/packages/renderer/src/draw/circle.ts @@ -6,7 +6,7 @@ import { drawBoxShadow, getOpacity } from './box'; export function drawCircle(ctx: ViewContext2D, elem: Element<'circle'>, opts: RendererDrawElementOptions) { const { detail, angle } = elem; const { viewScaleInfo, viewSizeInfo, parentOpacity } = opts; - const { background = '#000000', borderColor = '#000000', boxSizing, borderWidth = 0 } = detail; + const { background = '#000000', borderColor = '#000000', boxSizing, borderWidth = 0, borderDash } = detail; let bw: number = 0; if (typeof borderWidth === 'number' && borderWidth > 0) { bw = borderWidth as number; @@ -16,7 +16,7 @@ export function drawCircle(ctx: ViewContext2D, elem: Element<'circle'>, opts: Re bw = bw * viewScaleInfo.scale; // const { scale, offsetTop, offsetBottom, offsetLeft, offsetRight } = viewScaleInfo; - const { x, y, w, h } = calcViewElementSize({ x: elem.x, y: elem.y, w: elem.w, h: elem.h }, { viewScaleInfo, viewSizeInfo }) || elem; + const { x, y, w, h } = calcViewElementSize({ x: elem.x, y: elem.y, w: elem.w, h: elem.h }, { viewScaleInfo }) || elem; const viewElem = { ...elem, ...{ x, y, w, h, angle } }; rotateElement(ctx, { x, y, w, h, angle }, () => { @@ -29,10 +29,12 @@ export function drawCircle(ctx: ViewContext2D, elem: Element<'circle'>, opts: Re // 'content-box' const centerX = x + a; const centerY = y + b; + const radiusA = a; + const radiusB = b; if (bw > 0) { - if (boxSizing === 'border-box') { - a = a - bw; - b = b - bw; + if (boxSizing === 'content-box') { + a = a; + b = b; } else if (boxSizing === 'center-line') { a = a - bw / 2; b = b - bw / 2; @@ -47,18 +49,6 @@ export function drawCircle(ctx: ViewContext2D, elem: Element<'circle'>, opts: Re const opacity = getOpacity(viewElem) * parentOpacity; ctx.globalAlpha = opacity; - // draw border - if (typeof bw === 'number' && bw > 0) { - const ba = bw / 2 + a; - const bb = bw / 2 + b; - ctx.beginPath(); - ctx.strokeStyle = borderColor; - ctx.lineWidth = bw; - ctx.circle(centerX, centerY, ba, bb, 0, 0, 2 * Math.PI); - ctx.closePath(); - ctx.stroke(); - } - // draw content ctx.beginPath(); const fillStyle = createColorStyle(ctx, background, { @@ -67,10 +57,27 @@ export function drawCircle(ctx: ViewContext2D, elem: Element<'circle'>, opts: Re opacity: ctx.globalAlpha }); ctx.fillStyle = fillStyle; - ctx.circle(centerX, centerY, a, b, 0, 0, 2 * Math.PI); + ctx.circle(centerX, centerY, radiusA, radiusB, 0, 0, 2 * Math.PI); ctx.closePath(); ctx.fill(); ctx.globalAlpha = parentOpacity; + + // draw border + if (typeof bw === 'number' && bw > 0) { + const ba = bw / 2 + a; + const bb = bw / 2 + b; + ctx.beginPath(); + if (borderDash) { + const lineDash = borderDash.map((n) => n * viewScaleInfo.scale); + ctx.setLineDash(lineDash); + } + ctx.strokeStyle = borderColor; + ctx.lineWidth = bw; + ctx.circle(centerX, centerY, ba, bb, 0, 0, 2 * Math.PI); + ctx.closePath(); + ctx.stroke(); + ctx.setLineDash([]); + } } } }); diff --git a/packages/util/src/lib/view-box.ts b/packages/util/src/lib/view-box.ts index 1e2509d..f98fe73 100644 --- a/packages/util/src/lib/view-box.ts +++ b/packages/util/src/lib/view-box.ts @@ -5,7 +5,9 @@ const defaultElemConfig = getDefaultElementDetailConfig(); export function calcViewBoxSize(viewElem: Element, opts: { viewScaleInfo: ViewScaleInfo; viewSizeInfo: ViewSizeInfo }): ViewBoxSize { const { viewScaleInfo } = opts; const { scale } = viewScaleInfo; - let { borderRadius } = viewElem.detail; + let { borderRadius, borderDash } = viewElem.detail; + const hasBorderDash = Array.isArray(borderDash) && borderDash.length > 0; + const { boxSizing = defaultElemConfig.boxSizing, borderWidth } = viewElem.detail; if (Array.isArray(borderWidth)) { @@ -24,7 +26,8 @@ export function calcViewBoxSize(viewElem: Element, opts: { viewScaleInfo: ViewSc if (typeof borderWidth === 'number') { bw = (borderWidth || 0) * scale; } - if (boxSizing === 'border-box') { + if (boxSizing === 'border-box' && !hasBorderDash) { + // TODO x = viewElem.x + bw / 2; y = viewElem.y + bw / 2; w = viewElem.w - bw;