diff --git a/common/changes/@visactor/vrender-core/feat-keepStrokeScale_2024-11-13-08-47.json b/common/changes/@visactor/vrender-core/feat-keepStrokeScale_2024-11-13-08-47.json new file mode 100644 index 000000000..e11c1d85c --- /dev/null +++ b/common/changes/@visactor/vrender-core/feat-keepStrokeScale_2024-11-13-08-47.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@visactor/vrender-core", + "comment": "feat: support keepStrokeScale", + "type": "none" + } + ], + "packageName": "@visactor/vrender-core" +} \ No newline at end of file diff --git a/packages/vrender-core/src/graphic/config.ts b/packages/vrender-core/src/graphic/config.ts index a20752e31..d42fee6e8 100644 --- a/packages/vrender-core/src/graphic/config.ts +++ b/packages/vrender-core/src/graphic/config.ts @@ -188,6 +188,7 @@ export const DefaultAttribute: Required = { globalCompositeOperation: '', overflow: 'hidden', shadowPickMode: 'graphic', + keepStrokeScale: false, ...DefaultDebugAttribute, ...DefaultStyle, ...DefaultTransform diff --git a/packages/vrender-core/src/interface/context.ts b/packages/vrender-core/src/interface/context.ts index 116f70beb..ce427759b 100644 --- a/packages/vrender-core/src/interface/context.ts +++ b/packages/vrender-core/src/interface/context.ts @@ -34,6 +34,7 @@ export interface IStrokeStyleParams { lineJoin?: CanvasLineJoin; miterLimit?: number; opacity?: number; + keepStrokeScale?: boolean; } export interface ITextStyleParams { font?: string; diff --git a/packages/vrender-core/src/interface/graphic.ts b/packages/vrender-core/src/interface/graphic.ts index 63279cd60..8651851e1 100644 --- a/packages/vrender-core/src/interface/graphic.ts +++ b/packages/vrender-core/src/interface/graphic.ts @@ -322,6 +322,9 @@ export type IGraphicAttribute = IDebugType & overflow: 'scroll' | 'hidden' | 'scroll-x' | 'scroll-y'; // 绘制fill和stroke的顺序,为0表示fill先绘制,1表示stroke先绘制 fillStrokeOrder: number; + // @since 0.20.15 + // 保持stroke的scale,默认为false,为true的话stroke显示的宽度会随着scale变化 + keepStrokeScale: boolean; }; export interface IGraphicJson = Partial> { diff --git a/packages/vrender-core/src/render/contributions/render/contributions/arc-contribution-render.ts b/packages/vrender-core/src/render/contributions/render/contributions/arc-contribution-render.ts index a3ac18173..2f1f5c4ad 100644 --- a/packages/vrender-core/src/render/contributions/render/contributions/arc-contribution-render.ts +++ b/packages/vrender-core/src/render/contributions/render/contributions/arc-contribution-render.ts @@ -56,7 +56,8 @@ export class DefaultArcRenderContribution implements IArcRenderContribution { x: originX = arcAttribute.x, y: originY = arcAttribute.y, scaleX = arcAttribute.scaleX, - scaleY = arcAttribute.scaleY + scaleY = arcAttribute.scaleY, + keepStrokeScale = arcAttribute.keepStrokeScale } = arc.attribute; let { innerRadius = arcAttribute.innerRadius, outerRadius = arcAttribute.outerRadius } = arc.attribute; outerRadius += outerPadding; @@ -66,7 +67,7 @@ export class DefaultArcRenderContribution implements IArcRenderContribution { const doStroke = !!(borderStyle && borderStyle.stroke); const { distance = arcAttribute[key].distance } = borderStyle; - const d = getScaledStroke(context, distance as number, context.dpr); + const d = keepStrokeScale ? (distance as number) : getScaledStroke(context, distance as number, context.dpr); const deltaAngle = (distance as number) / outerRadius; const sign = key === 'outerBorder' ? 1 : -1; arc.setAttributes({ diff --git a/packages/vrender-core/src/render/contributions/render/contributions/circle-contribution-render.ts b/packages/vrender-core/src/render/contributions/render/contributions/circle-contribution-render.ts index 6e1e65e9e..2474acf67 100644 --- a/packages/vrender-core/src/render/contributions/render/contributions/circle-contribution-render.ts +++ b/packages/vrender-core/src/render/contributions/render/contributions/circle-contribution-render.ts @@ -54,14 +54,15 @@ export class DefaultCircleRenderContribution implements ICircleRenderContributio x: originX = circleAttribute.x, y: originY = circleAttribute.y, scaleX = circleAttribute.scaleX, - scaleY = circleAttribute.scaleY + scaleY = circleAttribute.scaleY, + keepStrokeScale = circleAttribute.keepStrokeScale } = circle.attribute; const renderBorder = (borderStyle: Partial, key: 'outerBorder' | 'innerBorder') => { const doStroke = !!(borderStyle && borderStyle.stroke); const { distance = circleAttribute[key].distance } = borderStyle; - const d = getScaledStroke(context, distance as number, context.dpr); + const d = keepStrokeScale ? (distance as number) : getScaledStroke(context, distance as number, context.dpr); const sign = key === 'outerBorder' ? 1 : -1; context.beginPath(); context.arc(x, y, radius + sign * d, startAngle, endAngle); diff --git a/packages/vrender-core/src/render/contributions/render/contributions/rect-contribution-render.ts b/packages/vrender-core/src/render/contributions/render/contributions/rect-contribution-render.ts index fe59cc0b1..e37504add 100644 --- a/packages/vrender-core/src/render/contributions/render/contributions/rect-contribution-render.ts +++ b/packages/vrender-core/src/render/contributions/render/contributions/rect-contribution-render.ts @@ -57,7 +57,8 @@ export class DefaultRectRenderContribution implements IRectRenderContribution { scaleX = rectAttribute.scaleX, scaleY = rectAttribute.scaleY, x1, - y1 + y1, + keepStrokeScale = rectAttribute.keepStrokeScale } = rect.attribute; let { width, height } = rect.attribute; @@ -70,7 +71,7 @@ export class DefaultRectRenderContribution implements IRectRenderContribution { const sign = key === 'outerBorder' ? -1 : 1; const { distance = rectAttribute[key].distance } = borderStyle; - const d = getScaledStroke(context, distance as number, context.dpr); + const d = keepStrokeScale ? (distance as number) : getScaledStroke(context, distance as number, context.dpr); const nextX = x + sign * d; const nextY = y + sign * d; const dw = d * 2; diff --git a/packages/vrender-core/src/render/contributions/render/contributions/symbol-contribution-render.ts b/packages/vrender-core/src/render/contributions/render/contributions/symbol-contribution-render.ts index 55df388bd..1695385cb 100644 --- a/packages/vrender-core/src/render/contributions/render/contributions/symbol-contribution-render.ts +++ b/packages/vrender-core/src/render/contributions/render/contributions/symbol-contribution-render.ts @@ -59,14 +59,15 @@ export class DefaultSymbolRenderContribution implements ISymbolRenderContributio x: originX = symbolAttribute.x, y: originY = symbolAttribute.y, scaleX = symbolAttribute.scaleX, - scaleY = symbolAttribute.scaleY + scaleY = symbolAttribute.scaleY, + keepStrokeScale = symbolAttribute.keepStrokeScale } = symbol.attribute; const renderBorder = (borderStyle: Partial, key: 'outerBorder' | 'innerBorder') => { const doStroke = !!(borderStyle && borderStyle.stroke); const { distance = symbolAttribute[key].distance } = borderStyle; - const d = getScaledStroke(context, distance as number, context.dpr); + const d = keepStrokeScale ? (distance as number) : getScaledStroke(context, distance as number, context.dpr); const sign = key === 'outerBorder' ? 1 : -1; context.beginPath(); diff --git a/packages/vrender-kits/src/canvas/contributions/browser/context.ts b/packages/vrender-kits/src/canvas/contributions/browser/context.ts index 647d1d14f..3cae9aec2 100644 --- a/packages/vrender-kits/src/canvas/contributions/browser/context.ts +++ b/packages/vrender-kits/src/canvas/contributions/browser/context.ts @@ -1136,9 +1136,10 @@ export class BrowserContext2d implements IContext2d { lineJoin = defaultParams.lineJoin, lineDash = defaultParams.lineDash, lineCap = defaultParams.lineCap, - miterLimit = defaultParams.miterLimit + miterLimit = defaultParams.miterLimit, + keepStrokeScale = defaultParams.keepStrokeScale } = attribute; - _context.lineWidth = getScaledStroke(this, lineWidth, this.dpr); + _context.lineWidth = keepStrokeScale ? lineWidth : getScaledStroke(this, lineWidth, this.dpr); _context.strokeStyle = createColor(this, stroke as any, params, offsetX, offsetY); _context.lineJoin = lineJoin; lineDash && _context.setLineDash(lineDash); diff --git a/packages/vrender-kits/src/canvas/contributions/harmony/context.ts b/packages/vrender-kits/src/canvas/contributions/harmony/context.ts index eb8f55f14..f437f792f 100644 --- a/packages/vrender-kits/src/canvas/contributions/harmony/context.ts +++ b/packages/vrender-kits/src/canvas/contributions/harmony/context.ts @@ -60,10 +60,11 @@ export class HarmonyContext2d extends BrowserContext2d implements IContext2d { lineJoin = defaultParams.lineJoin, lineDash = defaultParams.lineDash, lineCap = defaultParams.lineCap, - miterLimit = defaultParams.miterLimit + miterLimit = defaultParams.miterLimit, + keepStrokeScale = defaultParams.keepStrokeScale } = attribute; _context.globalAlpha = strokeOpacity * opacity * this.baseGlobalAlpha; - _context.lineWidth = getScaledStroke(this, lineWidth, this.dpr); + _context.lineWidth = keepStrokeScale ? lineWidth : getScaledStroke(this, lineWidth, this.dpr); _context.strokeStyle = createColor(this, stroke as any, params, offsetX, offsetY); _context.lineJoin = lineJoin; // lynx环境中lineDash不能为[0, 0] diff --git a/packages/vrender-kits/src/canvas/contributions/lynx/context.ts b/packages/vrender-kits/src/canvas/contributions/lynx/context.ts index bc1019f1a..8629efcc5 100644 --- a/packages/vrender-kits/src/canvas/contributions/lynx/context.ts +++ b/packages/vrender-kits/src/canvas/contributions/lynx/context.ts @@ -53,10 +53,11 @@ export class LynxContext2d extends BrowserContext2d implements IContext2d { lineJoin = defaultParams.lineJoin, lineDash = defaultParams.lineDash, lineCap = defaultParams.lineCap, - miterLimit = defaultParams.miterLimit + miterLimit = defaultParams.miterLimit, + keepStrokeScale = defaultParams.keepStrokeScale } = attribute; _context.globalAlpha = strokeOpacity * opacity * this.baseGlobalAlpha; - _context.lineWidth = getScaledStroke(this, lineWidth, this.dpr); + _context.lineWidth = keepStrokeScale ? lineWidth : getScaledStroke(this, lineWidth, this.dpr); _context.strokeStyle = createColor(this, stroke as any, params, offsetX, offsetY); _context.lineJoin = lineJoin; // lynx环境中lineDash不能为[0, 0] diff --git a/packages/vrender-kits/src/canvas/contributions/taro/context.ts b/packages/vrender-kits/src/canvas/contributions/taro/context.ts index c0a77880f..49e419dbc 100644 --- a/packages/vrender-kits/src/canvas/contributions/taro/context.ts +++ b/packages/vrender-kits/src/canvas/contributions/taro/context.ts @@ -101,10 +101,11 @@ export class TaroContext2d extends BrowserContext2d implements IContext2d { lineJoin = defaultParams.lineJoin, lineDash = defaultParams.lineDash, lineCap = defaultParams.lineCap, - miterLimit = defaultParams.miterLimit + miterLimit = defaultParams.miterLimit, + keepStrokeScale = defaultParams.keepStrokeScale } = attribute; _context.setGlobalAlpha(strokeOpacity * opacity); - _context.setLineWidth(getScaledStroke(this, lineWidth, this.dpr)); + _context.setLineWidth(keepStrokeScale ? lineWidth : getScaledStroke(this, lineWidth, this.dpr)); _context.setStrokeStyle(createColor(this, stroke as any, params, offsetX, offsetY)); _context.setLineJoin(lineJoin); lineDash && _context.setLineDash(lineDash); diff --git a/packages/vrender-kits/src/picker/contributions/canvas-picker/symbol-picker.ts b/packages/vrender-kits/src/picker/contributions/canvas-picker/symbol-picker.ts index b48ad34cf..1d5403621 100644 --- a/packages/vrender-kits/src/picker/contributions/canvas-picker/symbol-picker.ts +++ b/packages/vrender-kits/src/picker/contributions/canvas-picker/symbol-picker.ts @@ -107,7 +107,10 @@ export class DefaultCanvasSymbolPicker extends Base3dPicker implements } const lineWidth = symbolAttribute.lineWidth || themeAttribute.lineWidth; const pickStrokeBuffer = symbolAttribute.pickStrokeBuffer || themeAttribute.pickStrokeBuffer; - pickContext.lineWidth = getScaledStroke(pickContext, lineWidth + pickStrokeBuffer, pickContext.dpr); + const keepStrokeScale = symbolAttribute.keepStrokeScale || themeAttribute.keepStrokeScale; + pickContext.lineWidth = keepStrokeScale + ? lineWidth + pickStrokeBuffer + : getScaledStroke(pickContext, lineWidth + pickStrokeBuffer, pickContext.dpr); picked = context.isPointInStroke(pickPoint.x, pickPoint.y); return picked; } diff --git a/packages/vrender-kits/src/picker/contributions/common/base-line-picker.ts b/packages/vrender-kits/src/picker/contributions/common/base-line-picker.ts index 26d24e465..afb70cfb8 100644 --- a/packages/vrender-kits/src/picker/contributions/common/base-line-picker.ts +++ b/packages/vrender-kits/src/picker/contributions/common/base-line-picker.ts @@ -70,7 +70,10 @@ export abstract class BaseLinePicker { const lineWidth = symbolAttribute.lineWidth || themeAttribute.lineWidth; const pickStrokeBuffer = symbolAttribute.pickStrokeBuffer || themeAttribute.pickStrokeBuffer; - pickContext.lineWidth = getScaledStroke(pickContext, lineWidth + pickStrokeBuffer, pickContext.dpr); + const keepStrokeScale = symbolAttribute.keepStrokeScale || themeAttribute.keepStrokeScale; + pickContext.lineWidth = keepStrokeScale + ? lineWidth + pickStrokeBuffer + : getScaledStroke(pickContext, lineWidth + pickStrokeBuffer, pickContext.dpr); return context.isPointInStroke(pickPoint.x, pickPoint.y); }; diff --git a/packages/vrender-kits/src/picker/contributions/common/rect-picker-base.ts b/packages/vrender-kits/src/picker/contributions/common/rect-picker-base.ts index a77e19110..ca7223de8 100644 --- a/packages/vrender-kits/src/picker/contributions/common/rect-picker-base.ts +++ b/packages/vrender-kits/src/picker/contributions/common/rect-picker-base.ts @@ -93,7 +93,10 @@ export class RectPickerBase { } const lineWidth = rectAttribute.lineWidth || themeAttribute.lineWidth; const pickStrokeBuffer = rectAttribute.pickStrokeBuffer || themeAttribute.pickStrokeBuffer; - pickContext.lineWidth = getScaledStroke(pickContext, lineWidth + pickStrokeBuffer, pickContext.dpr); + const keepStrokeScale = rectAttribute.keepStrokeScale || themeAttribute.keepStrokeScale; + pickContext.lineWidth = keepStrokeScale + ? lineWidth + pickStrokeBuffer + : getScaledStroke(pickContext, lineWidth + pickStrokeBuffer, pickContext.dpr); picked = context.isPointInStroke(point.x, point.y); return picked; } diff --git a/packages/vrender/__tests__/browser/src/pages/symbol.ts b/packages/vrender/__tests__/browser/src/pages/symbol.ts index 49c133101..a73b6d226 100644 --- a/packages/vrender/__tests__/browser/src/pages/symbol.ts +++ b/packages/vrender/__tests__/browser/src/pages/symbol.ts @@ -105,7 +105,10 @@ export const page = () => { lineCap: 'round', fill: 'pink', fillStrokeOrder: 1, - size: 40 + size: 40, + scaleX: 2, + scaleY: 2, + keepStrokeScale: true }); const text = createText({ x: x,