Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SVG find orientation(angle) of a point to the x axis on a path

I am making parallax by moving an object on a path and it is working fine with getPointAtlength() but I also need to rotate this object with the path.

I need something like getPointAtLength() but for angles that I get the angle of the point. Rapheal seems to have a method to it but it isn't friendly to svg elements that is created in html or I don't know how to deal with it. Any ideas?

var l = document.getElementById('path');
var element=$('#svg_26')
$(window).scroll(function(){
    var pathOffset=parseInt($('#l1').css('stroke-dashoffset'));
    var p = l.getPointAtLength(-1*pathOffset);
    translation = 'translate('+p.x+'px,'+p.y+'px)'
    $(element).css('transform',translation);
})
like image 555
daredevil Avatar asked Dec 05 '22 20:12

daredevil


1 Answers

Using a library for this kind of task would be overkill. Its actually quite simple to write your own function to calculate the angle. All you have to do is use pointAtLength two time with a little offset:

var p1 = path.getPointAtLength(l)
var p2 = path.getPointAtLength(l + 3)

and then calculate the angle of the resulting line and the x-axis using Math.atan2

var deg = Math.atan2(p1.y - p2.y, p1.x - p2.x) * (180 / Math.PI);

here is a little example using the above formula

var path = document.getElementById("path")
var obj = document.getElementById("obj")
var l = 0
var tl = path.getTotalLength()

function getPointAtLengthWithRotation(path, length) {
  var p1 = path.getPointAtLength(length)
  var p2 = path.getPointAtLength(length + 3)
  var deg = Math.atan2(p1.y - p2.y, p1.x - p2.x) * (180 / Math.PI);
  return {
    x: p1.x,
    y: p1.y,
    angle: deg
  }
}

setInterval(function() {
  l += 1
  if (l > tl) l = 0;
  var p = getPointAtLengthWithRotation(path, l)
  obj.setAttribute("transform", "translate(" + p.x + "," + p.y + ") rotate(" + (p.angle + 180) + ")")
}, 30)
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="200" height="200">
  <path id="path" d="M 81.713425,82.629068 C 77.692791,85.788547 73.298237,77.367896 68.194886,79.039107 63.091534,80.710434 58.027628,96.952068 53.04637,97.140958 48.065112,97.329732 50.503508,75.285207 45.397105,74.05952 40.290703,72.833834 38.487501,93.968537 33.85932,91.287114 29.23114,88.605807 32.245641,70.914733 29.647307,66.19971 27.048973,61.484686 19.604932,68.733636 17.542589,63.315055 15.480245,57.896474 32.172733,59.004979 32.053727,53.363216 31.93472,47.721442 8.0865997,39.989401 9.2246856,34.665848 10.362772,29.342295 28.830448,38.693055 31.065274,33.7132 33.300101,28.733334 22.734045,13.601966 26.210126,9.6067771 29.686208,5.6115765 41.809938,29.357138 46.524268,27.383715 c 4.71433,-1.973424 3.011846,-23.1001292 8.022646,-23.3332919 5.0108,-0.2331744 4.529056,18.3713929 9.45006,20.4259809 4.921003,2.054588 12.017373,-15.4803016 16.717604,-13.058602 4.700233,2.421699 -6.261038,14.180819 -2.913997,18.778859 3.347041,4.59804 12.339067,-3.78046 13.896719,1.543011 1.557652,5.323471 -9.713912,13.199372 -9.176986,18.679109 0.536926,5.479772 19.347976,2.957331 18.124596,8.213665 -1.223374,5.256392 -21.036293,1.236997 -24.253076,5.968111 -3.216785,4.731114 9.342224,14.869033 5.321591,18.028511 z"
  fill="none" stroke="grey" />
  <path id="obj" d="M-5 -5 L5 0L-5 5z" fill="green" />
</svg>
like image 92
Holger Will Avatar answered Dec 08 '22 09:12

Holger Will