我的網站上有一個互動式繪圖應用程式,我想創建一個按鈕,以便人們可以在 FB 上分享他們的繪圖。
我正在嘗試將 SVG 元素轉換為 blob,然后將其傳遞給 og:image,但我在轉換時遇到了一些問題。
我有兩個試驗:一個由于某種原因沒有觸發 onl oad 功能。另一個回傳一個空的 blob
然而,這兩項試驗在 jsfiddle 上都運行良好。
第一次嘗試
var xmlSerializer = new XMLSerializer();
var svgString = xmlSerializer.serializeToString(document.querySelector("#svg"));
var canvas = document.createElement("canvas");
var bounds = {
width: 1040,
height: 487
};
canvas.width = bounds.width;
canvas.height = bounds.height;
var ctx = canvas.getContext("2d");
var DOMURL = self.URL || self.webkitURL || self;
var img = new Image();
var svg = new Blob([svgString], {
type: "image/svg xml;charset=utf-8"
});
var url = DOMURL.createObjectURL(svg);
img.onload = function() {
ctx.drawImage(img, 0, 0);
var png = canvas.toDataURL("image/png");
var mg = document.createElement("img");
mg.setAttribute("src", png);
document.body.appendChild(mg);
DOMURL.revokeObjectURL(png);
};
img.id = "testimg";
img.setAttribute("src", url);
第二次嘗試
var svgString = new XMLSerializer().serializeToString(document.querySelector("svg"));
var canvas = document.createElement('CANVAS');
var ctx = canvas.getContext("2d");
var DOMURL = self.URL || sel.webkitURL || self;
var img = new Image();
var svg = new Blob([svgString], {
type: "image/svg xml;charset=utf-8"
});
var url = DOMURL.createObjectURL(svg);
img.onload = function() {
ctx.drawImage(img, 0, 0);
var png = canvas.toDataURL("image/png");
var container = document.createElement('DIV');
container.innerHTML = '<img src="' png '"/>';
DOMURL.revokeObjectURL(png);
};
img.src = url;
document.body.appendChild(img);
這是由兩個按鈕“test1”和“test2”觸發的兩次嘗試的應用程式
uj5u.com熱心網友回復:
問題在于您定義xmlns:xlink屬性的方式。
目前從你的頁面做document.querySelector("use").attributes.getNamedItem("xmlns:xlink").namespaceURI將回傳null。這意味著該屬性已在 Document 的命名空間 (HTML) 中定義,因此當您使用 XMLSerializer 對其進行字串化時,您xmlns:xlink的元素實際上將擁有兩個屬性,一個在 HTML 命名空間中,另一個是隱含的 SVG在嵌入 HTML 檔案的 SVG 中。
在 SVG 中的同一個元素上具有兩個相同的屬性是無效的,因此您的檔案無效并且影像不會加載。
如果您遇到此問題,那肯定是因為您確實通過 JavaScript 設定了此屬性:
const newUse = document.createElementNS("http://www.w3.org/2000/svg", "use");
newUse.setAttribute("xmlns:xlink", "http://www.w3.org/1999/xlink");
newUse.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", "#foo");
document.querySelector("svg").append(newUse);
console.log("set from markup:", document.querySelector("use").attributes.getNamedItem("xmlns:xlink").namespaceURI);
console.log("(badly) set from JS:", document.querySelector("use use").attributes.getNamedItem("xmlns:xlink").namespaceURI);
// the last <use> has two xmlns:xlink attributes
console.log("serialization:", new XMLSerializer().serializeToString(document.querySelector("svg")));
<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30">
<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#foo"/>
</svg>
要正確設定它,您需要使用setAttributeNS()并使用 XMLNS 命名空間:
const newUse = document.createElementNS("http://www.w3.org/2000/svg", "use");
document.querySelector("svg").append(newUse);
// beware the last "/"
newUse.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink");
console.log("set from markup", document.querySelector("use").attributes.getNamedItem("xmlns:xlink").namespaceURI);
console.log("(correctly) set from JS", document.querySelector("use use").attributes.getNamedItem("xmlns:xlink").namespaceURI);
<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30">
<use xmlns:xlink="http://www.w3.org/1999/xlink"/>
</svg>
但是最好不要設定所有這些屬性。
正如我上面所說,嵌入在 HTML 中的 SVG 會自動定義正確的 xmlns 和 xlink 命名空間,而無需屬性。并且由于您是通過 JS 創建元素,因此您也已經在正確的命名空間中定義了它們。
所以不要理會這些屬性:
const SVGNS = "http://www.w3.org/2000/svg";
const svg = document.createElementNS(SVGNS, "svg");
// To be able to draw an SVG image on a canvas in Firefox
// you must set absolute width and height to the root svg node
svg.setAttribute("width", 50);
svg.setAttribute("height", 50);
const target = document.createElementNS(SVGNS, "symbol");
target.id = "target";
const rect = document.createElementNS(SVGNS, "rect");
rect.setAttribute("width", 50);
rect.setAttribute("height", 50);
rect.setAttribute("fill", "green");
const use = document.createElementNS(SVGNS, "use");
// since SVG2 we don't even need to set href in the xlink NS
use.setAttribute("href", "#target");
target.append(rect);
svg.append(target, use);
const svgString = new XMLSerializer().serializeToString(svg);
console.log(svgString); // contains all the NS attributes
const blob = new Blob([svgString], { type: "image/svg xml" });
const img = new Image();
img.src = URL.createObjectURL(blob);
document.body.append(img);
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/377362.html
標籤:javascript html svg 斑点
上一篇:為整個頁面分配一個圖案,但僅在某些形狀上顯示它,其余的應該是黑色的
下一篇:如何在異步中獲取最新資料?
