今天有个可爱的小姐姐有些疑惑,类似于这样的图片标注效果怎么实现呢?
我就想着也试了一下
大概思路就是用canvas,弄个覆盖在图片上的画布,就可以开始画了。
我们需要找到需要标注的点,比如眼睛,鼻子,嘴巴的坐标位置,找到位置就好画延展的线了,
那么坐标怎么找呢,我们可以在画布上画一个圆点,比如画布是1000宽高的,那么我们圆点就是(500,500)了,画好圆点之后然后通过移动坐标找到五官对应的坐标点了。
const myCanvas = document.getElementById("myCanvas")
// 画布
myCanvas.width = 1000
myCanvas.height = 1000
let ctx = myCanvas.getContext('2d')
const xR = myCanvas.height / 2 // 圆点
const yR = myCanvas.height / 2
// 绘画点
function setDian(x, y, r) {
ctx.beginPath()
ctx.arc(x, y, r, 0, 2 * Math.PI)
ctx.fillStyle = 'blue'
ctx.fill()
ctx.stroke();
}
this.setDian(xR , yR , 10) // 圆点
这样找到五官对应的坐标,就可以开始连线了
const xY1 = 500, yY1 = 400 // 眼睛1
const xY2 = 400, yY2 = 650 // 眼睛2
const xBZ = 500, yBZ = 550 // 鼻子
连线的地方用到很多,所以和画点一样都写在方法里,下次需要用就调用方法就可以了
function setLine(x, y, x2, y2) {
ctx.strokeStyle = "blue"
ctx.beginPath(); //新建一条path
ctx.moveTo(x, y); //把画笔移动到指定的坐标
ctx.lineTo(x2, y2); //绘制一条从当前位置到指定坐标(200, 50)的直线.
//闭合路径。会拉一条从当前点到path起始点的直线。如果当前点与起始点重合,则什么都不做
ctx.closePath();
ctx.stroke(); //绘制路径。
}
因为就想着实现一下思路,大致就这样,贴一下完整代码:
<!DOCTYPE html>
<html lang="cms-Hans-CN">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<title>标题</title>
<style>
body {
padding: 0;
margin: 0;
}
.app {
width: 100vw;
height: 100vh;
}
.img_bg {
width: 100vw;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.img {
width: 100vw;
height: auto;
}
.canvas_bg {
width: 100vw;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
position: fixed;
top: 0;
left: 0;
z-index: 1;
}
</style>
</head>
<body>
<div class="app">
<div class="img_bg">
<img src="https://img2.baidu.com/it/u=1925553718,3069984470&fm=26&fmt=auto&gp=0.jpg" class="img">
</div>
<div class="canvas_bg">
<canvas id="myCanvas" class="canvas"></canvas>
</div>
</div>
</body>
<script>
const myCanvas = document.getElementById("myCanvas")
// 画布
myCanvas.width = 1000
myCanvas.height = 1000
let ctx = myCanvas.getContext('2d')
const xR = myCanvas.height / 2 // 圆点
const yR = myCanvas.height / 2
const xY1 = 500, yY1 = 400 // 眼睛1
const xY2 = 400, yY2 = 650 // 眼睛2
const xBZ = 500, yBZ = 550 // 鼻子
// 绘画点
function setDian(x, y, r) {
ctx.beginPath()
ctx.arc(x, y, r, 0, 2 * Math.PI)
ctx.fillStyle = 'blue'
ctx.fill()
ctx.stroke();
}
function setLine(x, y, x2, y2) {
ctx.strokeStyle = "blue"
ctx.beginPath(); //新建一条path
ctx.moveTo(x, y); //把画笔移动到指定的坐标
ctx.lineTo(x2, y2); //绘制一条从当前位置到指定坐标(200, 50)的直线.
//闭合路径。会拉一条从当前点到path起始点的直线。如果当前点与起始点重合,则什么都不做
ctx.closePath();
ctx.stroke(); //绘制路径。
}
// 左眼
this.setDian(xY1, yY1, 10) // 小圆点
this.setLine(xY1, yY1, xY1, yY1 - 300) // 竖线
this.setDian(xY1, yY1 - 300, 80) // 大圆点
ctx.fillStyle = '#fff'
ctx.font = "40px Georgia";
ctx.fillText('左眼', xY1 - 40, yY1 - 280) // 字
// 右眼
this.setDian(xY2, yY2, 10) // 小圆点
this.setLine(xY2, yY2, xY2 - 200, yY2) // 横线
this.setLine(xY2 - 200, yY2, xY2 - 200, yY2 - 300) // 竖线
this.setDian(xY2 - 200, yY2 - 300, 80) // 大圆点
ctx.fillStyle = '#fff'
ctx.font = "40px Georgia";
ctx.fillText('右眼', xY2 - 240, yY2 - 280) // 字
this.setDian(xBZ, yBZ, 10) // 小圆点
this.setLine(xBZ, yBZ, xBZ + 200, yBZ) // 横线
this.setLine(xBZ + 200, yBZ, xBZ + 200, yBZ - 300) // 竖线
this.setDian(xBZ + 200, yBZ - 300, 80) // 大圆点
ctx.fillStyle = '#fff'
ctx.font = "40px Georgia";
ctx.fillText('鼻子', xBZ + 160, yBZ - 280) // 字
</script>
</html>
注:图片是随便网上找的可爱猫猫图片地址,所以可能会有图片失效的情况,但不影响其他的