[英]Modify Canvas SVG Image with Javascript
我有一張 svg 圖像,可以用來繪制到 canvas:
image = new Image()
image.src = "image.svg"
是否可以修改image
,例如,更改元素的顏色?
您可以使用提取 function 而不是將 SVG 直接加載到圖像元素中。這里的數據 URL 僅用於示例——它可以被 URL 替換。此時您可以將 SVG 存儲在變量中。
要更改 SVG ,一種方法是使用XPath 。 這就是 function changeAttribute() 中發生的情況,它采用 SVG、XPath 表達式和包含有關更改內容的數據的 object。
當我閱讀您的問題時,您已經明白了這一點。 在 function insertIntoCanvas() 中,使用FileReader將 SVG(XML 文檔)轉換為數據 URL。 之后創建圖像並在 canvas 上繪制。
const canvas = document.getElementById('canvas'); const ctx = canvas.getContext('2d'); fetch('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMTAgMTAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgPHBhdGggZD0iTSA1IDAgTCAwIDUgTCA1IDEwIEwgMTAgNSBaIiAvPgo8L3N2Zz4=').then(response => response.text()).then(text => { let xmlDoc = new DOMParser().parseFromString(text,'text/xml'); changeAttribute(xmlDoc, '//svg:path', {fill:'red'}); changeAttribute(xmlDoc, '//svg:svg', {width:100, height:100}); insertIntoCanvas(xmlDoc); }); function insertIntoCanvas(xmlDoc){ let file = new File([xmlDoc.rootElement.outerHTML], 'svg.svg', { type: "image/svg+xml" }); // and a reader let reader = new FileReader(); reader.addEventListener('load', e => { /* create a new image assign the result of the filereader to the image src */ let img = new Image(); // wait for it to got load img.addEventListener('load', e => { // update canvas with new image ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.drawImage(e.target, 0, 0); }); img.src = e.target.result; }); // read the file as a data URL reader.readAsDataURL(file); } function changeAttribute(doc, xpath, obj) { let r = doc.evaluate(xpath, doc, nsResolver, XPathResult.ANY_TYPE, null); let nodes = []; let next = r.iterateNext(); while (next) { nodes.push(next); next = r.iterateNext(); } nodes.forEach(node => { Object.keys(obj).forEach(key => { node.setAttribute(key, obj[key]); }); }); } function nsResolver(prefix) { const ns = { 'xhtml': 'http://www.w3.org/1999/xhtml', 'svg': 'http://www.w3.org/2000/svg' }; return ns[prefix] || null; }
canvas { border: thin solid black; }
<canvas id="canvas" width="300" height="200"></canvas>
你必須:
<style>
元素outerHTML
<canvas>
canvas.img
為 XML DataURI<canvas>
添加到 shadowDOMreplaceWith
組件所有現代瀏覽器都支持的原生 JavaScript Web 組件<svg-to-canvas>
,
它能為你做所有事情嗎,所以你只寫:
<svg-to-canvas src="//load-file.github.io/heart.svg">
<style>
svg { background:green }
path { fill:red }
</style>
</svg-to-canvas>
<style> svg-to-canvas { background: lightgreen } canvas { background:pink } </style> <svg-to-canvas src="//load-file.github.io/heart.svg"> <style> svg { background:green } path { fill:red } </style> </svg-to-canvas> <svg-to-canvas replaceWith src="//load-file.github.io/heart.svg"></svg-to-canvas> <script> customElements.define("svg-to-canvas", class extends HTMLElement { async connectedCallback(svg,canvas,img) { this.style.display = "inline-block"; this.attachShadow({mode:"open"}).innerHTML = await (await fetch(this.getAttribute("src"))).text(); svg = this.shadowRoot.querySelector("svg"); svg.append(...this.querySelectorAll("*")); // stop here for an SVG inside shadowDOM canvas = document.createElement('canvas'); img = Object.assign(new Image(), { onload: () => { canvas.width = img.width; canvas.height = img.height; canvas.getContext('2d').drawImage(img, 0, 0); }, src: "data:image/svg+xml;utf8," + svg.outerHTML.replace(/"/g, "'").replace(/#/g, "%23") }); if (this.hasAttribute("replaceWith")) this.replaceWith(canvas); else { svg.remove(); this.shadowRoot.append(canvas) } } }) </script>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.