我在写信给你,因为我真的被卡住了。我必须使用Konva.js创建一个箭头(我已经根据模型https://konvajs.github.io/docs/overview.html进行了个性化设置)。
我已经附加了我的JS文件(用于创建箭头),CSS和HTML文件,可以通过调用JS文件来显示结果。
这是我的问题:当我在HTML文件中输入一个值(风向)时,我希望箭头旋转指示的角度(风向)。可能是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>
答案 0 :(得分:1)
几乎所有计算机图形库的工作方式都是使用点和矩形。您需要考虑在矩形空间中绘制箭头。
请注意,Konva在图形库中有点不寻常,因为椭圆绘制的形状的旋转点默认为其中心。在Konva文档网站here上,对偏移/旋转方案有很好的解释。
在创建三角形的代码中,使用
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>