javascript - 获取可拖动箭头D3的角度值

时间:2017-04-28 18:30:45

标签: javascript d3.js svg

我有问题,我想获得箭头的角度值。 我是D3和SVG的新手。这是我的代码。

嗯,我想移动箭头并获得角度,但我不知道如何。希望你能帮助我们。我试图打印一些东西,但我总是得到未定义或什么都没有。



var margin = {
	top: 40,
	right: 40,
	bottom: 40,
	left: 40
}

var r = 200;
var hourR = r - 40;

var hourHandLength = 3 * r/3;
var minuteHandLength = r;

var w = d3.select('figure').node().clientWidth - margin.left - margin.right;
var h = d3.select('figure').node().clientHeight - margin.top - margin.bottom;

var drag = d3.behavior.drag()
	.on('dragstart', dragstart)
	.on('drag', drag)
	.on('dragend', dragend);

var handData = [
	{
		type:'hour',
		value:0,
		length:-hourHandLength,
	}
];

var svg = d3.select('svg')
	.attr('width', w + margin.left + margin.right)
	.attr('height', h + margin.top + margin.bottom);

var g = svg.append('g')
	.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');

var face = g.append('g')
	.attr('transform', 'translate(' + r + ',' + r + ')');

face.append('circle')
	.attr({
		class: 'outline',
		r: r,
		cx: 0,
		cy: 0,
		fill: '#a0a0a0'
	});
  
var hands = face.append('g');

hands.selectAll('line')
	.data(handData)
.enter().append('line')
	.attr({
		class: function(d) { return d.type + '-hand'; },
		x1: 0,
		y1: 0,
		x2: function(d) {
    
			return d.length * Math.cos(d.value);
		},
		y2: function(d) {
			return d.length * Math.sin(d.value);
		}
	})
	.call(drag);

face.append('circle')
	.attr({
		cx: 0,
		cy: 0,
		r: 15,
		fill: 'black',
		'stroke': '#374140',
		'stroke-width': 5
	});

function dragstart() {
}

function drag() {
	
	var rad = Math.atan2(d3.event.y, d3.event.x);
	
	d3.select(this)
		.attr({
			x2: function(d) {
				return r * Math.cos(rad);
			},
			y2: function(d) {
				return r * Math.sin(rad);
			}
		});
}

function dragend() {
}

@import url(https://fonts.googleapis.com/css?family=Nova+Mono);

* {
	box-sizing: border-box;
	margin: 0;
	padding: 0;
}

body {
	background-color: #374140;
	font-family: 'Nova Mono';
}

figure {
	height: 500px;
	width: 500px;
}

.outline {
	stroke: white;
	stroke-width: 1;
}

.hour {
	stroke: white;
	stroke-width: 4;
}

.hour-hand {
	stroke: white;
	stroke-width: 12;
	stroke-linecap: round;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

<figure>
	<svg></svg>
</figure>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:0)

我们可以根据线两端的x,y坐标计算角度。我已在您的svg行中添加id,以便稍后在drag函数中访问它。

在你的拖动功能中,我首先访问不同的位置值,然后计算theta值,然后转换为如下所示的度数:

  var angle = Math.atan2(y2Pos - y1Pos, x2Pos - x1Pos) * 180 / Math.PI + 180;

检查下面的工作代码:

var margin = {
  top: 40,
  right: 40,
  bottom: 40,
  left: 40
}

var r = 200;
var hourR = r - 40;

var hourHandLength = 3 * r / 3;
var minuteHandLength = r;

var w = d3.select('figure').node().clientWidth - margin.left - margin.right;
var h = d3.select('figure').node().clientHeight - margin.top - margin.bottom;

var drag = d3.behavior.drag()
  .on('dragstart', dragstart)
  .on('drag', drag)
  .on('dragend', dragend);

var handData = [{
  type: 'hour',
  value: 0,
  length: -hourHandLength,
}];

var svg = d3.select('svg')
  .attr('width', w + margin.left + margin.right)
  .attr('height', h + margin.top + margin.bottom);

var g = svg.append('g')
  .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');

var face = g.append('g')
  .attr('transform', 'translate(' + r + ',' + r + ')');

face.append('circle')
  .attr({
    class: 'outline',
    r: r,
    cx: 0,
    cy: 0,
    fill: '#a0a0a0'
  });

var hands = face.append('g');

hands.selectAll('line')
  .data(handData)
  .enter().append('line')
  .attr("id", "hand")
  .attr({
    class: function(d) {
      return d.type + '-hand';
    },
    x1: 0,
    y1: 0,
    x2: function(d) {

      return d.length * Math.cos(d.value);
    },
    y2: function(d) {
      return d.length * Math.sin(d.value);
    }
  })
  .call(drag);



face.append('circle')
  .attr({
    cx: 0,
    cy: 0,
    r: 15,
    fill: 'black',
    'stroke': '#374140',
    'stroke-width': 5
  });

function dragstart() {}

function drag() {

  var rad = Math.atan2(d3.event.y, d3.event.x);

  d3.select(this)
    .attr({
      x2: function(d) {
        return r * Math.cos(rad);
      },
      y2: function(d) {
        return r * Math.sin(rad);
      }
    });

  var singleLine = hands.selectAll('#hand');
  var x1Pos = singleLine.attr("x1");
  var x2Pos = singleLine.attr("x2");
  var y1Pos = singleLine.attr("y1");
  var y2Pos = singleLine.attr("y2");

  var angle = Math.atan2(y2Pos - y1Pos, x2Pos - x1Pos) * 180 / Math.PI + 180;
  console.log(angle);
}

function dragend() {}
@import url(https://fonts.googleapis.com/css?family=Nova+Mono);
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  background-color: #374140;
  font-family: 'Nova Mono';
}

figure {
  height: 500px;
  width: 500px;
}

.outline {
  stroke: white;
  stroke-width: 1;
}

.hour {
  stroke: white;
  stroke-width: 4;
}

.hour-hand {
  stroke: white;
  stroke-width: 12;
  stroke-linecap: round;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

<figure>
  <svg></svg>
</figure>