Vẽ tệp SVG trên khung vẽ HTML5


130

Có cách nào để vẽ tệp SVG mặc định trên khung vẽ HTML5 không? Google Chrome hỗ trợ tải SVG dưới dạng hình ảnh (và chỉ cần sử dụng drawImage), nhưng bảng điều khiển dành cho nhà phát triển đã cảnh báo điều đó resource interpreted as image but transferred with MIME type image/svg+xml.

Tôi biết rằng một khả năng sẽ là chuyển đổi SVG thành các lệnh canvas (như trong câu hỏi này ), nhưng tôi hy vọng điều đó không cần thiết. Tôi không quan tâm đến các trình duyệt cũ hơn (vì vậy nếu FireFox 4 và IE 9 sẽ hỗ trợ một cái gì đó, thì đủ tốt rồi).


4
Câu hỏi này có câu trả lời với một bản demo stackoverflow.com/questions/5495952/
Drew LeSueur

Câu trả lời:


121

EDIT ngày 16 tháng 12 năm 2019

Path2D được hỗ trợ bởi tất cả các trình duyệt chính hiện nay

EDIT ngày 5 tháng 11 năm 2014

Bây giờ bạn có thể sử dụng ctx.drawImageđể vẽ HTMLImageElements có nguồn .svg trong một số nhưng không phải tất cả các trình duyệt . Chrome, IE11 và Safari hoạt động, Firefox hoạt động với một số lỗi (nhưng hàng đêm đã sửa chúng).

var img = new Image();
img.onload = function() {
    ctx.drawImage(img, 0, 0);
}
img.src = "http://upload.wikimedia.org/wikipedia/commons/d/d2/Svg_example_square.svg";

Sống ví dụ ở đây . Bạn sẽ thấy một hình vuông màu xanh lá cây trong khung vẽ. Hình vuông màu xanh lá cây thứ hai trên trang là cùng một <svg>phần tử được chèn vào DOM để tham khảo.

Bạn cũng có thể sử dụng các đối tượng Path2D mới để vẽ các đường dẫn SVG (chuỗi). Nói cách khác, bạn có thể viết:

var path = new Path2D('M 100,100 h 50 v 50 h 50');
ctx.stroke(path);

Ví dụ trực tiếp về điều đó ở đây.


Câu trả lời của hậu thế cũ:

Không có gì riêng cho phép bạn sử dụng các đường dẫn SVG trong canvas. Bạn phải tự chuyển đổi hoặc sử dụng thư viện để làm điều đó cho bạn.

Tôi khuyên bạn nên tìm đến canvg:

http://code.google.com.vn/p/canvg/

http://canvg.googlecode.com/svn/trunk/examples/index.htm


4
Tại sao điều này là cần thiết? SVG dường như vẽ hoàn hảo trên một canvase chỉ với drawImage. Nhưng tôi vẫn nhận được cảnh báo đó. Nó đến từ đâu?
shoosh

1
Simon, những gì bạn đang nói là không chính xác. Và thứ hai, đó là một lỗi đã được xác nhận trong Chrome.
Mathias Lykkegaard Lorenzen

4
Wikimedia dường như không thích bạn sử dụng SVG. Tôi đã trao đổi trong snapsvg.io/assets/images/logo.svg như là SVG có sẵn đầu tiên tôi tìm thấy. Làm việc trong FF. jsfiddle.net/Na6X5/331
Thomas

1
Bạn cũng có thể sử dụng Data URI để thực hiện việc này: jsfiddle.net/020k543w
Xoay

9
Lưu ý: do lỗi FireFox tồn tại lâu, đáng buồn thay, các Svss thiếu thẻ chiều rộng và chiều cao sẽ không hiển thị trên khung vẽ. Ngoài ra, chiều rộng và chiều cao không được tính theo tỷ lệ phần trăm.
Hatoru Hansou

26

Xin lỗi, tôi không có đủ danh tiếng để nhận xét về câu trả lời @Matyas, nhưng nếu hình ảnh của Svg cũng ở cơ sở64, nó sẽ bị thu hút vào đầu ra.

Bản giới thiệu:

var svg = document.querySelector('svg');
var img = document.querySelector('img');
var canvas = document.querySelector('canvas');

// get svg data
var xml = new XMLSerializer().serializeToString(svg);

// make it base64
var svg64 = btoa(xml);
var b64Start = 'data:image/svg+xml;base64,';

// prepend a "header"
var image64 = b64Start + svg64;

// set it as the source of the img element
img.onload = function() {
    // draw the image onto the canvas
    canvas.getContext('2d').drawImage(img, 0, 0);
}
img.src = image64;
svg, img, canvas {
  display: block;
}
SVG

<svg height="40">
  <rect width="40" height="40" style="fill:rgb(255,0,255);" />
  <image xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAEX0lEQVQ4jUWUyW6cVRCFv7r3/kO3u912nNgZgESAAgGBCJgFgxhW7FkgxAbxMLwBEmIRITbsQAgxCEUiSIBAYIY4g1EmYjuDp457+Lv7n+4tFjbwAHVOnVPnlLz75ht67OhhZg/M0p6d5tD9C8SNBBs5XBJhI4uNLC4SREA0UI9yJr2c4e6QO+v3WF27w+rmNrv9Pm7hxDyHFg5yYGEOYxytuRY2SYiSCIwgRgBQIxgjEAKuZWg6R9S0SCS4qKLZElY3HC5tp7QPtmlMN7HOETUTXBJjrEGsAfgPFECsQbBIbDGJZUYgGE8ugQyPm+o0STtTuGZMnKZEjRjjLIgAirEOEQEBDQFBEFFEBWLFtVJmpENRl6hUuFanTRAlbTeZarcx0R6YNZagAdD/t5N9+QgCYAw2jrAhpjM3zaSY4OJGTDrVwEYOYw2qioigoviq5MqF31m9fg1V5fCx+zn11CLNVnufRhBrsVFE1Ihpthu4KDYYwz5YQIxFBG7duMZnH31IqHL6wwnGCLFd4pez3/DaG2/x4GNPgBhEZG/GGlxkMVFkiNMYay3Inqxed4eP33uf7Y0uu90xWkGolFAru7sZn5w5w921m3u+su8vinEO02hEWLN/ANnL2rkvv2an2yd4SCKLM0JVBsCgAYZZzrnPP0eDRzXgfaCuPHXwuEYjRgmIBlQVVLl8/hKI4fRzz3L6uWe5+PMvnHz6aa4uX+D4yYe5vXaLH86eoyoLjLF476l9oKo9pi5HWONRX8E+YznOef7Vl1h86QWurlwjbc+QpikPPfoIcZLS39pmMikp8pzae6q6oqgriqrGqS+xeLScoMYSVJlfOMTl5RXW1+5w5fJVnFGWf1/mxEMnWPppiclkTLM5RdJoUBYFZVlQ5DnZMMMV167gixKLoXXsKGqnOHnqOJ/+/CfZ+XUiZ0jTmFv5mAvf/YjEliQ2vPD8Ir6qqEcZkzt38cMRo5WruFvfL9FqpyRxQhj0qLOax5I2S08+Tu/lFiGUGOPormxwuyfMnjrGrJa88uIixeYWl776lmrzNjmw8vcG8sU7ixpHMXFsCUVg9tABjEvRgzP82j7AhbyiX5Qcv2+Bvy7dYGZ1k7efeQB/Y4PBqGBtdYvb3SFzLcfqToZc/OB1zYeBSpUwLBlvjZidmWaSB1yaYOfn6LqI/r0hyU6P+cRSlhXjbEI2zvnt7y79oqQ3qeg4g6vKjCIXehtDmi6m0UnxVnCRkPUHVNt9qkLJxgXOCYNOg34v48raPaamU2o89/KKsQ9sTSpc0JK7NwdcX8s43Ek5cnSOLC/Z2R6Rj0ra0w2W1/t0xyWn51uk2Ri1QtSO6OU5d7OSi72cQeWxKG7p/Dp//JXTy6C1Pcbc6DMpPRtjTxChEznWhwVZUCKrjCrPoPDczHLmnLBdBgZlRRWUEBR3ZKrme5TlrTGlV440Y1IrXM9qQGi6mkG5V6uza7tUIeCDElTZ1L26elX+fcH/ACJBPYTJ4X8tAAAAAElFTkSuQmCC" height="20px" width="20px" x="10" y="10"></image>
</svg>
<hr/><br/>

IMAGE
<img/>
<hr/><br/>
   
CANVAS
<canvas></canvas>
<hr/><br/>


1
Điều tương tự với phông chữ, chúng cần được nhúng trong SVG: jsfiddle.net/ykx7kp8L/121
Sphinxxx

1
bạn có thể lặp lại qua các imgthẻ trong svgvà chỉ cần vẽ hình ảnh trên khung vẽ một cách riêng biệt sau đó.
luckydonald

24

Bạn có thể dễ dàng vẽ svgs đơn giản lên một khung vẽ bằng cách:

  1. Gán nguồn của Svg cho một hình ảnh ở định dạng base64
  2. Vẽ hình ảnh lên một bức tranh

Lưu ý: Hạn chế duy nhất của phương thức là nó không thể vẽ hình ảnh được nhúng trong svg. (xem bản demo)

Trình diễn:

(Lưu ý rằng hình ảnh nhúng chỉ hiển thị trong svg)

var svg = document.querySelector('svg');
var img = document.querySelector('img');
var canvas = document.querySelector('canvas');

// get svg data
var xml = new XMLSerializer().serializeToString(svg);

// make it base64
var svg64 = btoa(xml);
var b64Start = 'data:image/svg+xml;base64,';

// prepend a "header"
var image64 = b64Start + svg64;

// set it as the source of the img element
img.src = image64;

// draw the image onto the canvas
canvas.getContext('2d').drawImage(img, 0, 0);
svg, img, canvas {
  display: block;
}
SVG

<svg height="40">
  <rect width="40" height="40" style="fill:rgb(255,0,255);" />
  <image xlink:href="https://en.gravatar.com/userimage/16084558/1a38852cf33713b48da096c8dc72c338.png?size=20" height="20px" width="20px" x="10" y="10"></image>
</svg>
<hr/><br/>

IMAGE
<img/>
<hr/><br/>
   
CANVAS
<canvas></canvas>
<hr/><br/>


2
Có cách nào để khắc phục vấn đề mà bạn đề cập. Hình ảnh được nhúng trong svg.
Vijay Baskaran

Xin lỗi, nhưng tôi chưa tìm thấy giải pháp cho vấn đề hình ảnh nhúng.
Matyas

Được chứ. Cảm ơn Matyas :)
Vijay Baskaran

6

Mozilla có một cách đơn giản để vẽ SVG trên canvas có tên là " Vẽ các đối tượng DOM vào khung vẽ "


Điều này có nhược điểm giống như trong phương pháp đầu tiên của @ Simon: không hoạt động trong Firefox, Chrome OK.
amergin

3
Liên kết của bạn không hoạt động nữa. Tôi vẫn quan tâm đến cách Mozilla
Alirezak

6

Như Simon đã nói ở trên, sử dụng drawImage không nên hoạt động. Nhưng, sử dụng thư viện canvg và:

var c = document.getElementById('canvas');
var ctx = c.getContext('2d');
ctx.drawSvg(SVG_XML_OR_PATH_TO_SVG, dx, dy, dw, dh);

Điều này xuất phát từ liên kết mà Simon cung cấp ở trên, có một số gợi ý khác và chỉ ra rằng bạn muốn liên kết đến hoặc tải xuống canvg.js và rgbcolor.js. Những thứ này cho phép bạn thao tác và tải một SVG, thông qua URL hoặc sử dụng mã SVG nội tuyến giữa các thẻ svg, trong các hàm JavaScript.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.