我写信给你是因为我真的被困住了。我必须使用 Konva.js 创建一个箭头(我根据模型对我的进行了个性化设置:https://konvajs.github.io/docs/overview.html)。
我附上了我的 JS 文件(用于创建箭头)、CSS 和通过调用 JS 文件显示结果的 HTML 文件。
这是我的问题:当我在 HTML 文件中输入一个值(风向)时,我希望我的箭头旋转指示的 Angular (方向)。它可以是 45°、90°、135°...(所以 NE、E、SE...)。但实际上,我的箭头会旋转,但也会在屏幕上围绕左上角移动。我不知道为什么。我希望它只自转。你会怎么做?
我已经看到它可以与 offsetX 和 offsetY 一起使用,但不知道是否有更好的解决方案或如何使用它。这就是为什么我需要你的帮助。
function draw_fleche_vent(direction){
var direction = direction//new Konva.Transformer({
// rotationSnaps: [0, 45, 90, 135, 180, 225, 270, 315, 360],
// });
// var force = "";
// get
// var rotationSnaps = transformer.rotationSnaps();
// set
// transformer.rotationSnaps([0, 45, 90, 135, 180, 225, 270, 315, 360]);
var stage = new Konva.Stage({
container: 'container',
width: window.innerWidth,
height: window.innerHeight
});
var layer = new Konva.Layer();
/*
* create a triangle shape by defining a
* drawing function which draws a triangle
*/
var triangle = new Konva.Shape({
sceneFunc: function (context, shape) {
context.beginPath();
context.moveTo(225, 10);
context.lineTo(150, 190);
context.quadraticCurveTo(230, 90, 300, 190);
context.closePath();
//context.offset({context.width/2, context.height/2});
//context.position({context.width/2,context.height/2});
context.fillStrokeShape(shape);
},
fill: '#FF5757',
stroke: 'black',
strokeWidth: 4
});
//var c = document.getElementById(context);
//context.rotate(direction * Math.PI / 180) ;
triangle.rotate(direction);
layer.add(triangle);
stage.add(layer);
// console.log('ca marche');
// switch (direction) {
// case 0:
// // ayer.add(triangle);.add(direction);
// // add the triangle shape to the layer
// layer.add(triangle);
// // triangle.rotate(0);
// // add the layer to the stage
// stage.add(layer);
// console.log('on est dans le switch 0');
// break;
// case 45:
// //context.rotate();
// // add the triangle shape to the layer
// layer.add(triangle);
// triangle.rotate(45);
// // add the layer to the stage
// stage.add(layer);
// console.log('on est dans le switch 45');
// break;
// case 90:
// // context.rotate(Math.PI / 180);
// // add the triangle shape to the layer
// layer.add(triangle);
// triangle.rotate(90);
// // add the layer to the stage
// stage.add(layer);
// console.log('on est dans le switch 90');
// break;
// case 135:
// // add the triangle shape to the layer
// layer.add(triangle);
// triangle.rotate(135);
// // add the layer to the stage
// stage.add(layer);
// console.log('on est dans le switch 135');
// break;
// case 180:
// // add the triangle shape to the layer
// layer.add(triangle);
// triangle.rotate(180);
// // add the layer to the stage
// stage.add(layer);
// console.log('on est dans le switch 180');
// break;
// case 225:
// // add the triangle shape to the layer
// layer.add(triangle);
// triangle.rotate(225);
// // add the layer to the stage
// stage.add(layer);
// console.log('on est dans le switch 225');
// break;
// case 270:
// // add the triangle shape to the layer
// layer.add(triangle);
// triangle.rotate(270);
// // add the layer to the stage
// stage.add(layer);
// console.log('on est dans le switch 270');
// break;
// case 315:
// // add the triangle shape to the layer
// layer.add(triangle);
// triangle.rotate(315);
// // add the layer to the stage
// stage.add(layer);
// console.log('on est dans le switch 315');
// break;
// case 360:
// // add the triangle shape to the layer
// layer.add(triangle);
// triangle.rotate(360);
// // add the layer to the stage
// stage.add(layer);
// console.log('on est dans le switch 360');
// break;
// }
// add the triangle shape to the layer
// layer.add(triangle);
// add the layer to the stage
// stage.add(layer);
}
// function rotation(){
// triangle.rotate(45);
// stage.draw();
// console.log('loaded');
// }
body {
margin: 0;
padding: 0;
overflow: hidden;
background-color: #F0F0F0;
}
<!DOCTYPE html>
<html>
<head>
<script type = "text/javascript" src="konva.min.js"></script>
<link rel="stylesheet" href="main.css" />
<script type = "text/javascript" src = "fleche.js"></script>
<meta charset="utf-8">
<title>Arrow - Try</title>
</head>
<body>
<div id="container"></div>
<script type = "text/javascript">
draw_fleche_vent(45);
</script>
</body>
</html>
最佳答案
几乎所有计算机绘图库的工作方式都是使用点和矩形。您需要考虑将箭头绘制在矩形空间中。
请注意,Konva 在图形库中有点不寻常,因为椭圆形的旋转点默认为它们的中心。在 Konva 文档网站上有关于偏移/旋转场景的很好解释 here .
在创建三 Angular 形的代码中使用
context.beginPath();
context.moveTo(225, 10);
...
起点 (beginPath) 是包含绘图的矩形的左上角。所以这是点(0,0)。
应用于形状的任何位置更改或旋转更改都使用此点作为移动中心。
如您所见,这意味着旋转似乎意外地移动了形状。
可以通过 offSet(x, y) 函数移动旋转点。顾名思义,这会将旋转点移动给定值。
您必须准确决定旋转点应该移动到哪里,这取决于您绘制的形状。一个好的起点通常是使用围绕形状的矩形的中心。
var dX = node.width()/2;
var dY = node.height()/2;
node.offset(dX, dY)
请注意,更改偏移量会移动形状,因此您需要重新定位形状
node.position({x:node.x() + dX, y: node.y() + dY})
最后 - 当发布代码示例时,尝试将它们缩减到能够说明基本问题的程度。所以下次把所有被注释的代码都去掉,除了有用的注释。
// Set up the canvas / stage
var div = $('#container');
var stage = new Konva.Stage({container: 'container', width: div.width(), height: div.height()});
var layer = new Konva.Layer({draggable: false});
stage.add(layer)
// make a triangle
var triangle = new Konva.Shape({
sceneFunc: function (context, shape) {
context.beginPath();
context.moveTo(25, 00);
context.lineTo(0, 60);
context.quadraticCurveTo(0, 60, 50, 60);
context.closePath();
context.fillStrokeShape(shape);
},
fill: 'cyan',
stroke: 'transparent'
});
// make a rect hsape to illustrate the rectangle that the triangle is drawn into
var rect = new Konva.Rect({
x: 0,
y: 0,
width: 50,
height: 60,
stroke: 'magenta',
strokeWidth: 1
});
// add both to a group
var group1 = new Konva.Group();
group1.position({x:50, y:50})
group1.add(triangle)
group1.add(rect)
// note the size of the group before we stick the cross to it as the cross affects the size.
// we will use this for offset and position later
var szWidth = group1.getClientRect().width/2;
var szHeight = group1.getClientRect().height/2;
// make a big red X to show the rotation point.
var cross = new Konva.Shape({
name: 'cross',
sceneFunc: function (context, shape) {
context.beginPath();
context.moveTo(0, 10);
context.lineTo(10, 0);
context.moveTo(0, 0);
context.lineTo(10, 10);
context.fillStrokeShape(shape);
},
strokeWidth: 2,
stroke: 'red',
x: -5,
y: -5
});
group1.add(cross)
// clone the first group to make a second, overriding the x position
var group3 = group1.clone({
x: 120,
opacity: .4 // give this one low opacity to make it faint.
});
// clone a node and override the x position - this is the one we will spin.
var group2 = group1.clone({
x: 120
});
// load all into the layer
layer.add(group1)
layer.add(group3)
layer.add(group2)
// offset group2 drawing & rotating point (call this the origin)
group2.offsetX(szWidth);
group2.offsetY(szHeight);
// IMPORTANT: but now we need to move the shape to compensate for the offset of the 'origin'.
group2.move({x: szWidth, y: szHeight})
// move the big red cross to show where the origin is now.
var cross2 = group2.findOne('.cross');
cross2.move({x: szWidth, y: szHeight});
stage.draw()
// hook the button click event to make the rotation happen
$('#rotate10').on('click', function(){
group1.rotate(10);
group2.rotate(10);
layer.draw();
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/konva/2.5.1/konva.min.js"></script>
<div>
<p>Left arrow is rotating without offset. The right arrow has both offset() and move() applied.</p>
<button id='rotate10' class='btn'>Rotate 10 degrees clockwise</button>
</div>
<div id='container' style="position: absolute; top: 40px; z-index: -1; display: inline-block; left: 0px; width: 260px; height: 140px; background-color: silver;"></div>
关于javascript - Konva.js 中的中心旋转箭头,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54358612/