การวาดไฟล์ SVG บนผ้าใบ HTML5


131

มีวิธีเริ่มต้นในการวาดไฟล์ SVG ลงบนผืนผ้าใบ HTML5 หรือไม่ Google Chrome รองรับการโหลด SVG เป็นรูปภาพ (และใช้งานง่าย ๆdrawImage) แต่คอนโซลนักพัฒนาซอฟต์แวร์เตือนสิ่งresource interpreted as image but transferred with MIME type image/svg+xmlนั้น

ฉันรู้ว่ามีความเป็นไปได้ที่จะแปลง SVG เป็นคำสั่ง canvas (เช่นในคำถามนี้ ) แต่ฉันหวังว่าจะไม่จำเป็น ฉันไม่สนใจเบราว์เซอร์รุ่นเก่า (ดังนั้นถ้า FireFox 4 และ IE 9 จะรองรับบางอย่างก็เพียงพอแล้ว)


4
คำถามนี้มีคำตอบพร้อมการสาธิตสด stackoverflow.com/questions/5495952/…
Drew LeSueur

คำตอบ:


122

แก้ไข 16 ธันวาคม 2562

Path2D ได้รับการสนับสนุนโดยเบราว์เซอร์หลักทั้งหมดในขณะนี้

แก้ไข 5 พฤศจิกายน 2557

ตอนนี้คุณสามารถใช้ctx.drawImageการวาด HTMLImageElements ที่มีแหล่งที่มา .svg ในบางส่วน แต่ไม่ทั้งหมดเบราว์เซอร์ Chrome, IE11 และ Safari ทำงานได้ Firefox ทำงานกับข้อบกพร่องบางอย่าง (แต่ทุกคืนได้แก้ไขแล้ว)

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";

ตัวอย่างที่อาศัยอยู่ที่นี่ คุณควรเห็นสี่เหลี่ยมสีเขียวในผืนผ้าใบ สี่เหลี่ยมสีเขียวที่สองบนหน้าเป็น<svg>องค์ประกอบเดียวกันที่แทรกใน DOM สำหรับการอ้างอิง

คุณยังสามารถใช้ออบเจ็กต์ Path2D ใหม่เพื่อวาดเส้นทาง SVG (สตริง) กล่าวอีกนัยหนึ่งคุณสามารถเขียน:

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

ตัวอย่างสดของที่นี่


คำตอบรุ่นหลังเก่า:

ไม่มีอะไรในตัวที่ช่วยให้คุณใช้เส้นทาง SVG ในพื้นที่ทำงานได้ คุณต้องแปลงตัวเองหรือใช้ห้องสมุดเพื่อทำเพื่อคุณ

ฉันขอแนะนำให้ดูที่ canvg:

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

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


4
เหตุใดจึงจำเป็น SVG ดูเหมือนจะวาดได้อย่างสมบูรณ์แบบบนผืนผ้าใบเพียงแค่drawImage. แต่ฉันยังคงได้รับคำเตือนนั้น มันมาจากไหน?
shoosh

1
Simon สิ่งที่คุณพูดไม่ถูกต้อง และประการที่สองเป็นข้อบกพร่องที่ได้รับการยืนยันแล้วใน Chrome
Mathias Lykkegaard Lorenzen

4
Wikimedia ไม่ชอบให้คุณใช้ SVG ฉันเปลี่ยนsnapsvg.io/assets/images/logo.svgเป็น SVG ที่มีอยู่ตัวแรกที่ฉันพบ ทำงานใน FF. jsfiddle.net/Na6X5/331
Thomas

1
คุณยังสามารถใช้Data URIเพื่อทำสิ่งนี้ได้: jsfiddle.net/020k543w
Swivel

9
หมายเหตุ: เนื่องจาก FireFox Bug เป็นเวลานานน่าเศร้าที่ svgs ที่ไม่มีแท็กความกว้างและความสูงจะไม่แสดงผลเลยบนผืนผ้าใบ นอกจากนี้ความกว้างและความสูงต้องไม่เป็นเปอร์เซ็นต์
Hatoru Hansou

26

ขออภัยฉันมีชื่อเสียงไม่เพียงพอที่จะแสดงความคิดเห็นเกี่ยวกับคำตอบของ @Matyas แต่หากภาพของ svg อยู่ใน base64 ด้วยเช่นกันภาพนั้นจะถูกดึงไปที่ผลลัพธ์

การสาธิต:

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
สิ่งเดียวกันกับแบบอักษรพวกเขาต้องฝังใน SVG: jsfiddle.net/ykx7kp8L/121
Sphinxxx

1
คุณอาจสามารถวนซ้ำimgแท็กในแท็กsvgและวาดภาพบนผืนผ้าใบแยกกันได้ในภายหลัง
luckydonald

24

คุณสามารถวาดภาพง่ายๆsvgลงบนผืนผ้าใบได้อย่างง่ายดายโดย:

  1. การกำหนดแหล่งที่มาของ svg ให้กับรูปภาพในรูปแบบ base64
  2. วาดภาพลงบนผืนผ้าใบ

หมายเหตุ:ข้อเสียเปรียบเพียงประการเดียวของวิธีนี้คือไม่สามารถวาดภาพที่ฝังอยู่ในไฟล์svg. (ดูการสาธิต)

สาธิต:

(โปรดทราบว่าภาพที่ฝังจะมองเห็นได้เฉพาะใน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
มีวิธีใดในการแก้ไขปัญหาที่คุณกล่าวถึง รูปภาพที่ฝังอยู่ใน svg
Vijay Baskaran

ขออภัยฉันไม่พบวิธีแก้ปัญหาภาพฝังตัว
Matyas

ตกลง. ขอบคุณ Matyas :)
Vijay Baskaran

6

Mozilla มีวิธีง่ายๆในการวาด SVG บนผืนผ้าใบที่เรียกว่า "การวาดวัตถุ DOM ลงในผืนผ้าใบ "


สิ่งนี้มีข้อเสียเปรียบเช่นเดียวกับวิธีแรกของ @ Simon: ไม่ทำงานใน Firefox, Chrome OK
amergin

3
ลิงก์ของคุณใช้ไม่ได้อีกต่อไป ฉันยังสนใจ Mozilla way
Alirezak

6

ดังที่ Simon กล่าวไว้ข้างต้นการใช้ drawImage ไม่ควรได้ผล แต่ใช้ไลบรารีcanvgและ:

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

สิ่งนี้มาจากลิงค์ที่ Simon ให้ไว้ด้านบนซึ่งมีคำแนะนำอื่น ๆ อีกมากมายและชี้ให้เห็นว่าคุณต้องการเชื่อมโยงหรือดาวน์โหลด canvg.js และ rgbcolor.js สิ่งเหล่านี้ช่วยให้คุณจัดการและโหลด SVG ไม่ว่าจะผ่าน URL หรือใช้โค้ด SVG แบบอินไลน์ระหว่างแท็ก svg ภายในฟังก์ชัน JavaScript

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.