Open david2tdw opened 4 years ago
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>tooltip</title> <style> canvas { cursor: pointer; border: 1px solid black; } </style> <script> // 保存每个点的数据 function Point(x, y, radius, color, value) { this.x = x this.y = y this.radius = radius this.color = color this.value = value this.isSelected = false } var points = [] var previousSelectedPoint var canvas var context window.onload = function () { canvas = document.getElementById('canvas') context = canvas.getContext('2d') // 清空画布 clearCanvas() canvas.onmousemove = onMouseMove } // 绘制 chart function drawChart() { /*开始绘制外边框*/ context.beginPath() context.strokeStyle = '#cdc9c4' context.lineWidth = 4 context.moveTo(100, 400) context.lineTo(1020, 400) context.stroke() context.beginPath() context.strokeStyle = '#cdc9c4' context.lineWidth = 4 context.moveTo(100, 400) context.lineTo(100, 0) context.stroke() /*开始绘制横向内边框*/ context.beginPath() context.strokeStyle = '#e7e5e2' context.lineWidth = 1 for (let i = 1; i <= 6; i++) { context.moveTo(100, 400 - 60 * i) context.lineTo(980, 400 - 60 * i) context.stroke() } /*开始绘制竖向内边框*/ for (let i = 1; i <= 11; i++) { context.moveTo(100 + 80 * i, 400) context.lineTo(100 + 80 * i, 40) context.stroke() } /*开始绘制竖轴文字*/ context.font = '16px SimHei' context.fillStyle = '#00c5de' //从坐标点(50,345)开始绘制文字 for (let i = 0; i <= 6; i++) { context.fillText(10 * i + '万', 50, 405 - 60 * i) } /*开始绘制横轴文字*/ for (let i = 1; i <= 12; i++) { context.fillText('2017-' + i, 80 * i, 440) } context.stroke() } // 将所有的点添加到points中 function addAllPoints(context) { // 模拟的每月数据 var arr = [22, 40, 50, 60, 32, 11, 0, 45, 50, 15, 20, 55] for (let i = 0; i < arr.length; i++) { let x = 100 + 80 * i let y = 400 - arr[i] * 6 // let point = new Point(x, y, 9, 0, Math.PI * 2) let point = new Point(x, y, 9, 'pink', arr[i]) points.push(point) } // 绘制点 drawPoints() } function drawPoints() { for (let i = 0; i < points.length; i++) { let point = points[i] context.globalAlpha = 0.85 context.beginPath() context.arc(point.x, point.y, point.radius, 0, Math.PI * 2) context.fillStyle = '#00c5de' context.strokeStyle = '#00c5de' context.lineWidth = 1 // 绘制选中的点 if (point.isSelected) { context.strokeStyle = '#dc128a' } context.fill() context.closePath() context.stroke() //绘制连接圆的折线 context.beginPath() context.strokeStyle = '#00c5de' context.lineWidth = 1 context.moveTo(point.x, point.y) // console.log(points[i + 1]) if (points[i + 1]) { context.lineTo(points[i + 1].x, points[i + 1].y) } context.stroke() } } function onMouseMove(evt) { // 清空画布 clearCanvas() // 清除之前选择的圆圈 if (previousSelectedPoint != null) { previousSelectedPoint = null } // 取得画布上被单击的点 var mousePosition = getMousePos(canvas, evt) for (let i = 0; i < points.length; i++) { let point = points[i] // 使用勾股定理计算这个点与圆心之间的距离 let distanceFromCenter = Math.sqrt( Math.pow(point.x - mousePosition.x, 2) + Math.pow(point.y - mousePosition.y, 2) ) // 判断这个点是否在圆圈中 if (distanceFromCenter <= point.radius) { // 选择新圆圈 previousSelectedPoint = point point.isSelected = true // 停止搜索 break } } // 绘制点 drawPoints() // 如果当前鼠标位置有圆圈,还要显示tip if (previousSelectedPoint != null) { drawToolTip('当前值为:' + previousSelectedPoint.value + '万', mousePosition.x, mousePosition.y) } } //获取鼠标在canvas画布上的位置(**不是浏览器窗口的鼠标位置) function getMousePos(canvas, evt) { // var rect = canvas.getBoundingClientRect() // return { // x: evt.clientX - rect.left * (canvas.width / rect.width), // y: evt.clientY - rect.top * (canvas.height / rect.height), // } var clickX = evt.pageX - canvas.offsetLeft var clickY = evt.pageY - canvas.offsetTop return { x: clickX, y: clickY, } } /// 清空画布 function clearCanvas() { points = [] context.clearRect(0, 0, canvas.width, canvas.height) drawChart() addAllPoints() } //绘制tooltip提示文字 function drawToolTip(txtLoc, x, y) { context.save() var padding = 3 var gap = 10 var font = '16px arial' context.font = font context.textBaseline = 'bottom' context.fillStyle = 'yellow' //绘制ToolTip背景 var width = context.measureText(txtLoc).width var height = parseInt(font, 10) context.fillRect(x, y - height - gap, width + padding * 2, height + padding * 2) //绘制ToolTip文字 context.fillStyle = '#000' context.fillText(txtLoc, x + padding, y + padding - gap) context.restore() } </script> </head> <body> <div class="myCanvas-cont"> <canvas id="canvas" width="1100" height="500"> 您的浏览器暂不支持canvas </canvas> </div> </body> </html>
HTML5 - 让Canvas内部元素实现鼠标移入、移出效果(Tooltip提示效果)
canvas.save() 和 canvas.restore():
当我们对画布进行旋转,缩放,平移等操作的时候其实我们是想对特定的元素进行操作,比如图片,一个矩形等,但是当你用canvas的方法来进行这些操作的时候,其实是对整个画布进行了操作,那么之后在画布上的元素都会受到影响,所以我们在操作之前调用canvas.save()来保存画布当前的状态,当操作之后取出之前保存过的状态,这样就不会对其他的元素进行影响。
canvas.save() canvas.restore() 作用
HTML5 - 让Canvas内部元素实现鼠标移入、移出效果(Tooltip提示效果)