所以我一直在尝试使用Konva来绘制一些图像,文本和形状,一切都很好,直到我尝试在混合中添加旋转。我知道Konva使用原点(默认情况下是左上角,可以通过偏移量移动)来旋转图像,但我需要位置始终是左上角。
因此,我尝试计算、旋转和重新定位对象,以模仿我想要的,但这总是导致图像位置与我的初始状态不同,这是一种不需要的行为。
所以我的问题是,Konva可以从中心旋转图像,同时在旋转后保持左上角的原点位置吗?
*使用代码编辑示例:绿色框/文本被旋转,但位置完全错误。我需要从左到右的位置。
const stage = new Konva.Stage({ container: 'container', width: window.innerWidth, height: window.innerHeight const layer = new Konva.Layer(); stage.add(layer); const rotatePoint= (x, y , rad)=> { const rcos = Math.cos(rad); const rsin = Math.sin(rad); return { x: x * rcos - y * rsin, y: y * rcos + x * rsin const rotateAroundCenter = (node, rotation) => { const topLeft = { x: -node.width() / 2, y: -node.height() / 2 }; const current = rotatePoint(topLeft.x, topLeft.y, Konva.getAngle(node.rotation())); const rotated = rotatePoint(topLeft.x, topLeft.y, Konva.getAngle(rotation)); const dx = rotated.x - current.x, dy = rotated.y - current.y; node.rotation(rotation); node.x(node.x() + dx); node.y(node.y() + dy); return node; let x = 100, y = 50, width = 50, height = 50; const rotation = 90; const text = { width, height, fontSize: 15, fontFamily: 'Calibri', text: 'Simple Text', opacity: 0.5 }; const rect = { width, height, strokeWidth: 2} let pos = {x, y}; layer.add(new Konva.Circle({ ...pos, radius:5, fill: 'black' })); layer.add(new Konva.Text({ ...pos, ...text, fill: 'black' })); layer.add(new Konva.Rect({ ...pos, ...rect, stroke: 'purple' })); layer.add(new Konva.Text({ ...pos, ...text, fill: 'purple', rotation: rotation })); layer.add(new Konva.Rect({ ...pos, ...rect, stroke: 'purple', rotation: rotation })); pos = {x, y:150}; layer.add(new Konva.Circle({ ...pos, radius:5, fill: 'black' })); layer.add(rotateAroundCenter(new Konva.Text({ ...pos, ...text, fill: 'green' }), rotation)); layer.add(rotateAroundCenter(new Konva.Rect({ ...pos, ...rect, stroke: 'green' }), rotation)); layer.draw();
<!DOCTYPE html> <meta name="description" content="KonvaJS Template"> <script src="https://cdnjs.cloudflare.com/ajax/libs/konva/4.2.0/konva.min.js"></script> <meta charset="utf-8"> </head> <div id="container"></div> </body> </html>
发布于 2020-03-26 20:51:55
好的,基本上必须按照拉夫顿说的做,把形状放在一个组中(用正确的位置),然后在组内旋转和偏移形状。
const stage = new Konva.Stage({ container: 'container', width: 300, height: 700 const layer = new Konva.Layer(); stage.add(layer); const rotatePoint = ({ x, y }, rad) => { const rcos = Math.cos(rad); const rsin = Math.sin(rad); return { x: x * rcos - y * rsin, y: y * rcos + x * rsin }; // will work for shapes with top-left origin, like rectangle const rotateAroundCenter = (node, rotation) => { //current rotation origin (0, 0) relative to desired origin - center (node.width()/2, node.height()/2) const topLeft = { x: -node.width() / 2, y: -node.height() / 2 }; const current = rotatePoint(topLeft, Konva.getAngle(node.rotation())); const rotated = rotatePoint(topLeft, Konva.getAngle(rotation)); const dx = rotated.x - current.x, dy = rotated.y - current.y; const r = Math.floor(rotation / 90) % 4; switch(r){ case 1: case 3: node.x(node.x() + dx + node.height()/2); node.y(node.y() + dy + node.width()/2); break; case 2: default: node.x(node.x() + dx + node.width()/2); node.y(node.y() + dy + node.height()/2); break; node.rotation(rotation); return node; let x = 200, y = 250, width = 30, height = 75, text = "? ? ? ? ?", opacity = 0.4; drawShapes = (x, y, width, height, rotation) => { layer.add(new Konva.Text({x:0, y, fill: 'black', text: (rotation+"°").padStart(5,"_")})); layer.add(new Konva.Rect({x, y, width, height, fill: 'black', rotation})); layer.add(new Konva.Text({x, y, width, height, fill: 'white', rotation, text})); const group = new Konva.Group({ x, y,/* clip:{x:0,y:0,width:200,height:200}*/}) group.add(rotateAroundCenter(new Konva.Rect({x:-width/2,y:-height/2, width, height,fill: 'grey', opacity}), rotation)); group.add(rotateAroundCenter(new Konva.Text({x:-width/2,y:-height/2, width, height,fill: 'black', text}), rotation)); layer.add(group, new Konva.Circle({x, y, radius: 2, fill: 'black'})); drawShapes(x, 50, width, height, 0); drawShapes(x, 200, width, height, 90); drawShapes(x, 350, width, height, 180); drawShapes(x, 500, width, height, 270); layer.draw();
<!DOCTYPE html> <meta name="description" content="KonvaJS Template"> <script src="https://cdnjs.cloudflare.com/ajax/libs/konva/4.2.0/konva.min.js"></script>