Not work:
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8" />
<title>Путь без карты</title>
<style>
canvas {
border: 1px solid black;
}
#startBtn {
margin-top: 10px;
}
</style>
</head>
<body>
<canvas id="mapCanvas" width="800" height="600"></canvas><br/>
<button id="startBtn">Старт</button>
<script>
const canvas = document.getElementById('mapCanvas');
const ctx = canvas.getContext('2d');
let watchId = null;
let isTracking = false;
let path = []; // Все точки пути
let backPath = []; // Обратный маршрут
let currentPosition = null;
// Иконка для текущего положения
const iconSize = 10;
// Обработчик кнопки
document.getElementById('startBtn').addEventListener('click', () => {
if (!isTracking) {
startTracking();
} else {
stopTracking();
}
});
function startTracking() {
if (navigator.geolocation) {
watchId = navigator.geolocation.watchPosition(
(pos) => {
const { latitude, longitude } = pos.coords;
// Для простоты — используем координаты как есть
// Можно добавить преобразование к экранным координатам
const point = { lat: latitude, lon: longitude };
updatePath(point);
draw();
},
(err) => {
alert('Ошибка получения геолокации: ' + err.message);
},
{
enableHighAccuracy: true,
maximumAge: 0,
timeout: 5000,
}
);
isTracking = true;
document.getElementById('startBtn').textContent = 'Стоп';
} else {
alert('Геолокация не поддерживается браузером');
}
}
function stopTracking() {
if (watchId !== null) {
navigator.geolocation.clearWatch(watchId);
watchId = null;
}
isTracking = false;
document.getElementById('startBtn').textContent = 'Старт';
}
// Обновляем путь
function updatePath(point) {
if (path.length > 0) {
// Если возвращаемся назад, переносим точку в серый путь
const lastPoint = path[path.length - 1];
if (distance(lastPoint, point) > 10) { // порог для определения движения
// Простая проверка - если новая точка значительно отличается, считаем, что возвращаемся
// В реальности можно сделать более сложную логику
// Для примера просто добавляем новую точку
path.push(point);
}
} else {
path.push(point);
}
// Можно добавить логику для определения возврата и окраски пути
// Но для простоты — все новые точки добавляются в зеленый путь
}
// Расстояние между точками
function distance(p1, p2) {
const R = 6371e3; // радиус Земли в метрах
const φ1 = p1.lat * Math.PI/180;
const φ2 = p2.lat * Math.PI/180;
const Δφ = (p2.lat - p1.lat) * Math.PI/180;
const Δλ = (p2.lon - p1.lon) * Math.PI/180;
const a = Math.sin(Δφ/2) * Math.sin(Δφ/2) +
Math.cos(φ1) * Math.cos(φ2) *
Math.sin(Δλ/2) * Math.sin(Δλ/2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
const d = R * c;
return d;
}
// Отрисовка
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
if (path.length === 0) return;
// Определим масштаб и смещение для отображения
// Для простоты — используем диапазон координат и масштабируем под канвас
const xs = path.map(p => p.lon);
const ys = path.map(p => p.lat);
const minX = Math.min(...xs);
const maxX = Math.max(...xs);
const minY = Math.min(...ys);
const maxY = Math.max(...ys);
const padding = 20;
const scaleX = (canvas.width - 2*padding) / (maxX - minX || 1);
const scaleY = (canvas.height - 2*padding) / (maxY - minY || 1);
const scale = Math.min(scaleX, scaleY);
// Функция для преобразования координат
function toCanvas(p) {
return {
x: padding + (p.lon - minX) * scale,
y: canvas.height - padding - (p.lat - minY) * scale // вверх - север
};
}
// Рисуем пройденный путь
ctx.lineWidth = 3;
// Зеленый путь — текущий
ctx.strokeStyle = 'green';
ctx.beginPath();
const start = toCanvas(path[0]);
ctx.moveTo(start.x, start.y);
for (let i = 1; i < path.length; i++) {
const p = toCanvas(path[i]);
ctx.lineTo(p.x, p.y);
}
ctx.stroke();
// Обновляем текущую позицию
currentPosition = toCanvas(path[path.length - 1]);
// Рисуем иконку текущего положения
ctx.fillStyle = 'blue';
ctx.beginPath();
ctx.arc(currentPosition.x, currentPosition.y, iconSize, 0, Math.PI*2);
ctx.fill();
}
</script>
</body>
</html>
среда, 12 августа 2026 г. в 10:51:04 UTC+3, GOOD: