Paper.js pathData 动画 onFrame 和 onMouseDrag

Paper.js pathData animation onFrame and onMouseDrag

我使用 pathData 方法 [demo ]. I want the line animate a small wave effect in onFrame function. Also, the line would be rubberband effect when it onMouseDrag function and it will return back to the original shape when onMouseUp function. I'm a newbie in 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;
      }
    }
 }

Live demo^^

任何paperJs专家请帮助我实现它。帮助将不胜感激,提前致谢。

首先是波浪效果的问题。您只是沿 Y 轴进行变换。这可能是您想要的,但我假设不是。

一般情况下,沿着直线的normal vector进行变换,效果会好很多。法线将是垂直于线方向的方向。所以,当你变换时,波看起来就像是沿着线本身传播的。

在二维中计算法线很容易,因为您只需要在单个平面上反映当前方向。

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;

您可以在 my fork of your fiddle 中查看。

另一个关键方面是,您不想转换原始数据。这就是我创建另一个副本的原因:

var linePathCached = new Path(dataLine);
var linePath = new Path(dataLine);

您将始终需要原始数据的副本,以便您可以操作副本并在下一帧中使用旧数据进行新转换。

现在,第二,你的橡皮筋效果。

您已经非常接近当前代码了。但是,同样,您正在转换原始数据,这没有帮助。

为了达到这种效果,我建议您创建原始数据的第二个副本,从而使您拥有 3 个数据集:

  1. 您的原始线条路径,用作所有转换的基础。
  2. 鼠标拖动操作的线条路径
  3. 您正在渲染的线条路径。

在您的 onMouseDrag 处理程序中,您将转换集合 2。

在您的 onFrame 处理程序中,您将应用您在第 2 组中已有的正弦波变换并生成第 3 组。此外,您将在它们的当前位置和它们在第 1 组中的原始位置之间插入所有段.

您可以应用非常常见的 elasticOut equation, or look into other spring 相关实现。