Статья по теме:
Демо JavaScript:
<script> /* Управление мышью: - удерживание ЛКМ + перемещение для перетаскивания - вращение колесика для масштабирования - удерживание ПКМ + вращение колесика для вращения */ // Инициализация переменных и добавление обработчика событий для события contextmenu, чтобы предотвратить появление контекстного меню по нажатию ПКМ document.getElementById('viewport').addEventListener('contextmenu', mouseDown); let scale = 50, angle = 1, startX, startY, xOffset = 0, yOffset = 0, xPos = 0, yPos = 0, dragging = false, rightMouseButtonPressed = false; // Первоначальная отрисовка setTimeout(() => { redraw() }, 250); function rotate(value) { angle += 2 * value; redraw(); } // Основная функция для отрисовки графика с учетом текущих параметров function redraw() { let ctx = document.getElementById('viewport').getContext('2d'), x, y; ctx.clearRect(0, 0, 500, 500); ctx.lineWidth = 2; ctx.strokeStyle = '#188ce1'; ctx.beginPath(); let slider = document.getElementById("scale"); for (t = 0; t <= 2 * Math.PI; t += 0.005) { x = 20 * (Math.cos(t) + Math.cos(5 * t) / 5) * scale * 0.1; y = 20 * (Math.sin(t) - Math.sin(5 * t) / 5) * scale * 0.1; ctx.lineTo((x * Math.cos(angle) - y * Math.sin(angle)) + 250 + xOffset + xPos, (x * Math.sin(angle) + y * Math.cos(angle)) + 250 + yOffset + yPos); } ctx.stroke(); } // Обработка клика мышью. На ЛКМ сохраняем координаты для последующего перемещения графика. На ПКМ - сохраняем состояние текущей нажатой кнопки function mouseDown(e) { e.preventDefault(); if (e.button == 0) { dragging = true; startX = e.pageX; startY = e.pageY; } else if (e.button == 2) { rightMouseButtonPressed = true; } } // Перемещение мыши. Проверка, что нажата ЛКМ, перемещение графика и переотрисовка графика function mouseMove(e) { if (!dragging) { return; } xOffset = e.pageX - startX; yOffset = e.pageY - startY; redraw(); } // Событие отпускания кнопки мыши. На ЛКМ сохраняем текущие координаты графика. На ПКМ - сохраняем состояние текущей нажатой кнопки function mouseFinish(e) { if (e.button == 0) { dragging = false; xPos = xPos + xOffset; yPos = yPos + yOffset; xOffset = 0; yOffset = 0; } else if (e.button == 2) { rightMouseButtonPressed = false; } } // Событие вращения колесика мыши. В зависимости от нажатых кнопок происходит вращение или масштабирование графика. function mouseWheel(e) { e.preventDefault(); if (!rightMouseButtonPressed) { let delta = Math.sign(e.deltaY); scale -= delta * -6; scale = Math.max(scale, 0); redraw(); } else { rotate(Math.sign(e.deltaY)); } } </script> <style> canvas { border: 1px solid rgba(255, 255, 255, .2); border-radius: 10px; } .container { height: 100vh; align-items: center; display: flex; justify-content: center; position: relative; background-color: #131436; } </style>