javascript - Paper.js 中动态生成的可移动矢量形状

标签 javascript canvas vector-graphics paperjs

我正在尝试在 Paper.js 中呈现箭头形状。我已经能够创建呈现出箭头尖端的线段,但无法创建任何进一步的点来完成箭头的轮廓。出于我自己的测试目的,它目前只有 3 条线,但是我需要创建一个可以填充等的形状,所以我需要能够勾勒出箭头并在鼠标朝某个方向拖动时让组动态移动.我需要一支粗箭头!

我选择的每个点,尽管是相对于当前矢量的位置,但在操纵箭头时似乎会自行旋转。

几天来我一直在努力解决这个问题,但没有运气。

这是我正在使用的 -

var vectorStart, vector; 

var vectorItem = new Group();

onMouseDrag = function (event) {
    var arrowLength = 50;
    vectorItem.remove();
    engaged = true;
    vectorStart = view.center;
    var end = vectorStart + vector;
    vector = event.point - vectorStart;
    console.log('arrow pointer location: ' + event.point);
    var vectorArrow = vector.normalize(arrowLength);
    vectorItem = new Group([
        new Path([vectorStart, end]),
        new Path([
            end + vectorArrow.rotate(120),
            end,
            end + vectorArrow.rotate(-120),
        ]),
    ]);
    vectorItem.strokeWidth = 1;
    vectorItem.strokeColor = 'black';
    this.onMouseUp = function() {
        vectorItem.remove();
    }
}

这是 a link to a Sketch包含我的代码。

我不明白的是如何将点添加到生成箭头的路径以创建形状。一切似乎都在自行旋转,并且没有按照我需要的方式运行。

任何帮助都会很棒!

最佳答案

绘制箭头轮廓的一种简单方法是组合 3 个矩形。
Paper.js 允许您使用 Path.unite() 执行此操作方法。

这里是绘图算法的概述

enter image description here

这是一个Sketch展示我的解决方案。

//
// CONSTANTS
//

// user defined
var STROKE_WIDTH = 40;
var HEAD_LENGTH  = 300;
var STYLE        = {
    fillColor  : 'orange',
    strokeColor: 'black',
    strokeWidth: 5
};

// computed
var WIDTH    = STROKE_WIDTH * 2;
var DIAGONAL = Math.sqrt(Math.pow(STROKE_WIDTH * 2, 2) * 2);


//
// METHODS
//

/**
 * Draws an arrow between two points.
 * For simplicity sake, arrow is drawn horizontally at origin first
 * then it is moved and rotated according to start / end points.
 * It is composed of 3 rectangles which are united into a single shape.
 * @param {Point} start
 * @param {Point} end
 */
function drawArrow(start, end)
{
    // calculate distance between points
    var distance = start.getDistance(end);
    // make sure it is not lower than diagonal
    if (distance < DIAGONAL)
    {
        distance = DIAGONAL;
    }

    // draw rectangles
    var directionRectangle = new Path.Rectangle(new Point(0, -STROKE_WIDTH), new Point(distance - DIAGONAL, STROKE_WIDTH));
    var topRectangle       = new Path.Rectangle(new Point(0, -STROKE_WIDTH), new Point(HEAD_LENGTH, STROKE_WIDTH));

    // move top rectangle to the right
    topRectangle.translate(directionRectangle.bounds.rightCenter - topRectangle.bounds.rightCenter + [ WIDTH, 0 ]);

    // make bottom rectangle by cloning top one
    var bottomRectangle = topRectangle.clone();

    // offset top and bottom rectangles
    topRectangle.position -= [ 0, STROKE_WIDTH ];
    bottomRectangle.position += [ 0, STROKE_WIDTH ];

    // rotate then to form arrow head
    topRectangle.rotate(45, topRectangle.bounds.bottomRight - [ WIDTH, 0 ]);
    bottomRectangle.rotate(-45, bottomRectangle.bounds.topRight - [ WIDTH, 0 ]);

    // join the 3 rectangles into one path
    var arrow = directionRectangle.unite(topRectangle).unite(bottomRectangle);

    // move and rotate this path to fit start / end positions
    arrow.translate(start - directionRectangle.bounds.leftCenter);
    arrow.rotate((end - start).angle, start);

    // apply custom styling
    arrow.style = STYLE;

    // remove construction items
    directionRectangle.remove();
    topRectangle.remove();
    bottomRectangle.remove();
}

function onMouseDrag(event)
{
    // clear canvas
    project.clear();
    // draw arrow according to mouse position
    drawArrow(event.downPoint, event.point);
}


//
// INIT
//

// display instructions
new PointText({
    point        : view.center,
    justification: 'center',
    content      : 'Draw arrow by dragging and dropping with your mouse.'
});

关于javascript - Paper.js 中动态生成的可移动矢量形状,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51138809/

相关文章:

javascript - 对所选元素进行分组 : document. querySelectorAll

javascript - 将实时数据从联网 C 程序发送到浏览器客户端进行绘图

javascript - 使用 JS 更改值后对数据表进行排序

javascript - 使用 javascript 和 jQuery 进行色度键控

canvas - 如何让 canvas% 对象响应鼠标悬停?

cocoa - 使用 NSBezierPath 绘制不同的线宽?

javascript - Angular $scope 变量在更新时中断

javascript - 无法在 Phonegap 中的 HTML5 Canvas 上绘制图像

javascript - 有没有一种方法可以在网页上使用矢量绘图创建一个小图形?

math - 如何在大致等距的 D 维球面上绘制 N 个点?