乐闻世界logo
搜索文章和话题

JavaScript 如何操作和操作 SVG

2月21日 15:58

JavaScript 与 SVG 的结合可以实现强大的动态交互功能。以下是 JavaScript 操作 SVG 的主要方法:

1. 选择 SVG 元素 使用标准 DOM 方法选择 SVG 元素。

javascript
// 通过 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 元素(注意命名空间)。

javascript
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'); // 添加到 SVG const svg = document.querySelector('svg'); svg.appendChild(circle);

3. 修改 SVG 属性 使用 setAttributegetAttribute 方法。

javascript
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

javascript
const circle = document.querySelector('circle'); // 直接设置样式 circle.style.fill = 'green'; circle.style.opacity = '0.5'; circle.style.transform = 'scale(1.2)'; // 使用 classList circle.classList.add('highlight'); circle.classList.remove('normal'); circle.classList.toggle('active');

5. 事件监听 为 SVG 元素添加事件监听器。

javascript
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 动画。

javascript
const circle = document.querySelector('circle'); // 使用 requestAnimationFrame let 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 中的相对位置。

javascript
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 元素的拖拽。

javascript
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 图形。

javascript
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 创建数据可视化。

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)处理复杂场景
  • 测试跨浏览器兼容性
标签:SVG