JavaScript 如何操作和操作 SVG
JavaScript 与 SVG 的结合可以实现强大的动态交互功能。以下是 JavaScript 操作 SVG 的主要方法:1. 选择 SVG 元素使用标准 DOM 方法选择 SVG 元素。// 通过 ID 选择const circle = document.getElementById('myCircle');// 通过类名选择const circles = document.querySelectorAll('.circle');// 通过标签名选择const allRects = document.querySelectorAll('rect');// 通过属性选择const filledElements = document.querySelectorAll('[fill="red"]');2. 创建 SVG 元素使用 createElementNS 创建 SVG 元素(注意命名空间)。const svgNS = 'http://www.w3.org/2000/svg';// 创建 SVG 元素const circle = document.createElementNS(svgNS, 'circle');circle.setAttribute('cx', '100');circle.setAttribute('cy', '100');circle.setAttribute('r', '50');circle.setAttribute('fill', 'blue');// 添加到 SVGconst svg = document.querySelector('svg');svg.appendChild(circle);3. 修改 SVG 属性使用 setAttribute 和 getAttribute 方法。const circle = document.querySelector('circle');// 修改属性circle.setAttribute('fill', 'red');circle.setAttribute('r', '60');circle.setAttribute('stroke', 'black');circle.setAttribute('stroke-width', '3');// 获取属性const fill = circle.getAttribute('fill');const radius = circle.getAttribute('r');4. 修改 SVG 样式使用 style 属性或 classList。const circle = document.querySelector('circle');// 直接设置样式circle.style.fill = 'green';circle.style.opacity = '0.5';circle.style.transform = 'scale(1.2)';// 使用 classListcircle.classList.add('highlight');circle.classList.remove('normal');circle.classList.toggle('active');5. 事件监听为 SVG 元素添加事件监听器。const circle = document.querySelector('circle');// 鼠标事件circle.addEventListener('click', function() { console.log('Circle clicked!'); this.setAttribute('fill', 'red');});circle.addEventListener('mouseover', function() { this.style.cursor = 'pointer';});circle.addEventListener('mouseout', function() { this.style.cursor = 'default';});// 键盘事件(需要 tabindex)circle.setAttribute('tabindex', '0');circle.addEventListener('keydown', function(event) { if (event.key === 'Enter' || event.key === ' ') { event.preventDefault(); console.log('Circle activated!'); }});6. 动画实现使用 JavaScript 实现 SVG 动画。const circle = document.querySelector('circle');// 使用 requestAnimationFramelet progress = 0;function animate() { progress += 0.01; const x = 100 + Math.sin(progress * 2 * Math.PI) * 50; circle.setAttribute('cx', x); if (progress < 1) { requestAnimationFrame(animate); }}animate();// 使用 CSS 过渡circle.style.transition = 'all 0.5s ease';circle.setAttribute('fill', 'red');circle.setAttribute('r', '60');7. 获取鼠标位置获取鼠标在 SVG 中的相对位置。const svg = document.querySelector('svg');svg.addEventListener('click', function(event) { const point = svg.createSVGPoint(); point.x = event.clientX; point.y = event.clientY; const svgPoint = point.matrixTransform(svg.getScreenCTM().inverse()); console.log(`SVG coordinates: x=${svgPoint.x}, y=${svgPoint.y}`);});8. 拖拽功能实现 SVG 元素的拖拽。let selectedElement = null;let offset = { x: 0, y: 0 };function getMousePosition(evt) { const CTM = svg.getScreenCTM(); return { x: (evt.clientX - CTM.e) / CTM.a, y: (evt.clientY - CTM.f) / CTM.d };}function startDrag(evt) { selectedElement = evt.target; offset = getMousePosition(evt); offset.x -= parseFloat(selectedElement.getAttribute('cx')); offset.y -= parseFloat(selectedElement.getAttribute('cy'));}function drag(evt) { if (selectedElement) { evt.preventDefault(); const coord = getMousePosition(evt); selectedElement.setAttribute('cx', coord.x - offset.x); selectedElement.setAttribute('cy', coord.y - offset.y); }}function endDrag(evt) { selectedElement = null;}const svg = document.querySelector('svg');svg.addEventListener('mousedown', startDrag);svg.addEventListener('mousemove', drag);svg.addEventListener('mouseup', endDrag);svg.addEventListener('mouseleave', endDrag);9. 动态创建复杂图形使用 JavaScript 动态创建复杂的 SVG 图形。function createStar(cx, cy, spikes, outerRadius, innerRadius) { const svgNS = 'http://www.w3.org/2000/svg'; const polygon = document.createElementNS(svgNS, 'polygon'); let points = []; for (let i = 0; i < spikes * 2; i++) { const radius = i % 2 === 0 ? outerRadius : innerRadius; const angle = (Math.PI / spikes) * i; const x = cx + Math.cos(angle) * radius; const y = cy + Math.sin(angle) * radius; points.push(`${x},${y}`); } polygon.setAttribute('points', points.join(' ')); polygon.setAttribute('fill', 'gold'); polygon.setAttribute('stroke', 'orange'); polygon.setAttribute('stroke-width', '2'); return polygon;}const svg = document.querySelector('svg');const star = createStar(100, 100, 5, 50, 25);svg.appendChild(star);10. 数据可视化使用 SVG 和 JavaScript 创建数据可视化。const data = [10, 25, 40, 30, 50];const svg = document.querySelector('svg');const barWidth = 40;const gap = 20;data.forEach((value, index) => { const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect'); const x = 20 + index * (barWidth + gap); const y = 200 - value * 3; rect.setAttribute('x', x); rect.setAttribute('y', y); rect.setAttribute('width', barWidth); rect.setAttribute('height', value * 3); rect.setAttribute('fill', `hsl(${index * 60}, 70%, 50%)`); svg.appendChild(rect);});最佳实践:使用 createElementNS 创建 SVG 元素合理使用事件委托优化动画性能,使用 requestAnimationFrame注意命名空间考虑使用 SVG 库(如 D3.js)处理复杂场景测试跨浏览器兼容性