绕点旋转-偏移功能可移动形状吗?

时间:2018-11-13 09:01:14

标签: html5-canvas konvajs

当您第一次开始使用offset()设置形状或组的旋转点时,您会感到困惑,因为组的位置也发生了变化。

这是我产生的用于包装正确数学的函数。有谁有更好的解决方案?

更长的故事:我发现将偏移量设置为非直觉时需要重新计算形状的(x,y)。恕我直言,想象旋转的过程时,大多数人会根据早期的数学课程将画布概念化。如果我想象黑板和我的数学老师正在谈论旋转三角形,那么她会指向旋转中心,并且我可以想象三角形围绕着手指旋转。我知道在Konvajs中,偏移量与绘图操作有关,并且出于更深层次的原因,它与形状的x,y pos有关系-对于我来说,考虑在旋转绘图位置时旋转是不直观的!

请注意,在以下代码段的函数中,传入的旋转点的x,y位置相对于舞台的左上方。

/*
Set the offset for rotation to the given location and re-position the shape
*/
function RotatePoint(shape, pos){  // where pos = {x: xpos, y: yPos}
var initialPos = shape.getAbsolutePosition();
var moveBy = {x: pos.x - initialPos.x, y: pos.y - initialPos.y};

// offset is relative to initial x,y of shape, so deduct x,y.
shape.offsetX(moveBy.x);
shape.offsetY(moveBy.y);

// reposition x,y because changing offset moves it.
shape.x(initialPos.x + moveBy.x);
shape.y(initialPos.y + moveBy.y);
}

而且在行动...

/*
Set the offset for rotation to the given location and re-position the shape
*/
function RotatePoint(shape, pos){  // where pos = {x: xpos, y: yPos}
var initialPos = shape.getAbsolutePosition();
var moveBy = {x: pos.x - initialPos.x, y: pos.y - initialPos.y};

// offset is relative to initial x,y of shape, so deduct x,y.
shape.offsetX(moveBy.x);
shape.offsetY(moveBy.y);

// reposition x,y because changing offset moves it.
shape.x(initialPos.x + moveBy.x);
shape.y(initialPos.y + moveBy.y);
}


// from here on was just a part-complete project I grabbed to illustrate the above function

// kpi chart is one or more circles.
var outputKpiChart = function(opts){

// Set up the canvas / stage
var stage = new Konva.Stage({container: opts.ele, width: opts.size.width, height: opts.size.height});
var layer = new Konva.Layer({draggable: false});
stage.add(layer);

var theCfg = getFormat('one');

for (var i = 0; i < theCfg.length; i = i + 1){
	var cfg = theCfg[i];
	
	var group = new Konva.Group({});

	var w = opts.size.width;
	var h = opts.size.height;
	var r = opts.size.width/4;
	var ctr = {x: opts.size.width/2, y: opts.size.height/2};
	var circle = new Konva.Circle({
		x: w * cfg.pos.x,
		y: h * cfg.pos.y,
		radius: w * cfg.r,
		stroke: '#D4B22B',
		strokeWidth: 4,
		fill: '#7D8DF9'
		});
	group.add(circle);

	var text = new Konva.Text({
		x: w * cfg.pos.x,
		y: h * cfg.pos.y,
		text: '42',
		fill: 'blue',
		fontSize: 140,
		fontFamily: 'Roboto'
		});

	text.offset({x: text.getWidth()/2, y: text.getHeight()/2});
	group.add(text);

	var text1 = new Konva.Text({
		x: w * cfg.pos.x,
		y:   (h * cfg.pos.y) - (w * cfg.r * .25),
		text: 'Meaning of Life',
		fill: 'blue',
		fontSize: 20,
		fontFamily: 'Roboto'
		});
  
  text1.x(text1.x() + (text.width() - text1.width())/2); // centre over text 1

  text1.offset({x: text.getWidth()/2, y: text.getHeight()/2});
	group.add(text1);
	
	layer.add(group)
		
	var pos = group.getClientRect();

  // set the group rotate point. Note - x,y is relative to top-left of stage !
  RotatePoint(group, {x: pos.x + pos.width/2, y: pos.y + pos.height/2});

	var c1 = new Konva.Circle({x: group.offsetX(), y:  group.offsetY(), radius: 4, fill: 'red'});
	layer.add(c1)
	
    // the tween has to be created after the node has been added to the layer
    var tween = new Konva.Tween({
        node: group,
        duration: 4,
        rotation: 360,
        easing: Konva.Easings.BackEaseOut
    });	
	tween.play();
}


stage.draw();

}

// this is a dashboard project, this func is intended to return positioning 
// metrics for complex kpi displays
var getFormat = function(formatName){

switch (formatName){
	
	case 'one': // display a single circle kpi display
		config = [{name: 'c1', r: .25, pos: {x: .5, y: .5}, size: {x: .5, y: .5}}]
		break;
	}
return config;
}

outputKpiChart({ele: '#container', size: {width: 600, height: 300} })
<script src="https://cdnjs.cloudflare.com/ajax/libs/konva/2.5.1/konva.js"></script>
<p>A function to move the rotaton point of a group.</p>
<div id='container' style="display: inline-block; width: 300px, height: 200px; background-color: silver; overflow: hidden; position: relative;"></div>

0 个答案:

没有答案