Snap.svg 从点差的斜率中获取旋转
Snap.svg Getting rotation from slope in point difference
我正在制作一个动画,我需要让这架飞机沿着给定的路径行驶并且看起来像 "circling" 地球。 Here is the codePen,如您所见,相当简单。
我的问题是角度,我试图通过计算两点的斜率并将其转换为度数来了解当平面在路径中移动时我应该旋转多少。
即使我添加了一个 epsilon 来安全检查各点之间的一致差异以及所有其他安全检查,但当它接近 +-90 度时,它会改变符号,而不是传递给其他象限120度等
我可以理解这是由于
造成的
您可以在控制台中的中点看到这种情况(显示:slope, arctangent, degrees
)。
为了解决这个问题,我通过使用 newPoint.x - firstPoint.x, newPoint.y - firstPoint.y
作为参数来重复 Math.atan2()
。它以正确的值 (CodePen here) 开始。但它仍然会做一个时髦的旋转。
这是代码(我没有发布 SVG 图片,因为它很大):
JS
var snap = Snap('#Globe_1_');
// Trail 1
var trail1 = snap.path('M354.3,707.9c13.9,14.5,27.9,27.2,41.7,38c13.9,10.9,27.2,19.3,39.3,25.4 c12.6,6.1,24.8,9,35.7,10.3c10.9,1.2,21.1-1.2,30.2-5.4c17-7.8,29-24.8,35.7-48.3c7.2-23.5,9-55,5.4-91.8 c-3.7-36.8-12-77.9-24.8-120.9c-12.6-43-30.2-87.6-51.9-131.7c-21.1-44.1-45.2-85.8-70.7-122.7s-50.8-69.5-77.3-95.5 c-27.2-26-52.5-43.6-75.6-53.2c-22.9-9.7-43.6-10.3-60.4-2.5c-16.3,7.8-27.9,24.2-35.1,47.7c-7.2,23.5-9.7,53.8-6.6,88.8')
.attr({
id: 'trail1',
fill:'none',
stroke: '#C25353',
strokeMiterLimit: 10
});
var len = trail1.getTotalLength();
var plane1 = snap.path('M375.7,708.4c0.1,0.8-0.7,1.8-1.6,1.9l-10.4,0.2l-8.4,15.1l-4,0l4.1-14.6l-7.8-0.2l-2.7,3.2L342,714 l1.6-4.9l-1.7-5.4l3.1,0.1l2.5,3.6l7.8,0.2l-4.3-14.6l4,0l8.3,14.7l10.4-0.2C375.5,706.7,376,707.1,375.7,708.4z') .attr({fill: '#CDCCCC' });
var initPoint = trail1.getPointAtLength( 1 ),
lastPoint,
slope = 0,
lastLen = 0;
Snap.animate(0, len, function( value ) {
movePoint = trail1.getPointAtLength( value );
if (lastPoint && ( Math.abs(lastPoint.y - movePoint.y) > 1 || Math.abs(lastPoint.x - movePoint.x) > 1 )) {
var slope_val = (lastPoint.y - movePoint.y) / (lastPoint.x - movePoint.x),
slope_atan = Math.atan2(movePoint.x - initPoint.x, movePoint.y - initPoint.y),
slope_deg = Snap.deg(slope_atan);
slope = slope_deg;
console.log('Capturing rotation', slope_val, slope_atan, slope_deg);
lastLen = value;
}
plane1.transform( 't' + parseInt(movePoint.x - 350) + ',' + parseInt( movePoint.y - 700) + 'r' + slope);
lastPoint = movePoint;
}, 5000, mina.linear);
你能帮帮我吗,谢谢
我不确定你想要的完整效果,如果它是纯 2d 角度,Snap 已经内置了这个(从点沿线返回角度),所以不需要太努力......
element.getPointAtLength() returns一个角度alpha,所以movePoint.alpha可以用...
下面的相关行,其他计算行已删除。
plane1.transform( 't' + parseInt(movePoint.x - 350) + ',' + parseInt( movePoint.y - 700) + 'r' + (180 + movePoint.alpha));
我正在制作一个动画,我需要让这架飞机沿着给定的路径行驶并且看起来像 "circling" 地球。 Here is the codePen,如您所见,相当简单。
我的问题是角度,我试图通过计算两点的斜率并将其转换为度数来了解当平面在路径中移动时我应该旋转多少。
即使我添加了一个 epsilon 来安全检查各点之间的一致差异以及所有其他安全检查,但当它接近 +-90 度时,它会改变符号,而不是传递给其他象限120度等
我可以理解这是由于
造成的您可以在控制台中的中点看到这种情况(显示:slope, arctangent, degrees
)。
为了解决这个问题,我通过使用 newPoint.x - firstPoint.x, newPoint.y - firstPoint.y
作为参数来重复 Math.atan2()
。它以正确的值 (CodePen here) 开始。但它仍然会做一个时髦的旋转。
这是代码(我没有发布 SVG 图片,因为它很大):
JS
var snap = Snap('#Globe_1_');
// Trail 1
var trail1 = snap.path('M354.3,707.9c13.9,14.5,27.9,27.2,41.7,38c13.9,10.9,27.2,19.3,39.3,25.4 c12.6,6.1,24.8,9,35.7,10.3c10.9,1.2,21.1-1.2,30.2-5.4c17-7.8,29-24.8,35.7-48.3c7.2-23.5,9-55,5.4-91.8 c-3.7-36.8-12-77.9-24.8-120.9c-12.6-43-30.2-87.6-51.9-131.7c-21.1-44.1-45.2-85.8-70.7-122.7s-50.8-69.5-77.3-95.5 c-27.2-26-52.5-43.6-75.6-53.2c-22.9-9.7-43.6-10.3-60.4-2.5c-16.3,7.8-27.9,24.2-35.1,47.7c-7.2,23.5-9.7,53.8-6.6,88.8')
.attr({
id: 'trail1',
fill:'none',
stroke: '#C25353',
strokeMiterLimit: 10
});
var len = trail1.getTotalLength();
var plane1 = snap.path('M375.7,708.4c0.1,0.8-0.7,1.8-1.6,1.9l-10.4,0.2l-8.4,15.1l-4,0l4.1-14.6l-7.8-0.2l-2.7,3.2L342,714 l1.6-4.9l-1.7-5.4l3.1,0.1l2.5,3.6l7.8,0.2l-4.3-14.6l4,0l8.3,14.7l10.4-0.2C375.5,706.7,376,707.1,375.7,708.4z') .attr({fill: '#CDCCCC' });
var initPoint = trail1.getPointAtLength( 1 ),
lastPoint,
slope = 0,
lastLen = 0;
Snap.animate(0, len, function( value ) {
movePoint = trail1.getPointAtLength( value );
if (lastPoint && ( Math.abs(lastPoint.y - movePoint.y) > 1 || Math.abs(lastPoint.x - movePoint.x) > 1 )) {
var slope_val = (lastPoint.y - movePoint.y) / (lastPoint.x - movePoint.x),
slope_atan = Math.atan2(movePoint.x - initPoint.x, movePoint.y - initPoint.y),
slope_deg = Snap.deg(slope_atan);
slope = slope_deg;
console.log('Capturing rotation', slope_val, slope_atan, slope_deg);
lastLen = value;
}
plane1.transform( 't' + parseInt(movePoint.x - 350) + ',' + parseInt( movePoint.y - 700) + 'r' + slope);
lastPoint = movePoint;
}, 5000, mina.linear);
你能帮帮我吗,谢谢
我不确定你想要的完整效果,如果它是纯 2d 角度,Snap 已经内置了这个(从点沿线返回角度),所以不需要太努力......
element.getPointAtLength() returns一个角度alpha,所以movePoint.alpha可以用...
下面的相关行,其他计算行已删除。
plane1.transform( 't' + parseInt(movePoint.x - 350) + ',' + parseInt( movePoint.y - 700) + 'r' + (180 + movePoint.alpha));