canvas 静态
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div style="display: flex;">
<div style="width: 500px;height: 500px;border: 1px solid red;">
<canvas id="canva" width="100%" height="100%"></canvas>
</div>
<br/>
<div style="width: 500px;height: 500px;margin-left: 50px;border: 1px solid rgb(118, 57, 231);">
<img id="img" width="400" height="400">
</div>
</div>
<br/>
<div style="width: 500px;height: 500px;border: 1px solid red;">
<canvas id="canvasRef" width="100%" height="100%"></canvas>
</div>
<script>
/**
* canvas画布ref
*/
let canRef = document.getElementById('canva');
let ctx = canRef.getContext('2d'); // 获取2d上下文对象
console.log(ctx,'ctx');
/**
* 绘制属性
*/
ctx.fillStyle = 'black'; // 填充颜色
ctx.fillRect(0,0,100,100); // 填充坐标、宽高
//ctx.strokeStyle = 'black'; // 描边颜色
//ctx.strokeRect(0,0,100,100); // 描边坐标、宽高
/**
* 展示绘制图像的ref(放大/缩小)
*/
let imgRef = document.getElementById('img');
var imgURL = canRef.toDataURL("image/png"); // 获取图像的数据URL 默认图片格式为png,也可以自定义设置格式。
imgRef.src = imgURL
/**
* 外部图像的ref(放大/缩小)
*/
let canvasRef = document.getElementById('canvasRef');
let context = canvasRef.getContext('2d'); // 获取2d上下文对象
var img = new Image();
img.src = "photo.png";
img.onload = function() {
context.drawImage(img,10,10); // 使用drawImage绘制到画布上面
}
</script>
</body>
</html>
canvas 绘制多个矩形
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Canvas鼠标绘制</title>
<style>
canvas {
border:1px solid #000; }
</style>
</head>
<body>
<canvas id="myCanvas" width="400" height="300"></canvas>
<div>
<button type="button" onclick="clearCanvas()">清除画布</button>
</div>
<script>
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
canvas.addEventListener('mousedown', startDrawing);
canvas.addEventListener('mousemove', draw);
canvas.addEventListener('mouseup', stopDrawing);
let startX;
let startY;
let overX;
let overY;
let rectList = []
function startDrawing(event) {
event.preventDefault();
startX = event.clientX - canvas.offsetLeft
startY = event.clientY - canvas.offsetTop
}
function draw(event) {
if (event.buttons !== 1) return; // 只有当按下左键时才开始绘制
ctx.strokeStyle = "black"; // 线条颜色为黑色
ctx.lineWidth = 2; // 线条宽度为2像素
ctx.clearRect(0,0,canvas.width,canvas.height)
overX = event.offsetX - startX
overY = event.offsetY - startY
paintRect(startX, startY, overX, overY)
rectList.forEach(v=>paintRect(v.p1, v.p2, v.p3, v.p4))
}
function paintRect(startX, startY, overX, overY) {
ctx.save() // 将当前状态压入堆栈
ctx.beginPath() // 创建新路径
ctx.strokeRect(startX, startY, overX, overY); // 绘制填充了指定颜色的矩形
ctx.restore() // 弹出堆栈上的顶级状态,将上下文恢复到该状态。
}
function stopDrawing() {
ctx.closePath(); // 停止路径
rectList.push(JSON.parse(JSON.stringify({
p1:startX, p2: startY,p3: overX,p4: overY})))
console.log(rectList,'1');
canvas.addEventListener('mousemove', draw);
}
// function clearCanvas() { // 全部清除
// ctx.clearRect(0,0,canvas.width,canvas.height)
// }
function clearCanvas() {
// 清除上一个
if (rectList.length > 1) {
rectList.pop()
}
}
</script>
</body>
</html>
canvas 选择形状
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>跟随鼠标绘制矩形框</title>
<style>
#canvas {
border: 1px solid red;
}
</style>
</head>
<body>
<canvas id="canvas" width="640" height="480"></canvas>
<select name="mode" id="mode">
<option value="point">标记关键点</option>
<option value="rect">绘制矩形框</option>
</select>
<button id="undo" onclick="undo()">撤销</button>
<script>
const canvas = document.getElementById('canvas'),
context = canvas.getContext('2d'), //取得2D上下文对象
pointArray = [],
history = []
let dragging = false,
mode = 'point',
mousedown = null
function Point(x, y, type) {
this.x = x
this.y = y
this.type = type // 左击 1 右击 3
}
// 坐标转化为canvas坐标
function windowToCanvas(x, y, type) {
//返回元素的大小以及位置
var bbox = canvas.getBoundingClientRect();
// bbox 的宽度会加上 canvas 的 border 会影响精度
return new Point(x - bbox.left * (canvas.width / bbox.width),
y - bbox.top * (canvas.height / bbox.height), type)
}
function drawPoint(point) {
context.save()
context.fillStyle = point['type'] === 3 ? 'red' : 'green'
context.beginPath();
context.arc(point.x, point.y, 3, 0, Math.PI * 2, true)
context.fill()
context.font = "20px serif";
context.fillText((pointArray.length).toString(), point.x - 5, point.y - 10)
context.restore()
pointArray.push(point)
}
function updateRect(point) {
let w = Math.abs(point.x - mousedown.x)
let h = Math.abs(point.y - mousedown.y)
let left = point.x > mousedown.x ? mousedown.x : point.x
let top = point.y > mousedown.y ? mousedown.y : point.y
context.save();
context.beginPath();
context.rect(left, top, w, h);
context.stroke();
context.restore();
}
function showLastHistory() {
context.putImageData(history[history.length - 1]['data'], 0, 0)
}
function undo() {
if (history.length > 1) {
history[history.length - 1]['mode'] === 'point' && pointArray.pop()
history.pop()
showLastHistory()
}
}
function addHistoy(data) {
history.push({
mode,
data: context.getImageData(0, 0, canvas.width, canvas.height)
})
}
document.getElementById('mode').onchange = function(e) {
mode = e.target.value
}
// 鼠标事件
canvas.onmousedown = function(e) {
e.preventDefault();
mousedown = windowToCanvas(e.clientX, e.clientY, e.which)
dragging = true
}
canvas.onmousemove = function(e) {
e.preventDefault();
if (dragging && mode === 'rect') {
// 只有绘制矩形框时有效果
showLastHistory() // 每次绘制先清除上一次
updateRect(windowToCanvas(e.clientX, e.clientY, e.which))
}
}
addHistoy() // 添加一张默认的数据
canvas.onmouseup = function(e) {
e.preventDefault();
dragging = false
mode === 'point' && drawPoint(mousedown)
addHistoy() // 保存上一次数据
}
// 阻止页面的右击菜单栏
canvas.oncontextmenu = function(e) {
e.preventDefault()
}
</script>
</body>
</html>