我想用fabric.js沿着一条线拖动一个圆圈,所以当用户用鼠标选择圆圈并拖动它时,它只会沿着这条线移动。 这是我用1行和1个圆做的小事,它应该沿着这条线移动: MoveTheCircle
Circle正在移动,但边框错误。 (移动逻辑确实令人困惑,对不起:/,我试图对其进行有用的评论)
到目前为止,这是我的代码(要查看它的实际效果,请参阅小提琴):
var canvas = new fabric.Canvas('canvas');
fabric.Object.prototype.originX = fabric.Object.prototype.originY = 'center';
var line1 = new fabric.Line([50, 50, 100, 70], {
fill: 'red',
stroke: 'red',
strokeWidth: 2,
left: 80,
top: 50,
scaleX: 2,
scaleY: 2,
selectable: false
});
var c = new fabric.Circle({
left: 80,
top: 50,
strokeWidth: 2,
radius: 5,
fill: '#000',
stroke: '#000'
});
c.hasControls = c.hasBorders = false;
c.line1 = line1;
canvas.add(line1, c);
/**
* Calculates the dot product of two 2-Dimensional Vectors.
*/
function dot_vec(v1_x, v1_y, v2_x, v2_y){
return (v1_x*v2_x) + (v1_y*v2_y);
}
/**
* Calculates the magnitude(length) of a 2-Dimensional Vector.
*/
function magnitudeVec(v_x, v_y){
return Math.sqrt( (v_x*v_x) + (v_y*v_y) );
}
function proj_vec(pBase_x, pBase_y, pEnd_x, pEnd_y, pEnd2_x, pEnd2_y){
//=== vec from p1 to p2 ===
var v1_x = (pEnd_x - pBase_x);
var v1_y = (pEnd_y - pBase_y);
//=== vec from oldLinePoint to p2 ===
var v2_x = (pEnd2_x - pBase_x);
var v2_y = (pEnd2_y - pBase_y);
//=== proj v1 on v2 ===
var vProj = proj_vec(v1_x, v1_y, v2_x, v2_y);
//=== tar vec ===
var vTar_x = pBase_x + vProj[0];
var vTar_y = pBase_y + vProj[1];
return [vTar_x, vTar_y];
}
function proj_vec(v1_x, v1_y, v2_x, v2_y){
//=== dot product v1 v2 ===
var v1v2_dot = dot_vec(v1_x, v1_y, v2_x, v2_y);
//=== magnitude of v2 ===
var v1_mag = magnitudeVec(v1_x, v1_y);
//=== vec proj. v1 to v2 ===
var facVProj = (v1v2_dot) / (v1_mag*v1_mag);
var vProj_x = facVProj * v1_x;
var vProj_y = facVProj * v1_y;
return [vProj_x, vProj_y];
}
canvas.on('object:moving', function(e) {
var object = e.target;
var objType = object.get('type');
object.setCoords();
var mouse = canvas.getPointer(event.e);
//=== vec from line start to line end ===
var vector_linestart_lineend_x = (line1.x1 - line1.x2);
var vector_linestart_lineend_y = (line1.y1 - line1.y2);
//=== vec from mouse to line end ===
var vector_mouse_line_x = (mouse.x - line1.x2);
var vector_mouse_line_y = (mouse.y - line1.y2);
//=== vec proj. v1 to v2 ===
var vProj = proj_vec(vector_linestart_lineend_x, vector_linestart_lineend_y, vector_mouse_line_x, vector_mouse_line_y);
var vProj_x = vProj[0];
var vProj_y = vProj[1];
//=== target result ===
var vTar_x = line1.x2 + vProj_x;
var vTar_y = line1.y2 + vProj_y;
//=== clip Point between endpoints ===
var vProj_len = magnitudeVec(vProj_x, vProj_y);
var v1_len = magnitudeVec(vector_linestart_lineend_x, vector_mouse_line_y);
if (vProj_len < 0) {
vTar_x = line1.x2;
vTar_y = line1.y2;
}
if (vProj_len > v1_len) {
vTar_x = line1.x1;
vTar_y = line1.y1;
}
// console.log(vTar_x + " " + vTar_y);
object.set({'left': vTar_x});
object.set({'top': vTar_y});
});
感谢您的帮助!