Javascript Paper.js中动态生成的可移动向量形状
我正在尝试在Paper.js中渲染箭头类型的形状。我已经能够创建渲染箭头尖端的线段,但无法创建任何进一步的点来完成箭头的轮廓。出于我自己的测试目的,它目前只有3行,但是我需要创建一个可以填充的形状,等等,所以我需要能够勾勒出箭头的轮廓,并在鼠标沿某个方向拖动时使组动态移动。我需要一支胖箭 我选择的每个点,尽管相对于当前向量的位置,在操纵箭头时似乎都会自行旋转 好几天来我一直在碰这个,运气不好 以下是我的工作内容-Javascript Paper.js中动态生成的可移动向量形状,javascript,canvas,vector-graphics,paperjs,Javascript,Canvas,Vector Graphics,Paperjs,我正在尝试在Paper.js中渲染箭头类型的形状。我已经能够创建渲染箭头尖端的线段,但无法创建任何进一步的点来完成箭头的轮廓。出于我自己的测试目的,它目前只有3行,但是我需要创建一个可以填充的形状,等等,所以我需要能够勾勒出箭头的轮廓,并在鼠标沿某个方向拖动时使组动态移动。我需要一支胖箭 我选择的每个点,尽管相对于当前向量的位置,在操纵箭头时似乎都会自行旋转 好几天来我一直在碰这个,运气不好 以下是我的工作内容- var vectorStart, vector; var vectorItem
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();
}
}
这是我的代码
我不理解的是如何在生成箭头的路径上添加点,以便创建形状。一切似乎都是自行旋转的,并没有按照我需要的方式运行
任何帮助都会很好 绘制箭头轮廓的简单方法是组合3个矩形。
Paper.js
允许您使用方法执行此操作
下面是绘图算法的概述
下面是一个演示我的解决方案的示例
//
// 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.'
});
//
//常数
//
//用户定义
var STROKE_WIDTH=40;
变压头长度=300;
变量样式={
fillColor:'橙色',
strokeColor:'黑色',
冲程宽度:5
};
//计算
变量宽度=笔划宽度*2;
var对角线=数学sqrt(数学功率(行程宽度*2,2)*2);
//
//方法
//
/**
*在两点之间绘制箭头。
*为简单起见,首先在原点水平绘制箭头
*然后根据起点/终点移动和旋转它。
*它由3个长方形组成,这些长方形合并成一个形状。
*@param{Point}start
*@param{Point}end
*/
功能图箭头(开始、结束)
{
//计算点之间的距离
var距离=开始。getDistance(结束);
//确保它不低于对角线
if(距离<对角线)
{
距离=对角线;
}
//画矩形
var directionRectangle=新路径.矩形(新点(0,-笔划宽度),新点(距离-对角线,笔划宽度));
var topRectangle=新路径矩形(新点(0,-笔划宽度),新点(笔划长度,笔划宽度));
//将顶部矩形向右移动
translate(directionRectangle.bounds.rightCenter-topRectangle.bounds.rightCenter+[WIDTH,0]);
//通过克隆顶部矩形来制作底部矩形
var bottomRectangle=topRectangle.clone();
//偏移顶部和底部矩形
topRectangle.position-=[0,笔划宽度];
bottomRectangle.position+=[0,笔划宽度];
//然后旋转形成箭头
旋转(45,topRectangle.bounds.bottomRight-[WIDTH,0]);
bottomRectangle.rotate(-45,bottomRectangle.bounds.topRight-[WIDTH,0]);
//将3个矩形连接到一条路径中
var arrow=方向矩形.unite(顶部矩形).unite(底部矩形);
//移动并旋转此路径以适合开始/结束位置
translate(开始-方向矩形.边界.左中心);
箭头。旋转((结束-开始)。角度,开始);
//应用自定义样式
arrow.style=样式;
//拆除施工项目
directionRectangle.remove();
topRectangle.remove();
bettomRectangle.remove();
}
函数onMouseDrag(事件)
{
//透明帆布
project.clear();
//根据鼠标位置绘制箭头
drawArrow(event.downPoint,event.point);
}
//
//初始化
//
//显示说明
新点文本({
视点:view.center,
理由:'中心',
内容:“用鼠标拖放绘制箭头。”
});
以下是一些创建箭头的代码。使用鼠标下点初始化对象,并在鼠标拖动到的点处绘制带有尖端的箭头
function Arrow (mouseDownPoint) {
this.start = mouseDownPoint;
this.headLength = 20;
this.tailLength = 9;
this.headAngle = 35;
this.tailAngle = 110
}
Arrow.prototype.draw = function (point) {
var end = point;
var arrowVec = this.start.subtract(end);
// parameterize {headLength: 20, tailLength: 6, headAngle: 35, tailAngle: 110}
// construct the arrow
var arrowHead = arrowVec.normalize(this.headLength);
var arrowTail = arrowHead.normalize(this.tailLength);
var p3 = end; // arrow point
var p2 = end.add(arrowHead.rotate(-this.headAngle)); // leading arrow edge angle
var p4 = end.add(arrowHead.rotate(this.headAngle)); // ditto, other side
var p1 = p2.add(arrowTail.rotate(this.tailAngle)); // trailing arrow edge angle
var p5 = p4.add(arrowTail.rotate(-this.tailAngle)); // ditto
// specify all but the last segment, closed does that
this.path = new paper.Path(this.start, p1, p2, p3, p4, p5);
this.path.closed = true;
this.path.strokeWidth = 1
this.path.strokColor = 'black'
this.path.fillColor = 'black'
return this.path
}
我喜欢锥形尾翼,但你可以通过调整构造器的长度来摆脱它
这里有一个关于鼠标操作的例子