Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/418.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 尝试在画布中创建新图像时未触发image onload。为什么?_Javascript_Jquery_Canvas_Svg_Todataurl - Fatal编程技术网

Javascript 尝试在画布中创建新图像时未触发image onload。为什么?

Javascript 尝试在画布中创建新图像时未触发image onload。为什么?,javascript,jquery,canvas,svg,todataurl,Javascript,Jquery,Canvas,Svg,Todataurl,我想抓取一个svg并将其保存为png(来自一个创建svg的图表插件),我想我已经找到了实现这一点的方法 我一直在寻找onload函数不启动的原因,但仍然不明白下面的代码为什么不起作用。“你好”未显示。它可能非常简单,但我现在无法看到它 jQuery(function ($) { var svg = $("#visualizer-152").find('svg'); var imgsrc = 'data:image/svg+xml;base64,'+ btoa(svg);

我想抓取一个svg并将其保存为png(来自一个创建svg的图表插件),我想我已经找到了实现这一点的方法

我一直在寻找onload函数不启动的原因,但仍然不明白下面的代码为什么不起作用。“你好”未显示。它可能非常简单,但我现在无法看到它

jQuery(function ($) {   

    var svg = $("#visualizer-152").find('svg');
    var imgsrc = 'data:image/svg+xml;base64,'+ btoa(svg);
    var canvas = document.createElement("canvas");
    var context = canvas.getContext("2d");

    drawing = new Image();
    //All above seems to work, no errors in console and objects
    //seems to be created correctly

    drawing.onload = function () {
        alert('hello');
        context.drawImage(drawing,0,0);
        var base64 = canvas.toDataURL('image/png', 1);
    };

    drawing.src = imgsrc;
});
更新

将onload更改为,它似乎可以工作

$( drawing ).load( "", function() {
    context.drawImage(drawing,0,0);
    var base64 = canvas.toDataURL('image/png', 1);
    console.log('base64');
   console.log(base64);
});
但现在又出现了另一个问题,我发现了这个错误:

未捕获的InvalidStateError:无法在上执行“drawImage” “CanvasRenderingContext2D”:提供的HTMLImageElement位于 “破碎”状态

更新2 如果我尝试单击控制台中生成的数据字符串:

var imgsrc = 'data:image/svg+xml;base64,'+ btoa(svg);
console.log(imgsrc);
我在控制台中获得以下字符串:

data:image/svg+xml;base64,W29iamVjdCBPYmplY3Rd
浏览器中出现此错误:

此页面包含以下错误:

第1列第1行错误:下面的文档为空,这是第一个错误之前的页面呈现

更新3: 我开始意识到实际的问题,是我无法正确地获取源代码。我测试了手动将源代码设置为指向特定文件,然后它就工作了。通过查看生成的svg内容。。。(部分)

还有来自fiddle的html。。(开始)



但在我的例子中,它不起作用,因为html看起来不一样,svg没有id。我曾尝试向svg添加id,尝试向svg添加类,但没有成功。我还尝试在jQuery中使用wrap()函数创建包装器,但没有成功:

这里是您在fiddle中开始的一个变体,它似乎对我有用。这里缺少的是,您必须调整画布大小以匹配您的图像,但您得到了这个想法

var container = document.getElementById('container');
var svgText   = document.getElementById("myViewer").outerHTML;
var myCanvas  = document.getElementById("canvas");
var ctxt      = myCanvas.getContext("2d");
var DOMURL    = window.URL || window.webkitURL || window;

var svg = new Blob([svgText], {type: 'image/svg+xml;charset=utf-8'});
var url = DOMURL.createObjectURL(svg);

var img = new Image();
    img.onload = createPNG;
    img.src = url;

function createPNG() {
  ctxt.drawImage(img, 0, 0);
  var canvasData = myCanvas.toDataURL('image/png');
  // For the download button you can use one you have on your HTML
  // or create one like this. Notice the download attribute where you can name your file.
  // https://developer.mozilla.org/en/docs/Web/HTML/Element/a#Using_the_download_attribute_to_save_a_canvas_as_a_PNG
  var saveBtn = document.createElement('a');
      saveBtn.href = canvasData;
      saveBtn.textContent = 'Download PNG';
      saveBtn.download = 'FILENAME.png';
  DOMURL.revokeObjectURL(url);
  container.appendChild(saveBtn);
}
编辑: 要选择没有ID的svg,可以使用
querySelector
查询任何特定元素。尝试将前两行替换为以下内容:

var container = document.getElementById('visualizer-152');
var svgText = container.querySelector('svg').outerHTML;

querySelector()
将只返回它找到的第一个
svg
元素。如果您有多个SVG,可以使用
querySelectorAll()
,它将返回所有
SVG
元素的数组。

base64-不是什么东西,浏览器需要加载。它已加载。这就是为什么你没有被解雇的原因。@primetwig-那没有意义?我已经更新了问题。您需要等待svg加载(如果是文件)。至于现在,您正试图在源代码尚未加载的情况下创建base64。@primetwig svg是基于jQuery加载的(函数($){…因为加载了dom?还是说我必须执行一些onload svg函数?svg是创建的,我可以通过var svg=$(“#visualizer-152”)访问它。find('svg'));如果您在新窗口中打开
var imgsrc='data:image/svg+xml;base64,+btoa(svg);
的结果,您是否真的看到了图像?您的其余代码很好,因此我怀疑图像数据已损坏。那么容器和myViewer应该是什么?(基于我在update3中编写的可视化工具插件生成的html)容器不会影响图像的创建(获取SVG或生成PNG),因此它可以是HTML中要放置下载按钮的任何元素。它可以是
var container=document.getElementById('visualizer-152')
甚至只是你的body标签
var container=document.body;
我理解你的意思。我将容器设置为visualizer-152元素的包装器。但困难的部分是用什么替换myViewer?因为在fiddle myViewer中,myViewer指的是实际的SVG,但在生成的html中,没有SVG元素的id。看看是否我的编辑很有帮助。原则上,在HTML中获取元素应该不难,尤其是现在我们可以在JS中本机使用。我尝试了您的编辑,在尝试获取outerHTML:Uncaught TypeError:Cannot read属性'outerHTML'为null时出现了此错误。我还尝试了var svgText=container.querySelector('svg')[0].outerHTML;然后出现错误:未捕获的TypeError:无法读取null的属性“0”
<div id="container" width=500px height=400px>
    <svg class="svg-editor" 
    id="myViewer" 
    width="1400" 
    height="1400" 
    xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" 
    style="overflow:scroll;margin:0;">
var container = document.getElementById('container');
var svgText   = document.getElementById("myViewer").outerHTML;
var myCanvas  = document.getElementById("canvas");
var ctxt      = myCanvas.getContext("2d");
var DOMURL    = window.URL || window.webkitURL || window;

var svg = new Blob([svgText], {type: 'image/svg+xml;charset=utf-8'});
var url = DOMURL.createObjectURL(svg);

var img = new Image();
    img.onload = createPNG;
    img.src = url;

function createPNG() {
  ctxt.drawImage(img, 0, 0);
  var canvasData = myCanvas.toDataURL('image/png');
  // For the download button you can use one you have on your HTML
  // or create one like this. Notice the download attribute where you can name your file.
  // https://developer.mozilla.org/en/docs/Web/HTML/Element/a#Using_the_download_attribute_to_save_a_canvas_as_a_PNG
  var saveBtn = document.createElement('a');
      saveBtn.href = canvasData;
      saveBtn.textContent = 'Download PNG';
      saveBtn.download = 'FILENAME.png';
  DOMURL.revokeObjectURL(url);
  container.appendChild(saveBtn);
}
var container = document.getElementById('visualizer-152');
var svgText = container.querySelector('svg').outerHTML;