Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Line drawing quality during animation #1902

Open
PawelGIX opened this issue Mar 20, 2025 · 3 comments
Open

Line drawing quality during animation #1902

PawelGIX opened this issue Mar 20, 2025 · 3 comments

Comments

@PawelGIX
Copy link

PawelGIX commented Mar 20, 2025

Is there a way to display lines on Windows & chrome without blurring during animation?

When zooming in / out the top and bottom lines are displayed thicker. when the animation stops the line renders correctly as 1px.

I gave parseInt() on the dimensions so that the lines were rendered precisely to a full pixel, but despite this the result on MS Windows is the same as in the movie. The problem does not occur on Mac OS.

preview.mp4

codesandbox:
https://codesandbox.io/p/devbox/konva-todataurl-performance-bug-forked-7jpkqh?workspaceId=ws_JhD6GMpzZ1BnQrCspH8pgU

@ayuechuan
Copy link

会不会跟屏幕的刷新率存在关系? 我尝试使用requestAnimationFrame来执行动画 有不错的回应。

@PawelGIX
Copy link
Author

会不会跟屏幕的刷新率存在关系? 我尝试使用requestAnimationFrame来执行动画 有不错的回应。

No, even after changing to requestAnimationFrame it still happens. Maybe it's a little less noticeable but I can still see the smudges

@ayuechuan
Copy link

我在以前也做过跟你视频中类似的功能,konva中的公共API Rect在执行动画会变粗,我的解决方案是自定义一个Rect,您可以尝试下我的解决方案
`

import Konva from "konva";
import { Context } from "konva/lib/Context";
import { ShapeConfig } from "konva/lib/Shape";

export interface Props extends ShapeConfig {
strokeTopColor?: string
strokeRightColor?: string
strokeBottomColor?: string
strokeLeftColor?: string
strokeTopDash?: number[]
strokeRightDash?: number[]
strokeBottomDash?: number[]
strokeLeftDash?: number[]
strokeTopWidth?: number,
strokeRightWidth?: number,
strokeBottomWidth?: number,
strokeLeftWidth?: number,
lineCap?: any
}

const getOffsetFromWidth = (width: number) => {
return width / 2 - 0.5
}

export class RectBorderNode extends Konva.Shape {
constructor(config: Props) {
const {
strokeTopColor = '#C0C4C9',
strokeRightColor = '#C0C4C9',
strokeBottomColor = '#C0C4C9',
strokeLeftColor = '#C0C4C9',
strokeTopDash = [],
strokeRightDash = [],
strokeBottomDash = [],
strokeLeftDash = [],
strokeTopWidth = 1,
strokeRightWidth = 1,
strokeBottomWidth = 1,
strokeLeftWidth = 1,
lineCap = "butt"
} = config;

const configassign = {
  name: 'RectBorderNode',
  sceneFunc(context: Context, shape: Konva.Shape) {
    const { x, y, width, height } = shape.attrs; // 使用 shape.attrs 获取属性
    /* Top border */
    if (strokeTopColor) {
      context.beginPath();
      context.moveTo(
        strokeLeftColor ? -getOffsetFromWidth(strokeLeftWidth) : 0,
        0.5
      );
      context.lineTo(
        shape.width() +
        (strokeRightColor ? getOffsetFromWidth(strokeRightWidth) + 1 : 1),
        0.5
      );
      context.setAttr("strokeStyle", strokeTopColor);
      context.setAttr("lineWidth", strokeTopWidth);
      context.setAttr("lineCap", lineCap);
      context.setLineDash(strokeTopDash);
      context.stroke();
    }
    /* Bottom border */
    if (strokeBottomColor) {
      context.beginPath();
      context.moveTo(
        strokeLeftColor ? -getOffsetFromWidth(strokeLeftWidth) : 0,
        shape.height() + 0.5
      );
      context.lineTo(
        shape.width() +
        (strokeRightColor ? getOffsetFromWidth(strokeRightWidth) + 1 : 1),
        shape.height() + 0.5
      );
      context.setAttr("lineWidth", strokeBottomWidth);
      context.setAttr("strokeStyle", strokeBottomColor);
      context.setAttr("lineCap", lineCap);
      context.setLineDash(strokeBottomDash);
      context.stroke();
    }
    /* Left border */
    if (strokeLeftColor) {
      context.beginPath();
      context.moveTo(
        0.5,
        strokeTopColor ? -getOffsetFromWidth(strokeTopWidth) : 0
      );
      context.lineTo(
        0.5,
        shape.height() +
        (strokeBottomColor
          ? getOffsetFromWidth(strokeBottomWidth) + 1
          : 1)
      );
      context.setAttr("strokeStyle", strokeLeftColor);
      context.setAttr("lineWidth", strokeLeftWidth);
      context.setAttr("lineCap", lineCap);
      context.setLineDash(strokeLeftDash);
      context.stroke();
    }
    /* Right border */
    if (strokeRightColor) {
      context.beginPath();
      context.moveTo(
        shape.width() + 0.5,
        strokeTopColor ? -getOffsetFromWidth(strokeTopWidth) : 0
      );
      context.lineTo(
        shape.width() + 0.5,
        shape.height() +
        (strokeBottomColor
          ? getOffsetFromWidth(strokeBottomWidth) + 1
          : 1)
      );
      context.setAttr("strokeStyle", strokeRightColor);
      context.setAttr("lineWidth", strokeRightWidth);
      context.setAttr("lineCap", lineCap);
      context.setLineDash(strokeRightDash);
      context.stroke();
    }
  }
}
super(Object.assign(configassign, config));

}
}

this.layer.add(new RectBorderNode({
  x: 200,
  y: 600,
  width: 200,
  height: 200
}))

`

Image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants