| | import { useEffect, useRef } from 'react'; |
| | import * as d3 from 'd3'; |
| | import { getConfig } from '../config/mapConfig.js'; |
| | import { applyZoomTransform } from '../utils/mappingUtils.js'; |
| |
|
| | |
| | |
| | |
| | export function useZoom(svgRef, baseGlyphSize, enabled = true, darkMode = false) { |
| | console.log('useZoom: Hook appelé avec baseGlyphSize:', baseGlyphSize); |
| | const zoomRef = useRef(null); |
| | const baseGlyphSizeRef = useRef(baseGlyphSize); |
| | const isInitializedRef = useRef(false); |
| |
|
| | |
| | useEffect(() => { |
| | baseGlyphSizeRef.current = baseGlyphSize; |
| | }, [baseGlyphSize]); |
| |
|
| | |
| | useEffect(() => { |
| | if (!enabled) { |
| | console.log('useZoom: Hook désactivé, sortie'); |
| | return; |
| | } |
| | |
| | |
| | if (isInitializedRef.current) { |
| | console.log('useZoom: Déjà initialisé, sortie'); |
| | return; |
| | } |
| | |
| | const initializeZoom = () => { |
| | if (!svgRef.current) { |
| | console.log('useZoom: svgRef.current is null, en attente...'); |
| | return; |
| | } |
| |
|
| | const svg = d3.select(svgRef.current); |
| | console.log('useZoom: SVG sélectionné', svg.node()); |
| | |
| | |
| | let viewportGroup = svg.select('.viewport-group'); |
| | if (viewportGroup.empty()) { |
| | viewportGroup = svg.append('g').attr('class', 'viewport-group'); |
| | console.log('useZoom: Groupe viewport créé'); |
| | } else { |
| | console.log('useZoom: Groupe viewport existant trouvé'); |
| | } |
| | |
| | |
| | const zoom = d3.zoom() |
| | .scaleExtent(getConfig('zoom.scaleExtent', [0.3, 3.0])) |
| | .on('zoom', (event) => { |
| | console.log('useZoom: Événement de zoom déclenché', event.transform); |
| | |
| | |
| | viewportGroup.attr('transform', event.transform); |
| | |
| | |
| | const scale = event.transform.k; |
| | const fontSize = Math.max(8, 16 / scale); |
| | const strokeColor = darkMode ? '#000000' : '#ffffff'; |
| | |
| | viewportGroup.selectAll('.centroid-label') |
| | .attr('font-size', `${fontSize}px`) |
| | .attr('stroke-width', `${Math.max(1, 4 / scale)}px`) |
| | .attr('stroke', strokeColor); |
| | }) |
| | .on('start', () => { |
| | console.log('useZoom: Début de l\'interaction'); |
| | }) |
| | .on('end', () => { |
| | console.log('useZoom: Fin de l\'interaction'); |
| | }); |
| |
|
| | |
| | svg.call(zoom); |
| | |
| | |
| | const initialScale = getConfig('zoom.initialScale', 0.8); |
| | const svgRect = svg.node().getBoundingClientRect(); |
| | const centerX = svgRect.width / 2; |
| | const centerY = svgRect.height / 2; |
| | |
| | |
| | const initialTransform = d3.zoomIdentity |
| | .translate(centerX * (1 - initialScale), centerY * (1 - initialScale)) |
| | .scale(initialScale); |
| | |
| | |
| | svg.call(zoom.transform, initialTransform); |
| | console.log('useZoom: Zoom initialisé avec échelle:', initialScale); |
| | |
| | |
| | zoomRef.current = zoom; |
| | isInitializedRef.current = true; |
| | }; |
| |
|
| | |
| | initializeZoom(); |
| | |
| | |
| | if (!svgRef.current) { |
| | const timer = setTimeout(initializeZoom, 100); |
| | return () => clearTimeout(timer); |
| | } |
| |
|
| | |
| | return () => { |
| | if (svgRef.current) { |
| | const svg = d3.select(svgRef.current); |
| | svg.on('.zoom', null); |
| | } |
| | |
| | zoomRef.current = null; |
| | isInitializedRef.current = false; |
| | }; |
| | }, [enabled]); |
| |
|
| | const resetZoom = () => { |
| | if (zoomRef.current && svgRef.current && isInitializedRef.current) { |
| | const svg = d3.select(svgRef.current); |
| | const svgNode = svg.node(); |
| | const width = svgNode.clientWidth || window.innerWidth; |
| | const height = svgNode.clientHeight || window.innerHeight; |
| | |
| | const centerX = width / 2; |
| | const centerY = height / 2; |
| | const scale = getConfig('zoom.initialScale', 0.8); |
| | |
| | |
| | const translateX = centerX * (1 - scale); |
| | const translateY = centerY * (1 - scale); |
| | |
| | const resetTransform = d3.zoomIdentity |
| | .translate(translateX, translateY) |
| | .scale(scale); |
| | |
| | svg.transition().duration(getConfig('zoom.transitionDuration', 750)).call( |
| | zoomRef.current.transform, |
| | resetTransform |
| | ); |
| | console.log('useZoom: Reset zoom appliqué'); |
| | } |
| | }; |
| |
|
| | return { resetZoom }; |
| | } |
| |
|