如何在KonvaJS矩形变换时视觉上保持圆角半径不变?
解决KonvaJS矩形变换时圆角视觉拉伸问题
当使用KonvaJS的Transformer工具缩放矩形时,默认会修改矩形的scaleX/scaleY属性,导致圆角被拉伸变形,无法保持视觉上的一致大小。以下是可行的解决方案:
核心思路
避免通过缩放节点(scaleX/scaleY)实现尺寸变化,转而直接修改矩形的width和height属性,同时保持节点缩放比例为1。这样圆角半径会基于实际尺寸渲染,不会被拉伸。
修改后的完整代码
<!DOCTYPE html> <html> <head> <script src="https://unpkg.com/konva@9.3.16/konva.min.js"></script> <meta charset="utf-8" /> <title>Konva Fixed Radius Transform Demo</title> <style> body { margin: 0; padding: 0; overflow: hidden; background-color: #f0f0f0; } </style> </head> <body> <div id="container"></div> <script> var width = window.innerWidth; var height = window.innerHeight; var stage = new Konva.Stage({ container: 'container', width: width, height: height, }); var layer = new Konva.Layer(); stage.add(layer); var rect = new Konva.Rect({ x: 160, y: 60, width: 100, height: 90, fill: 'red', name: 'rect', stroke: 'black', cornerRadius: 8, strokeScaleEnabled: false, draggable: true, }); layer.add(rect); // 保存矩形原始尺寸 const originalWidth = rect.width(); const originalHeight = rect.height(); var MAX_WIDTH = 600; var tr = new Konva.Transformer({ boundBoxFunc: function (oldBoundBox, newBoundBox) { if (Math.abs(newBoundBox.width) > MAX_WIDTH) { return oldBoundBox; } return newBoundBox; }, }); layer.add(tr); tr.nodes([rect]); // 监听Transformer变换事件,调整矩形尺寸而非缩放 tr.on('transform', () => { const scaleX = rect.scaleX(); const scaleY = rect.scaleY(); // 计算新的宽高(基于原始尺寸和当前缩放比例) const newWidth = originalWidth * scaleX; const newHeight = originalHeight * scaleY; // 更新矩形尺寸 rect.width(newWidth); rect.height(newHeight); // 重置缩放比例为1,避免圆角被拉伸 rect.scaleX(1); rect.scaleY(1); // 更新Transformer以适配新的尺寸 tr.nodes([rect]); layer.draw(); }); </script> </body> </html>
为什么之前的方法无效?
之前尝试通过transform事件调整cornerRadius的方式,仅在等比缩放时有效。当矩形非等比缩放(宽高缩放比例不同)时,单一的圆角半径无法同时适配两个方向的缩放,导致圆角变成椭圆,视觉上仍不一致。而直接修改尺寸的方式,让圆角始终基于矩形的实际宽高渲染,从根源避免了拉伸问题。
内容的提问来源于stack exchange,提问作者papryk
相关产品推荐
相关产品推荐

