如何解决Reactjs-如何在画布上缩放自由绘图?
我正在构建一个React组件,该组件用图像渲染画布,并允许用户在图像上涂抹。 涂鸦点存储在组件的状态中。
问题是缩放画布时,涂鸦位置无法适应新尺寸。
尝试1:在componentDidUpdate
中,我重新计算了新职位:
新位置x坐标=(new_width / old_width)* original_x
对于新的y坐标也是如此。
此解决方案的问题是除法不精确,放大和缩小几次(除法非常慢)时,累积的误差会很明显:
放大到48%之后,我希望线条会变短并保留其斜率,而会在中间断开。
尝试2:在componentDidUpdate
中:使用this.canvas!.toDataURL('image/jpg')
设置图像src
这也行不通。
我不确定是否可以在此处使用比例尺,因为im会更改组件的高度和宽度。
代码:
componentDidUpdate(prevProps: Props) {
if (this.canvasImage.src !== this.props.imageSrc) {
this.canvasImage.src = this.props.imageSrc
}
this._adjustPaintedPixels(prevProps.width,prevProps.height)
}
componentDidMount() {
this.props.registerClearAllCB(
() => this.setState({ pixelsToPaint: [] }))
document.addEventListener("mouseup",this._handleMouseUp);
this.canvas = document.getElementById('canvas') as HTMLCanvasElement
this.canvasImage.onload = this._onImageLoad
}
_adjustPaintedPixels(prevWidth: number,prevHeight: number) {
const { width,height } = this.props // update dims after the zoom
if (width === prevWidth) {
return
}
const { pixelsToPaint } = this.state
const adjusted = pixelsToPaint.map((pt: Point) => {
const ratio_x = width / prevWidth
const ratio_y = height / prevHeight
const new_x = ratio_x * pt.x
const new_y = ratio_y * pt.y
return { x: new_x,y: new_y }
})
this.setState({ pixelsToPaint: adjusted })
}
_onImageLoad = () => {
if (this.context == null || this.canvas == null
|| this.canvas?.width == 0 || this.canvas?.height == 0) {
return
}
const { width,height } = this.canvas!
this.context!.drawImage(this.canvasImage,width,height)
this._paintPixels() // iterates over the coords to paint and uses putImageData to change the pixels values
}
render() {
const { width,height } = this.props
return (
<div
onMouseDown={this._handleMouseDown}
onMouseMove={this._handleMouseMove}>
<canvas
id="canvas"
ref={(c) => this.context = c?.getContext("2d")}
width={width}
height={height}
>
This browser does not support canvas..
</canvas>
</div>
)
}
是否有更简单/直接的方法来做到这一点?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。