diff --git a/src/front/map.js b/src/front/map.js index 874a008..06fc6f9 100644 --- a/src/front/map.js +++ b/src/front/map.js @@ -83,17 +83,28 @@ const makeCourseColor = mainColor => return hsl.hex(); }; +const sizes = { + segmentOuter: 8, + segmentInner: 6, + stopRadius: 6, + stopBorder: 1.5, + courseSize: 15, + courseOuterBorder: 13, + courseBorder: 10, + courseInnerBorder: 7, +}; + const segmentBorderStyle = feature => new Style({ stroke: new Stroke({ color: makeBorderColor(feature.get('colors')[0]), - width: 8, + width: sizes.segmentOuter, }), }); const segmentInnerStyle = feature => new Style({ stroke: new Stroke({ color: feature.get('colors')[0], - width: 6, + width: sizes.segmentInner, }), }); @@ -104,9 +115,9 @@ const stopStyle = feature => new Style({ }), stroke: new Stroke({ color: makeBorderColor(feature.get('colors')[0]), - width: 1.5, + width: sizes.stopBorder, }), - radius: 6, + radius: sizes.stopRadius, }), }); @@ -118,11 +129,11 @@ const getCourseStyle = color => { const icon = document.createElement('canvas'); - const iconSize = 35; - const shapeSize = 15; + const shapeSize = sizes.courseSize; + const iconSize = sizes.courseSize + sizes.courseOuterBorder; icon.width = iconSize; - icon.height = iconSize * 0.6; + icon.height = iconSize; const cx = icon.width / 2; const cy = icon.height / 2; @@ -130,9 +141,9 @@ const getCourseStyle = color => const iconCtx = icon.getContext('2d'); for (let [color, size] of [ - [makeBorderColor(color), 13], - [color, 10], - [makeCourseColor(color), 7] + [makeBorderColor(color), sizes.courseOuterBorder], + [color, sizes.courseBorder], + [makeCourseColor(color), sizes.courseInnerBorder] ]) { iconCtx.fillStyle = color; @@ -223,9 +234,32 @@ const createMap = target => view, }); - // Run courses simulation and draw directly on the map + // Run courses simulation const simulInstance = simulation.start(); + // Course on which the view is currently focused + let focusedCourse = null; + const focusZoom = 17; + + const startFocus = courseId => + { + if (courseId in simulInstance.courses) + { + const course = simulInstance.courses[courseId]; + view.animate({ + center: course.position, + zoom: focusZoom, + duration: 500, + }, () => focusedCourse = courseId); + } + }; + + const stopFocus = () => + { + focusedCourse = null; + }; + + // Draw courses directly on the map map.on('postcompose', ev => { simulInstance.update(); @@ -256,6 +290,12 @@ const createMap = target => const point = new Point(course.position); ctx.drawGeometry(point); + + if (course.id === focusedCourse) + { + view.setCenter(course.position); + // view.setZoom(focus); + } } } @@ -263,6 +303,30 @@ const createMap = target => }); map.render(); + + map.on('singleclick', ev => + { + const mousePixel = map.getPixelFromCoordinate(ev.coordinate); + const maxDistance = sizes.courseSize + sizes.courseOuterBorder; + + for (let course of Object.values(simulInstance.courses)) + { + const coursePixel = map.getPixelFromCoordinate(course.position); + const dx = mousePixel[0] - coursePixel[0]; + const dy = mousePixel[1] - coursePixel[1]; + const distance = dx * dx + dy * dy; + + if (distance <= maxDistance * maxDistance) + { + startFocus(course.id); + return; + } + } + + // Clicking anywhere else resets focus + stopFocus(); + }); + return map; };