我使用pathData
方法[演示]创建了一行。我希望线条在onFrame
函数中动画化一个小波浪效果。此外,当线条onMouseDrag
功能时,它将是橡皮筋效果,当onMouseUp
功能时,它将恢复到原始形状。我是 Paper.js 的新手,所以当我编写一些代码时,我得到的动画会丢失对象形状。检查以下代码
代码已更新
var amount = 55;
var center = view.center;
function onFrame(event) {
// Loop through the segments of the path:
for (var i = 0; i <= amount; i++) {
var path = linePath;
var segment = path.segments[i];
// A cylic value between -1 and 1
var sinus = Math.sin(event.time * 3 + i);
// Change the y position of the segment point:
segment.point.y = sinus * 1 + center.y;
}
}
function onMouseDrag(event) {
var location = linePath.getNearestLocation(event.point);
var segment = location.segment;
var point = segment.point;
if (!point.fixed && location.distance < 600 / 4) {
var y = event.point.y;
point.y += (y - point.y) / 6;
if (segment.previous && !segment.previous.fixed) {
var previous = segment.previous.point;
previous.y += (y - previous.y) / 24;
}
if (segment.next && !segment.next.fixed) {
var next = segment.next.point;
next.y += (y - next.y) / 24;
}
}
}
现场演示^^
任何论文Js专家请帮助我实现它。帮助将不胜感激,提前感谢。
首先,波浪效应的问题。您只是沿 Y 轴进行变换。这可能是你想要的,但我假设,它不是。
通常,如果沿线的法线向量变换线,效果会好得多。法线将是垂直于线方向的方向。所以,当你变换时,看起来波浪沿着线本身传播。
在 2D 中计算法线很容易,因为您只需要在单个平面上反映当前方向。
var deltaX = nextSegment.point.x - segment.point.x;
var deltaY = nextSegment.point.y - segment.point.y;
var length = Math.sqrt( deltaX * deltaX + deltaY * deltaY );
var normal = [ deltaX / length, deltaY / length ];
normal = [ normal[ 1 ], -normal[ 0 ] ];
现在我们可以使用该法线来变换线:
toManipulate.point.x = segment.point.x + normal[0] * sinus * 3;
toManipulate.point.y = segment.point.y + normal[1] * sinus * 3;
你可以在我的小提琴叉子里看看它。
另一个关键方面是,您不想转换原始数据。这就是我创建另一个副本的原因:
var linePathCached = new Path(dataLine);
var linePath = new Path(dataLine);
您将始终需要原始数据的副本,以便您可以操作副本并在下一帧中使用旧数据进行新的转换。
现在,第二,你的橡皮筋效果。
您已经非常接近当前代码。但是,同样,您正在转换原始数据,这没有帮助。
为此,我建议创建原始数据的第二个副本,将您带到 3 个数据集:
- 原始线条路径,用作所有变换的基础。
- 通过用鼠标拖动来操作的线条路径。
- 要渲染的线条路径。
在onMouseDrag
处理程序中,您将转换集合 2。
在onFrame
处理程序中,您将应用在集合 2 上已有的正弦波变换并生成集合 3。此外,您将插值所有线段的当前位置与其在集合 1 中的原始位置。
您可以应用非常常见的 elasticOut 方程,也可以研究其他与弹簧相关的实现。