如何创建跟随鼠标的圆形轨迹?

时间:2019-07-29 14:11:28

标签: javascript canvas paperjs

我正在尝试构建something like this,但我希望它不是圆圈,而不是线条。这样,我可以添加其他填充。到目前为止,我可以使用此代码将其移动到鼠标上,但仅适用于第一个圆圈。我怎样才能让他们跟随一行?

// The amount of points in the path:
var points = 30;

// The distance between the points:
var length = 10;

var path = new paper.Path({
  strokeColor: "white",
  strokeWidth: 50,
  strokeCap: "round"
});

var start = view.center / [10, 1];

// Circle
var circlePath = new Path.Circle({
  center: [80, 50],
  fillColor: "transparent",
  radius: 50
});

var thirdLayer = new Group();

for (var i = 0; i < points; i++) path.add(start + new Point(i * length, 0));

console.log(path);
// // for (var i = 0; i < points; i++) path.add(end + new Point(i * length, 0));

// // path.addSegments([[657.55, 455], [657.55, 500.5]]);

// path.closed = true;

function onMouseMove(event) {
  path.firstSegment.point = event.point;

  for (var i = 0; i < points - 1; i++) {
    var segment = path.segments[i];
    var nextSegment = segment.next;
    var vector = segment.point - nextSegment.point;
    vector.length = length;
    nextSegment.point = segment.point - vector;
  }
  // rect.subtract(nextSegment.point);
  path.smooth({ type: "continuous" });
  var rect = new paper.Path.Rectangle({
    point: [0, 0],
    size: [view.size.width],
    fillColor: "#E50069",
    strokeWidth: 1
  });
  // path.offset(10);
  var drilled = rect.subtract(path);
  secondLayer.removeChildren();
  secondLayer.addChild(drilled);
  rect.remove();

  secondLayer.addChild();
}

function onMouseDown(event) {
  console.log(event);
  path.fullySelected = true;
  path.strokeColor = "#e08285";
}

function onMouseUp(event) {
  path.fullySelected = false;
  path.strokeColor = "#fff";
  path.opacity = 1;
}

// function onFrame(event) {
//   rect.unite(path);
// }

任何对前进道路的见解将不胜感激。

1 个答案:

答案 0 :(得分:2)

根据您的参考,这里的sketch展示了可能的解决方案。

var points = 25;
var length = 35;
var path = new Path();

var start = view.center / [10, 1];
for (var i = 0; i < points; i++) {
    path.add(start + new Point(i * length, 0));
}

// Create a circle for each segment of the path.
var circles = [];
for (var i = 0; i < path.segments.length; i++) {
    var circle = new Path.Circle({
        center: path.segments[i].point,
        radius: 10,
        strokeColor: 'red'
    });
    circles.push(circle);
}

function onMouseMove(event) {
    path.firstSegment.point = event.point;
    for (var i = 0; i < points - 1; i++) {
        var segment = path.segments[i];
        var nextSegment = segment.next;
        var vector = segment.point - nextSegment.point;
        vector.length = length;
        nextSegment.point = segment.point - vector;
    }
    // Each time the path is updated, update circles position.
    updateCirclesPosition();
}

function updateCirclesPosition() {
    for (var i = 0; i < path.segments.length; i++) {
        circles[i].position = path.segments[i].point;
    }
}

编辑

根据下面的评论,这是sketch,演示如何使用相同的逻辑来产生“显示图像”效果。
这些技巧依赖于使用混合模式来构成图层,而不必使用布尔操作(我最初将其发布为here)。

// First draw an image as background.
var background = new Raster({
    source: 'http://assets.paperjs.org/images/marilyn.jpg',
    onLoad: function() {
        // Make it fill all the screen.
        this.fitBounds(view.bounds, true);
    }
});

// Draw a rectangle to hide the background.
var maskBase = new Path.Rectangle({
    rectangle: view.bounds,
    fillColor: 'white'
});

// Prepare a group to store the circles that will make the background appear.
var circles = new Group({
    blendMode: 'destination-out'
});

// Assemble both previous element in a group in order to make it display as we
// need.
var mask = new Group({
    children: [maskBase, circles],
    blendMode: 'source-over'
});

// Then prepare the path.
var points = 25;
var length = 35;
var path = new Path();
var start = view.center / [10, 1];
for (var i = 0; i < points; i++) {
    path.add(start + new Point(i * length, 0));
}

// Create a circle for each segment of the path.
for (var i = 0; i < path.segments.length; i++) {
    var circle = new Path.Circle({
        center: path.segments[i].point,
        radius: 10,
        fillColor: 'red'
    });
    circles.addChild(circle);
}

// Update the path when the mouse moves.
function onMouseMove(event) {
    path.firstSegment.point = event.point;
    for (var i = 0; i < points - 1; i++) {
        var segment = path.segments[i];
        var nextSegment = segment.next;
        var vector = segment.point - nextSegment.point;
        vector.length = length;
        nextSegment.point = segment.point - vector;
    }
    // Each time the path is updated, update circles position.
    updateCirclesPosition();
}

function updateCirclesPosition() {
    for (var i = 0; i < path.segments.length; i++) {
        circles.children[i].position = path.segments[i].point;
    }
}