新增:绘画功能,已处理PC端和移动端兼容性问题
This commit is contained in:
@@ -33,6 +33,7 @@
|
|||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
box-shadow: #000000 0 0 1px;
|
box-shadow: #000000 0 0 1px;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
|
touch-action: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.color-btn {
|
.color-btn {
|
||||||
|
|||||||
@@ -47,17 +47,31 @@
|
|||||||
<div>题目:<span id="topic-name">坐井观天</span></div>
|
<div>题目:<span id="topic-name">坐井观天</span></div>
|
||||||
<div>提示:<span id="topic-tip">成语,四个字</span></div>
|
<div>提示:<span id="topic-tip">成语,四个字</span></div>
|
||||||
</div>
|
</div>
|
||||||
<canvas id="board" width="300" height="300"></canvas>
|
<canvas id="board" width="600" height="600"></canvas>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<button id="black-btn" class="color-btn" style="background-color: #000000;"></button>
|
<button class="color-btn" onclick="changeBrushColor('#000000')"
|
||||||
<button id="red-btn" class="color-btn" style="background-color: #ff0000;"></button>
|
style="background-color: #000000;"></button>
|
||||||
<button id="green-btn" class="color-btn" style="background-color: #00ff00;"></button>
|
<button class="color-btn" onclick="changeBrushColor('#ff0000')"
|
||||||
<button id="blue-btn" class="color-btn" style="background-color: #0000ff;"></button>
|
style="background-color: #ff0000;"></button>
|
||||||
<button id="yellow-btn" class="color-btn" style="background-color: #ffff00;"></button>
|
<button class="color-btn" onclick="changeBrushColor('#00ff00')"
|
||||||
|
style="background-color: #00ff00;"></button>
|
||||||
|
<button class="color-btn" onclick="changeBrushColor('#0000ff')"
|
||||||
|
style="background-color: #0000ff;"></button>
|
||||||
|
<button class="color-btn" onclick="changeBrushColor('#ffff00')"
|
||||||
|
style="background-color: #ffff00;"></button>
|
||||||
</div>
|
</div>
|
||||||
<div><label for="widthPicker">选择画笔宽度:</label>
|
<div>
|
||||||
<input type="range" id="widthPicker" value="1" min="1">
|
<button class="color-btn" onclick="changeBrushWidth(4)"
|
||||||
|
style="background-color: #888888;"></button>
|
||||||
|
<button class="color-btn" onclick="changeBrushWidth(8)"
|
||||||
|
style="background-color: #666666;"></button>
|
||||||
|
<button class="color-btn" onclick="changeBrushWidth(12)"
|
||||||
|
style="background-color: #444444;"></button>
|
||||||
|
<button class="color-btn" onclick="changeBrushWidth(16)"
|
||||||
|
style="background-color: #222222;"></button>
|
||||||
|
<button class="color-btn" onclick="changeBrushWidth(20)"
|
||||||
|
style="background-color: #000000;"></button>
|
||||||
</div>
|
</div>
|
||||||
<div id="player-box">
|
<div id="player-box">
|
||||||
<div class="player-item">张</div>
|
<div class="player-item">张</div>
|
||||||
@@ -88,8 +102,10 @@
|
|||||||
let playerId = "";
|
let playerId = "";
|
||||||
// 当前房间id
|
// 当前房间id
|
||||||
let roomId = "";
|
let roomId = "";
|
||||||
let backendAddr = "192.168.31.222:8080"
|
const backendAddr = "192.168.31.222:8080"
|
||||||
const api = "http://" + backendAddr + "/api"
|
const api = "http://" + backendAddr + "/api"
|
||||||
|
|
||||||
|
|
||||||
init();
|
init();
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
@@ -312,6 +328,28 @@
|
|||||||
if (result.type === "room-chat") {
|
if (result.type === "room-chat") {
|
||||||
$("#chat-box").append("<p>" + result.data + "</p>")
|
$("#chat-box").append("<p>" + result.data + "</p>")
|
||||||
}
|
}
|
||||||
|
if (result.type === "room-draw") {
|
||||||
|
let brush = JSON.parse(result.data);
|
||||||
|
console.log("收到坐标: ", brush.x, brush.y);
|
||||||
|
if (brush.isPoint) {
|
||||||
|
brushPoint = {x: brush.x, y: brush.y}
|
||||||
|
drawPoint(brush.x, brush.y, brush.width, brush.color);
|
||||||
|
} else {
|
||||||
|
// 移动端若按下事件坐标为空,则在划线事件中处理,将新的坐标作为点补充画点事件
|
||||||
|
if (brushPoint.x == null || brushPoint.y == null) {
|
||||||
|
drawPoint(brush.x, brush.y, brush.width, brush.color);
|
||||||
|
brushPoint = {x: brush.x, y: brush.y};
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
drawLine(brushPoint, {
|
||||||
|
x: brush.x,
|
||||||
|
y: brush.y
|
||||||
|
}, brush.width, brush.color);
|
||||||
|
brushPoint = {x: brush.x, y: brush.y};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
ws.onclose = function () {
|
ws.onclose = function () {
|
||||||
// 关闭 websocket
|
// 关闭 websocket
|
||||||
@@ -413,3 +451,5 @@
|
|||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<script src="./js/draw.js"></script>
|
||||||
@@ -0,0 +1,127 @@
|
|||||||
|
// canvas画板
|
||||||
|
let canvas = document.getElementById("board");
|
||||||
|
let context = canvas.getContext("2d");
|
||||||
|
context.imageSmoothingEnabled = true;
|
||||||
|
let brushColor = "#000000";
|
||||||
|
let brushWidth = 2;
|
||||||
|
let brushPoint = {x: 0, y: 0};
|
||||||
|
let isDrawing = false;
|
||||||
|
// PC端 *******************************
|
||||||
|
// 鼠标按下事件处理程序
|
||||||
|
canvas.addEventListener("mousedown", function (event) {
|
||||||
|
isDrawing = true;
|
||||||
|
brushPoint = getBrushPoint(event);
|
||||||
|
// 广播绘画数据
|
||||||
|
sendDrawData(brushPoint.x, brushPoint.y, true);
|
||||||
|
drawPoint(brushPoint.x, brushPoint.y, brushWidth, brushColor);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 鼠标移动事件处理程序
|
||||||
|
canvas.addEventListener("mousemove", function (event) {
|
||||||
|
if (isDrawing) {
|
||||||
|
let newPoint = getBrushPoint(event);
|
||||||
|
// 广播绘画数据
|
||||||
|
sendDrawData(newPoint.x, newPoint.y, false);
|
||||||
|
drawLine(brushPoint, newPoint, brushWidth, brushColor);
|
||||||
|
brushPoint = newPoint;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 鼠标释放事件处理程序
|
||||||
|
canvas.addEventListener("mouseup", function () {
|
||||||
|
isDrawing = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 移动端 *******************************
|
||||||
|
// 触摸开始事件处理程序
|
||||||
|
canvas.addEventListener("touchstart", function (event) {
|
||||||
|
isDrawing = true;
|
||||||
|
brushPoint = getTouchPoint(event);
|
||||||
|
// 广播绘画数据
|
||||||
|
sendDrawData(brushPoint.x, brushPoint.y, true);
|
||||||
|
drawPoint(brushPoint.x, brushPoint.y, brushWidth, brushColor);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 触摸移动事件处理程序
|
||||||
|
canvas.addEventListener("touchmove", function (event) {
|
||||||
|
event.preventDefault(); // 防止滚动页面
|
||||||
|
if (isDrawing) {
|
||||||
|
let newPoint = getTouchPoint(event.touches[0]); // 使用第一个触摸点
|
||||||
|
// 广播绘画数据
|
||||||
|
sendDrawData(newPoint.x, newPoint.y, false);
|
||||||
|
drawLine(brushPoint, newPoint, brushWidth, brushColor);
|
||||||
|
brushPoint = newPoint;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 触摸结束事件处理程序
|
||||||
|
canvas.addEventListener("touchend", function () {
|
||||||
|
isDrawing = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 计算画笔在画布上的坐标
|
||||||
|
function getBrushPoint(event) {
|
||||||
|
let rect = canvas.getBoundingClientRect();
|
||||||
|
return {
|
||||||
|
x: (event.clientX - rect.left) * 2,
|
||||||
|
y: (event.clientY - rect.top) * 2
|
||||||
|
};
|
||||||
|
}
|
||||||
|
// 计算画笔在画布上的触摸坐标
|
||||||
|
function getTouchPoint(touch) {
|
||||||
|
let rect = canvas.getBoundingClientRect();
|
||||||
|
return {
|
||||||
|
x: (touch.clientX - rect.left) * (canvas.width / rect.width),
|
||||||
|
y: (touch.clientY - rect.top) * (canvas.height / rect.height)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
// 绘制单个点
|
||||||
|
function drawPoint(x, y, width, color) {
|
||||||
|
context.beginPath();
|
||||||
|
context.fillStyle = color;
|
||||||
|
context.arc(x, y, width / 2, 0, Math.PI * 2);
|
||||||
|
context.fill();
|
||||||
|
context.closePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 绘制线段
|
||||||
|
function drawLine(startPoint, endPoint, whidth, color) {
|
||||||
|
context.beginPath();
|
||||||
|
context.strokeStyle = color;
|
||||||
|
context.lineWidth = whidth;
|
||||||
|
context.lineCap = "round";
|
||||||
|
context.moveTo(startPoint.x, startPoint.y);
|
||||||
|
context.lineTo(endPoint.x, endPoint.y);
|
||||||
|
context.stroke();
|
||||||
|
context.closePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发送绘图信息的函数
|
||||||
|
function sendDrawData(x, y, isPoint) {
|
||||||
|
// 构造绘图信息对象
|
||||||
|
const drawData = {
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
color: brushColor,
|
||||||
|
width: brushWidth,
|
||||||
|
isPoint
|
||||||
|
};
|
||||||
|
|
||||||
|
sendMessage("room-draw", JSON.stringify(drawData));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 切换画笔颜色
|
||||||
|
* @param color
|
||||||
|
*/
|
||||||
|
function changeBrushColor(color) {
|
||||||
|
brushColor = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 切换画笔宽度
|
||||||
|
* @param width 整数
|
||||||
|
*/
|
||||||
|
function changeBrushWidth(width) {
|
||||||
|
brushWidth = width;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user