我的脚本在桌面上运行良好,但在移动设备上运行不佳。 该脚本的工作原理如下:
在桌面上,它运行良好。但不适用于移动设备。
你能帮我改正我的代码吗?
这是页面:http://p4547.phpnet.org/velos/modal/
我已经添加了 touchstart、touchmove 和 touchend 功能,但是不起作用。
这是我的代码:
"use strict";
class Signature {
constructor() {
this.color = "#000000";
this.sign = false;
this.begin_sign = false;
this.width_line = 5;
this.canvas = document.getElementById('canvas');
this.offsetLeft = this.canvas.offsetLeft;
this.offsetTop = this.canvas.offsetTop;
this.context = canvas.getContext('2d');
this.context.lineJoin = 'round'; // jointure arrondie
this.context.lineCap = 'round'; // extrémité arrondie
this.whenActionDown();
this.whenActionUp();
this.whenActionMove();
this.createSignature();
this.clearCanvas();
this.resetCanvas();
}
// Mise à jour de la position de la souris car c'est dans une modal
updateMousePosition(mX, mY) {
let rect = this.canvas.getBoundingClientRect();
let scaleX = this.canvas.width / rect.width;
let scaleY = this.canvas.height / rect.height;
this.cursorX = (mX - rect.left) * scaleX;
this.cursorY = (mY - rect.top) * scaleY;
}
actionDown(e) {
this.sign = true;
this.updateMousePosition(e.clientX, e.clientY);
}
actionUp() {
this.sign = false;
this.begin_sign = false;
}
actionMove(e) {
if (this.sign) {
this.updateMousePosition(e.clientX, e.clientY);
this.createSignature();
}
}
// La signature commence lorsqu'on clique sur la souris :
whenActionDown() {
document.addEventListener("mousedown", this.actionDown.bind(this));
document.addEventListener("touchstart", this.actionDown.bind(this));
}
// Relâchement du clic. On arrête la signature :
whenActionUp() {
document.addEventListener("mouseup", this.actionUp.bind(this));
document.addEventListener("touchend", this.actionUp.bind(this));
}
// Mouvement de la souris sur le canvas :
whenActionMove() {
this.canvas.addEventListener('mousemove', this.actionMove.bind(this));
this.canvas.addEventListener('touchmove', this.actionMove.bind(this));
}
// Fonction qui permet la création de la signature :
createSignature() {
// Si c'est le début, la signature démarre :
if (!this.begin_sign) {
// Placement du curseur pour la première fois :
this.context.beginPath();
this.context.moveTo(this.cursorX, this.cursorY);
this.begin_sign = true;
}
// Sinon on signe :
else {
this.context.lineTo(this.cursorX, this.cursorY);
this.context.strokeStyle = this.color;
this.context.lineWidth = this.width_line;
this.context.stroke();
}
}
// Nettoyage du Canvas :
clearCanvas() {
this.context.clearRect(0, 0, this.canvas.offsetWidth, this.canvas.offsetHeight);
}
// Reset :
resetCanvas() {
document.getElementById("reset").addEventListener("click", () => {
this.clearCanvas();
})
}
}
// Instanciation de la Signature :
document.addEventListener("DOMContentLoaded", event => {
new Signature();
});
请注意:我还是一个初学者,我已经在Google上搜索了解决方案,但没有成功。
要解决签名脚本在桌面上运行而不是在移动设备上运行的问题,您需要关注两个关键事项:
解决方案:统一画布缩放和触摸事件处理
此解决方案将确保画布在不同设备上均匀缩放,并且触摸事件正确转换到画布,避免线条粗细或光标未对齐的任何问题。
代码调整 这是脚本的改进版本,其中包括画布缩放和触摸事件处理的修复:
"use strict";
class Signature {
constructor() {
this.color = "#000000";
this.sign = false;
this.begin_sign = false;
this.width_line = 5;
// Set up the canvas and context
this.canvas = document.getElementById('canvas');
this.context = this.canvas.getContext('2d');
this.context.lineJoin = 'round';
this.context.lineCap = 'round';
// Resize the canvas for uniform behavior across devices
this.resizeCanvas();
// Set up event listeners
this.whenActionDown();
this.whenActionUp();
this.whenActionMove();
this.resetCanvas();
// Ensure the canvas resizes properly when the window is resized
window.addEventListener('resize', this.resizeCanvas.bind(this));
}
// Resize the canvas without applying devicePixelRatio
resizeCanvas() {
const rect = this.canvas.getBoundingClientRect();
this.canvas.width = rect.width;
this.canvas.height = rect.height;
this.clearCanvas(); // Clear the canvas after resizing
}
// Update cursor position with adjusted coordinates
updateMousePosition(mX, mY) {
const rect = this.canvas.getBoundingClientRect();
const scaleX = this.canvas.width / rect.width;
const scaleY = this.canvas.height / rect.height;
this.cursorX = (mX - rect.left) * scaleX;
this.cursorY = (mY - rect.top) * scaleY;
}
actionDown(e) {
this.sign = true;
const clientX = e.touches ? e.touches[0].clientX : e.clientX;
const clientY = e.touches ? e.touches[0].clientY : e.clientY;
this.updateMousePosition(clientX, clientY);
}
actionUp() {
this.sign = false;
this.begin_sign = false;
}
actionMove(e) {
if (this.sign) {
const clientX = e.touches ? e.touches[0].clientX : e.clientX;
const clientY = e.touches ? e.touches[0].clientY : e.clientY;
this.updateMousePosition(clientX, clientY);
this.createSignature();
}
}
whenActionDown() {
this.canvas.addEventListener("mousedown", this.actionDown.bind(this));
this.canvas.addEventListener("touchstart", this.actionDown.bind(this), { passive: false });
}
whenActionUp() {
document.addEventListener("mouseup", this.actionUp.bind(this));
document.addEventListener("touchend", this.actionUp.bind(this));
}
whenActionMove() {
this.canvas.addEventListener('mousemove', this.actionMove.bind(this));
this.canvas.addEventListener('touchmove', this.actionMove.bind(this), { passive: false });
}
createSignature() {
if (!this.begin_sign) {
this.context.beginPath();
this.context.moveTo(this.cursorX, this.cursorY);
this.begin_sign = true;
} else {
this.context.lineTo(this.cursorX, this.cursorY);
this.context.strokeStyle = this.color;
this.context.lineWidth = this.width_line;
this.context.stroke();
}
}
clearCanvas() {
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
}
resetCanvas() {
document.getElementById("reset").addEventListener("click", () => {
this.clearCanvas();
});
}
}
// Initialize the Signature class after the content loads
document.addEventListener("DOMContentLoaded", () => {
new Signature();
});
变更说明
无 devicePixelRatio 的画布缩放:
鼠标和触摸事件的 clientX 和 clientY 处理:
为触摸事件添加{passive: false}:
结果
此解决方案应为您在桌面和移动设备上提供一致的画布行为,具有统一的线条粗细和正确对齐的触摸输入。如果这解决了您的问题,请告诉我!