[canvas] Canvas拖动交互
Opened this issue · 1 comments
david2tdw commented
[canvas] Canvas拖动交互
david2tdw commented
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>canvas drag</title>
<style>
canvas {
cursor: pointer;
border: 1px solid #008080;
}
</style>
<script>
// 这个方法用来储存每个圆圈对象
function Circle(x, y, radius, color) {
this.x = x
this.y = y
this.radius = radius
this.color = color
}
// 保存画布上所有的圆圈
var circles = []
var canvas
var context
var isDraging = false
let previousSelectedCircle
window.onload = function () {
canvas = document.getElementById('canvas')
context = canvas.getContext('2d')
canvas.onmousedown = canvasClick
canvas.onmouseup = stopDragging
canvas.onmouseout = stopDragging
canvas.onmousemove = dragCircle
}
// 在某个范围内生成随机数
function randomFromTo(from, to) {
return Math.floor(Math.random() * (to - from + 1) + from)
}
function addRandomCircle() {
// 为圆圈计算一个随机大小和位置
let radius = randomFromTo(10, 60)
let x = randomFromTo(0, canvas.width)
let y = randomFromTo(0, canvas.height)
// 为圆圈计算一个随机颜色
const colors = ['green', 'blue', 'red', 'yellow', 'magenta', 'orange', 'brown', 'purple', 'pink']
let color = colors[randomFromTo(0, 8)]
console.log(color)
// 创建一个新圆圈
let circle = new Circle(x, y, radius, color)
// 把它保存在数组中
circles.push(circle)
// 重新绘制画布
drawCircles()
}
function clearCanvas() {
// 去除所有圆圈
circles = []
// 重新绘制画布
drawCircles()
}
function drawCircles() {
// 清除画布,准备绘制
context.clearRect(0, 0, canvas.width, canvas.height)
for (let i = 0; i < circles.length; i++) {
let circle = circles[i]
//绘制圆圈
context.globalAlpha = 0.85
context.beginPath()
context.arc(circle.x, circle.y, circle.radius, 0, Math.PI * 2)
context.fillStyle = circle.color
context.strokeStyle = 'black'
if (circle.isSelected) {
context.lineWidth = 5
} else {
context.lineWidth = 1
}
context.fill()
context.stroke()
}
}
function canvasClick(event) {
//取得画布上被单击的点
let clickX = event.pageX - canvas.offsetLeft
let clickY = event.pageY - canvas.offsetTop
// 查找被单击的圆圈
// 后添加的圆层级高,所以要倒过来循环查找, 否则在覆盖的时候会出现层级错误问题!!!
for (let i = circles.length - 1; i >= 0; i--) {
let circle = circles[i]
// 使用勾股定理计算这个点与圆心之间的距离
let distanceFromCenter = Math.sqrt(Math.pow(circle.x - clickX, 2) + Math.pow(circle.y - clickY, 2))
// 判断这个点是否在圆圈中
if (distanceFromCenter <= circle.radius) {
// 清除之前选择的圆圈
if (previousSelectedCircle != null) {
previousSelectedCircle.isSelected = false
}
// 选择新圆圈
previousSelectedCircle = circle
circle.isSelected = true
// 使圆圈允许拖拽
isDraging = true
// 更新显示
drawCircles()
// return 停止搜索
return
}
console.log(i)
}
}
function stopDragging() {
isDraging = false
}
function dragCircle(event) {
// 判断圆圈是否开始拖拽
if (isDraging === true) {
// 判断拖拽对象是否存在
if (previousSelectedCircle != null) {
// 取得鼠标位置
let x = event.pageX - canvas.offsetLeft
let y = event.pageY - canvas.offsetTop
// 将圆圈移动到鼠标位置
previousSelectedCircle.x = x
previousSelectedCircle.y = y
// 更新画布
drawCircles()
}
}
}
</script>
</head>
<body>
<canvas id="canvas" width="400" height="300"></canvas>
<div>
<button onclick="addRandomCircle()">添加圆圈</button>
<button onclick="clearCanvas()">清空画布</button>
</div>
</body>
</html>