Подпись React Canvas не работает на мобильных устройствах - сенсорные события не запускаются, несмотря на пассив: falseJavascript

Форум по Javascript
Ответить
Anonymous
 Подпись React Canvas не работает на мобильных устройствах - сенсорные события не запускаются, несмотря на пассив: false

Сообщение Anonymous »

У меня есть компонент подписи React Canvas, который отлично работает на настольном компьютере (события мыши), но совершенно не работает на мобильных устройствах (события касания). Я не могу ничего рисовать на мобильном телефоне - события касания, кажется, вообще не срабатывают.
Что я пробовал:
  • Добавил прослушиватели событий касания вручную с помощью { пассивного: false
  • Установил touchAction: 'none' на холсте
  • Вызов PreventDefault() и stopPropagation() для всех событий касания.
  • Использовано useRef для состояния рисования, чтобы избежать устаревших замыканий.
  • Удалена функция скрытия переполнения из родительских контейнеров.
  • Настроено правильное масштабирование соотношения пикселей устройства.
Проблема:
События мыши работают на настольных компьютерах, но события касания ничего не делают на мобильных устройствах. Холст вообще не реагирует на прикосновения пальцев.
Среда:
  • React 18.
  • Тестирование в iOS Safari и Chrome на Android.
  • Настольный Chrome работает нормально.
Код:

Код: Выделить всё

const SignatureCanvas = () => {
const canvasRef = React.useRef(null);
const containerRef = React.useRef(null);
const isDrawingRef = React.useRef(false);

// Initialize canvas with device pixel ratio
const initializeCanvas = React.useCallback(() => {
if (canvasRef.current && containerRef.current) {
const canvas = canvasRef.current;
const container = containerRef.current;
const rect = container.getBoundingClientRect();
const dpr = window.devicePixelRatio || 1;

canvas.width = rect.width * dpr;
canvas.height = 200 * dpr;
canvas.style.width = `${rect.width}px`;
canvas.style.height = `200px`;

const ctx = canvas.getContext('2d');
ctx.scale(dpr, dpr);
ctx.lineWidth = 2;
ctx.lineCap = 'round';
ctx.strokeStyle = '#000';
}
}, []);

React.useEffect(() => {
initializeCanvas();
}, [initializeCanvas]);

// Attach touch listeners with { passive: false }
React.useEffect(() => {
const canvas = canvasRef.current;
if (!canvas) return;

const touchStartHandler = (e) => startDrawing(e);
const touchMoveHandler = (e) => draw(e);
const touchEndHandler = (e) => stopDrawing(e);

canvas.addEventListener('touchstart', touchStartHandler, { passive: false });
canvas.addEventListener('touchmove', touchMoveHandler, { passive: false });
canvas.addEventListener('touchend', touchEndHandler, { passive: false });

return () => {
canvas.removeEventListener('touchstart', touchStartHandler);
canvas.removeEventListener('touchmove', touchMoveHandler);
canvas.removeEventListener('touchend', touchEndHandler);
};
}, []);

const getCoordinates = (e) => {
const canvas = canvasRef.current;
if (!canvas) return { x: 0, y: 0 };

const rect = canvas.getBoundingClientRect();
let clientX, clientY;

if (e.type.includes('touch')) {
const touch = e.touches[0] || e.changedTouches[0];
if (!touch) return { x: 0, y: 0 };
clientX = touch.clientX;
clientY = touch.clientY;
} else {
clientX = e.clientX;
clientY = e.clientY;
}

return {
x: clientX - rect.left,
y: clientY - rect.top
};
};

const startDrawing = (e) => {
if (e.type.includes('touch')) {
e.preventDefault();
e.stopPropagation();
}

const canvas = canvasRef.current;
if (!canvas) return;

const ctx = canvas.getContext('2d');
const coords = getCoordinates(e);

ctx.beginPath();
ctx.moveTo(coords.x, coords.y);
isDrawingRef.current = true;
};

const draw = (e) => {
if (!isDrawingRef.current) return;

if (e.type.includes('touch')) {
e.preventDefault();
e.stopPropagation();
}

const canvas = canvasRef.current;
if (!canvas) return;

const ctx = canvas.getContext('2d');
const coords = getCoordinates(e);

ctx.lineTo(coords.x, coords.y);
ctx.stroke();
};

const stopDrawing = (e) => {
if (e &&  e.type.includes('touch')) {
e.preventDefault();
}
isDrawingRef.current = false;
};

return (



);
};
Вопрос:
Что мне не хватает? Почему события касания работают в консоли браузера (я вижу срабатывание touchstart), но холст не реагирует на попытки рисования на мобильных устройствах?
Есть ли лучший подход к обработке подписей холста, который надежно работает на всех устройствах?

Подробнее здесь: https://stackoverflow.com/questions/798 ... -despite-p
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Javascript»