Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save Teddy-Zhu/ec4313eea56d86802cb1dd61c98ccf8b to your computer and use it in GitHub Desktop.
Save Teddy-Zhu/ec4313eea56d86802cb1dd61c98ccf8b to your computer and use it in GitHub Desktop.
;
(function (window, document) {
if (window.canvasqt == undefined)
window.canvasqt = {};
if (window.canvasqt.arrow != undefined)
return;
//旋转坐标
var scrollXoy = function (p, theta) {
return {
x: p.x * Math.cos(theta) + p.y * Math.sin(theta),
y: p.y * Math.cos(theta) - p.x * Math.sin(theta)
};
};
var init = function (a, sp, ep, st) {
sp.x = parseFloat(sp.x);
sp.y = parseFloat(sp.y);
ep.x = parseFloat(ep.x);
ep.y = parseFloat(ep.y);
a.sp = sp; //起点
a.ep = ep; //终点
a.st = st; //强度
};
function drawCirLine(ctx, x1, y1, x2, y2, arraw , arraowParams ,degree, direct) {
x1 = parseFloat(x1);
y1 = parseFloat(y1);
x2 = parseFloat(x2);
y2 = parseFloat(y2);
degree = parseFloat(degree);
var direction = direct ? -1 : 1,
crookdegree = degree ? degree * direction : 20 * direction,
x = x2 - x1,
y = y2 - y1,
r = Math.sqrt(x * x + y * y),
deg = Math.asin(Math.abs(y) / Math.abs(r)),
simulationPoint = {
x: x1 + r,
y: y1
},
control1 = {},
control2 = {};
if (x > 0 && y > 0) {
}else if (x < 0 && y > 0) {
deg = Math.PI - deg;
}else if (x < 0 && y < 0) {
deg += Math.PI;
}else if (x > 0 && y < 0) {
deg = - deg;
}
control1['x'] = x1;
control2['x'] = simulationPoint.x;
control1['y'] = y1 + crookdegree;
control2['y'] = simulationPoint.y + crookdegree;
//rotate deg
ctx.translate(x1, y1);
ctx.rotate(deg);
ctx.translate(-x1, -y1);
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.bezierCurveTo(control1.x, control1.y, control2.x, control2.y, simulationPoint.x, simulationPoint.y);
ctx.stroke();
if (arraw) {
var newarraw = new window.canvasqt.arrow();
newarraw.set(control2, simulationPoint);
if (arraowParams) {
newarraw.setPara(arraowParams);
}else
{
newarraw.setPara({
arrow_size: 0.45,
arrow_sharp: 0.35
});
}
newarraw.paint(ctx);
}
ctx.closePath();
// roll back rotate for others'
ctx.translate(x1, y1);
ctx.rotate(-deg);
ctx.translate(-x1, -y1);
}
var arrowProc = {
/**
* 接收canvas对象,并在此上画箭头(箭头起止点已经设置)
* @param context
*/
paint: function (context) {
paint(this, context);
},
/**
* 设置箭头起止点
* @param sp起点
* @param ep终点
* @param st强度
*/
set: function (sp, ep, st) {
init(this, sp, ep, st);
},
/**
* 设置箭头外观
* @param args
*/
setPara: function (args) {
this.size = args.arrow_size; //箭头大小
this.sharp = args.arrow_sharp; //箭头锐钝
}
};
var lineProc = {
draw: function (ctx, x1, y1, x2, y2, arraw,degree, direct) {
drawCirLine(ctx, x1, y1, x2, y2, arraw,degree, direct);
}
}
//计算头部坐标
var calcH = function (a, sp, ep, context) {
var theta = Math.atan((ep.x - sp.x) / (ep.y - sp.y));
var cep = scrollXoy(ep, -theta);
var csp = scrollXoy(sp, -theta);
var ch1 = {
x: 0,
y: 0
};
var ch2 = {
x: 0,
y: 0
};
var l = cep.y - csp.y;
ch1.x = cep.x + l * (a.sharp || 0.025);
ch1.y = cep.y - l * (a.size || 0.05);
ch2.x = cep.x - l * (a.sharp || 0.025);
ch2.y = cep.y - l * (a.size || 0.05);
var h1 = scrollXoy(ch1, theta);
var h2 = scrollXoy(ch2, theta);
return {
h1: h1,
h2: h2
};
};
var paint = function (a, context) {
var sp = a.sp;
var ep = a.ep;
if (context == undefined)
return;
context.beginPath();
//画箭头头部
var h = calcH(a, sp, ep, context);
context.moveTo(ep.x, ep.y);
context.lineTo(h.h1.x, h.h1.y);
context.moveTo(ep.x, ep.y);
context.lineTo(h.h2.x, h.h2.y);
context.stroke();
};
var arrow = new Function();
var drawLine = new Function();
arrow.prototype = arrowProc;
drawLine.prototype = lineProc;
window.canvasqt.arrow = arrow;
window.canvasqt.drawLine = drawLine;
})(window, document);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment