uaeengine
Version:
基于MVVM和canvas的图形框架
140 lines (136 loc) • 4.11 kB
JavaScript
/**
* 坐标是否在圆内
* @param {Number} x 坐标
* @param {Number} y 坐标
* @param {Number} x1 圆心坐标
* @param {Number} y1 圆心坐标
* @param {Number} r 圆半径
*/
export function isPointInCircle(x, y, x1, y1, r) {
// 圆心坐标 (6,6)
const a = Math.abs(x - x1);
const b = Math.abs(y - y1);
const c = Math.sqrt(a * a + b * b);
return c <= r;
}
/**
* 坐标是否在圆角矩形内
* @param {Number} x 坐标
* @param {Number} y 坐标
* @param {Number} x1 圆角矩形坐标
* @param {Number} y1 圆角矩形坐标
* @param {Number} width 圆角矩形宽
* @param {Number} height 圆角矩形高
* @param {Number} radius 圆角矩形圆角半径(选填)
*/
export function isPointInRoundRect(x, y, x1, y1, width, height, radius) {
let x2 = x1 + width;
const y2 = y1 + height;
if (!radius) {
return x >= x1 && x <= x2 && y >= y1 && y <= y2;
}
x1 += radius;
x2 -= radius;
if (x >= x1 && x <= x2 && y >= y1 && y <= y2) {
return true;
}
if (isPointInCircle(x, y, x1, y1 + radius, radius)) {
return true;
}
if (isPointInCircle(x, y, x2, y1 + radius, radius)) {
return true;
}
if (isPointInCircle(x, y, x2, y2 - radius, radius)) {
return true;
}
if (isPointInCircle(x, y, x1, y2 - radius, radius)) {
return true;
}
return false;
}
/**
* 坐标是否在路径上
* @param {Number} x 坐标
* @param {Number} y 坐标
* @param {Array} path 路径坐标{x,y}数组
* @param {Number} pathWidth 路劲宽度
*/
export function isPointInPath(x, y, path, pathWidth) {
const halfPathWidth = pathWidth / 2;
const length = path.length;
for (let i = 1; i < length; i++) {
const prev = path[i - 1];
const item = path[i];
if (prev.x === item.x) {
// 竖
const x1 = prev.x - halfPathWidth;
const x2 = prev.x + halfPathWidth;
const y1 = Math.min(prev.y, item.y);
const y2 = Math.max(prev.y, item.y);
if (x >= x1 && x <= x2 && y >= y1 && y <= y2) {
return true;
}
} else if (prev.y === item.y) {
// 横
const x1 = Math.min(prev.x, item.x);
const x2 = Math.max(prev.x, item.x);
const y1 = prev.y - halfPathWidth;
const y2 = prev.y + halfPathWidth;
if (x >= x1 && x <= x2 && y >= y1 && y <= y2) {
return true;
}
} else {
// 斜
const x1 = Math.min(prev.x, item.x);
const x2 = Math.max(prev.x, item.x);
const y1 = Math.min(prev.y, item.y);
const y2 = Math.max(prev.y, item.y);
if (x >= x1 && x <= x2 && y >= y1 && y <= y2) {
// 在对角线所在的矩形中
// 求直线方程的一般方程的系数
const a = y2 - y1;
const b = x1 - x2;
const c = y1 * (x2 - x1) + x1 * (y1 - y2);
// 点到线的距离
const d = Math.abs(a * x + b * y + c) / Math.sqrt(a * a + b * b);
if (d < halfPathWidth) {
return true;
}
}
}
}
return false;
}
/**
* 绘制圆角矩形
* @param {Object} ctx canvas上下文对象
* @param {Number} x 圆角矩形坐标
* @param {Number} y 圆角矩形坐标
* @param {Number} width 圆角矩形宽
* @param {Number} height 圆角矩形高
* @param {Number} radius 圆角矩形圆角半径(选填)
*/
export function roundRect(ctx, x, y, width, height, radius) {
if (radius) {
ctx.beginPath();
ctx.moveTo(x + radius, y);
ctx.lineTo(x + width - radius, y);
if (radius) {
ctx.arcTo(x + width, y, x + width, y + radius, radius);
}
ctx.lineTo(x + width, y + height - radius);
if (radius) {
ctx.arcTo(x + width, y + height, x + width - radius, y + height, radius);
}
ctx.lineTo(x + radius, y + height);
if (radius) {
ctx.arcTo(x, y + height, x, y + height - radius, radius);
}
ctx.lineTo(x, y + radius);
if (radius) {
ctx.arcTo(x, y, x + radius, y, radius);
}
} else {
ctx.rect(x, y, width, height);
}
}