绘制点
/**
* 画点
* @param {*} x 起点坐标X
* @param {*} y 起点坐标Y
* @param {*} radius 点半径
* @param {*} fillStyle 填充颜色
*/
export function drawDot(ctx, x, y, radius, fillStyle = 'rgb(191, 191, 191)') {
ctx.beginPath();
ctx.arc(x, y, radius, 0, 2 * Math.PI);
ctx.fillStyle = fillStyle;
ctx.fill();
ctx.closePath();
}
绘制线
/**
* 画线
* @param {*} x 起点坐标X
* @param {*} y 起点坐标Y
* @param {*} lineWidth 线宽度
* @param {*} length 线长度
* @param {*} type 水平、垂直
* @param {*} strokeStyle 颜色
*/
export function drawLin(ctx, x, y, lineWidth, length, strokeStyle = "rgb(0,32,96)", type = "horizontal") {
ctx.beginPath();
ctx.lineWidth = lineWidth;
ctx.strokeStyle = strokeStyle;
ctx.moveTo(x, y);
ctx.lineCap = 'round ';
// 水平线
if (type == "horizontal") {
ctx.lineTo(x + length, y);
}
// 垂直线
if (type == "vertical") {
ctx.lineTo(x, y + length);
}
ctx.stroke();
}
绘制虚线
/**
* 画虚线
* @param {*} x x坐标
* @param {*} y y坐标
* @param {*} lineLength 线长度
* @param {*} lineWidth 先宽度
* @param {*} strokeStyle 颜色
*/
export function drawDashed(ctx, x, y, lineLength, lineWidth, strokeStyle) {
ctx.lineWidth = lineWidth;
ctx.strokeStyle = strokeStyle;
ctx.beginPath();
ctx.setLineDash([10, 5]);
ctx.moveTo(x, y);
ctx.lineTo(x + lineLength, y);
ctx.stroke();
ctx.setLineDash([]);
}
绘制三角形
/**
* 画三角形
* @param {*} x1 第一个点x坐标
* @param {*} y1 第一个点y坐标
* @param {*} x2 第二个点x坐标
* @param {*} y2 第二个点y坐标
* @param {*} x3 第三个点x坐标
* @param {*} y3 第三个点y坐标
* @param {*} fillStyle 颜色
*/
export function drawDelta(ctx, x1, y1, x2, y2, x3, y3, fillStyle) {
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.lineTo(x3, y3);
ctx.fillStyle = fillStyle;
ctx.closePath();
ctx.fill();
}
绘制长方形框
// 空心框
ctx.lineWidth = lineWidth;
ctx.strokeStyle = strokeStyle
ctx.strokeRect(x, y, width, height);
// 实心框
ctx.fillStyle = fillStyle;
ctx.fillRect(x, y, width, height)
绘制箭头
/**
* 画箭头
* @param {*} fromX 起点坐标X
* @param {*} fromY 起点坐标Y
* @param {*} toX 终点坐标 X
* @param {*} toY 终点坐标 Y
* @param {*} theta 三角斜边一直线夹角
* @param {*} headlen 三角斜边长度
* @param {*} width 箭头线宽度
* @param {*} color 箭头颜色
*/
export function drawArrow(ctx, fromX, fromY, toX, toY, theta, headlen, width, color) {
theta = typeof (theta) != 'undefined' ? theta : 30;
headlen = typeof (theta) != 'undefined' ? headlen : 10;
width = typeof (width) != 'undefined' ? width : 1;
color = typeof (color) != 'color' ? color : 'rgb(0,32,96)';
// 计算各角度和对应的P2,P3坐标
var angle = Math.atan2(fromY - toY, fromX - toX) * 180 / Math.PI,
angle1 = (angle + theta) * Math.PI / 180,
angle2 = (angle - theta) * Math.PI / 180,
topX = headlen * Math.cos(angle1),
topY = headlen * Math.sin(angle1),
botX = headlen * Math.cos(angle2),
botY = headlen * Math.sin(angle2);
ctx.save();
ctx.beginPath();
var arrowX = fromX - topX,
arrowY = fromY - topY;
ctx.moveTo(arrowX, arrowY);
ctx.moveTo(fromX, fromY);
ctx.lineTo(toX, toY);
arrowX = toX + topX;
arrowY = toY + topY;
ctx.moveTo(arrowX, arrowY);
ctx.lineTo(toX, toY);
arrowX = toX + botX;
arrowY = toY + botY;
ctx.lineTo(arrowX, arrowY);
ctx.strokeStyle = color;
ctx.lineWidth = width;
ctx.stroke();
}
绘制文本
-
- fillText(text, x, y [, maxWidth])
- strokeText(text, x, y [, maxWidth])
文本样式属性:
字体: font
对齐方式 :textAlign 值:start end left right center 默认:start
基线对齐方式:textBaseline 值:ophanging middle alphabetic ideographic bottom 默认: alphabetic
方向 : direction 值: ltr rtl inherit 默认:inherit
// html
<canvas id="tutorial" width="150" height="150"></canvas>
// js
// canvas 绘制文本
const canvasEle = document.querySelector("#tutorial");
const cxt = canvasEle.getContext("2d");
const documentElement = document.documentElement;
// 设置canvas的宽高全屏
canvasEle.width = documentElement.clientWidth;
canvasEle.height = documentElement.clientHeight;
cxt.fillText("heihei", 100, 100)
// 文字样式
cxt.font = "20px serif"
cxt.textAlign = "center"
cxt.textBaseline = "middle"
cxt.fillText("heihei", 100, 100)
绘制多行文本
/**
* 文本分段
* @param {*} text 文本
* @param {*} maxWidth 每行最大宽度
*/
export function getWrapText(ctx, text, maxWidth) {
if (!text) {
return []
}
let txtList = [];
let str = "";
for (let i = 0, len = text.length; i < len; i++) {
str += text.charAt(i);
if (ctx.measureText(str).width > maxWidth) {
txtList.push(str.substring(0, str.length - 1))
str = ""
i--
}
}
txtList.push(str)
return txtList;
}
/**
* 画多行文本
* @param {*} x 起点坐标X
* @param {*} y 起点坐标Y
* @param {*} text 文本数组
* @param {*} font 文本样式
* @param {*} fillStyle 文本颜色
*/
export function drawText(ctx, x, y, wrapTexts, font = "14px Arial", fillStyle = 'rgb(0,32,96)', lineHeight = 15, maxWidth = 150) {
ctx.font = font;
ctx.fillStyle = fillStyle;
let height = wrapTexts.length * lineHeight
wrapTexts.forEach((txt, index) => {
ctx.fillText(txt, x, y + lineHeight * index, maxWidth);
})
return height
}
绘制图片
/**
* 加载图片
* @param {*} url 图片地址
* @param {*} isRight 是否在右侧
* @param {*} imgWidth 图片宽度
* @param {*} imgHeight 图片高度
*/
export function loadImage(url, imgWidth, imgHeight) {
return new Promise((resolve, reject) => {
//创建img元素
let img = new Image();
//设置图片源地址
img.src = url;
// 跨域
img.setAttribute("crossOrigin", 'Anonymous');
img.onload = function () {
let width = imgWidth;
let height = imgHeight;
let x = 0, y = 0;
if (this.height / this.width <= (height / width)) {
let oldHeight = height;
height = this.height / (this.width / width);
y = (oldHeight - height) / 2;
} else {
let oldWidth = width;
width = this.width / (this.height / height);
x = (oldWidth - width) / 2;
}
resolve({
img,
width, // 图片实际宽度
height, // 图片实际高度
x, // 图片左右的留白
y // 图片上下的留白
})
}
img.onerror = function (err) {
console.log(err);
reject()
}
})
}
async test() {
// 画图片
let {img, width: iWidth, height: iHeight} = await loadImage(url, imgWidth, imgHeight)
ctx.drawImage(img, x, y, iWidth, iHeight)
}
设置高清canvas
注意: 先把canvas设为高清,再画东西,
当使用canvas宽度时,要用设置高清之前的canvas宽度
/**
* 高清canvas
* @param {*} canvas 要高清的canvas
*/
export function createHDCanvas(canvas) {
var ratio = 3
let lowCanvas = document.getElementById('eventLine')
let ctx = canvas.getContext('2d');
canvas.width = Math.floor(lowCanvas.width * ratio); // 实际渲染像素
canvas.height = Math.floor(lowCanvas.height * ratio); // 实际渲染像素
canvas.style.width = `${canvas.width}px`; // 控制显示大小
canvas.style.height = `${canvas.height}px`; // 控制显示大小
ctx.scale(ratio, ratio);
return canvas;
}