如何在 svg 到 canvas 转换完成后立即 post?
How to post immediately after svg to canvas conversion is done?
在将 html 元素中的所有 svg 转换为 canvas 之后,我尝试使用 html2canvas post,但是 post 在 svg 到 canvas 转换完成之前立即执行,因为它需要几秒钟。我已经尝试使用 deferred 和 promises,但我仍然遇到同样的问题。
// https://github.com/niklasvh/html2canvas/issues/95#issuecomment-45114424
// First render all SVGs to canvases
targetElem = $('#dashboard');
var elements = targetElem.find('svg').map(function() {
var svg = $(this);
var canvas = $('<canvas></canvas>');
svg.replaceWith(canvas);
// Get the raw SVG string and curate it
var content = svg.wrap('<p></p>').parent().html();
content = content.replace(/xlink:title='hide\/show'/g, '');
content = encodeURIComponent(content);
svg.unwrap();
// Create an image from the svg
var image = new Image();
image.src = 'data:image/svg+xml,' + content;
image.onload = function() {
canvas[0].width = image.width;
canvas[0].height = image.height;
// Render the image to the canvas
var context = canvas[0].getContext('2d');
context.drawImage(image, 0, 0);
};
return {
svg: svg,
canvas: canvas
};
}); // end of targetElem.find('svg').map(function() {...});
已编辑:这是我一直试图实现的延迟和承诺,以创建两个按顺序 运行 的操作。
$(document).ready(function() {
$( '#save_dashboard' ).click(function() {
// Create a deferred object
var dfd = $.Deferred();
// https://github.com/niklasvh/html2canvas/issues/95#issuecomment-45114424
// First render all SVGs to canvases
targetElem = $('#dashboard');
var elements = targetElem.find('svg').map(function() {
var svg = $(this);
var canvas = $('<canvas></canvas>');
svg.replaceWith(canvas);
// Get the raw SVG string and curate it
var content = svg.wrap('<p></p>').parent().html();
content = content.replace(/xlink:title='hide\/show'/g, '');
content = encodeURIComponent(content);
svg.unwrap();
// Create an image from the svg
var image = new Image();
image.src = 'data:image/svg+xml,' + content;
image.onload = function() {
canvas[0].width = image.width;
canvas[0].height = image.height;
// Render the image to the canvas
var context = canvas[0].getContext('2d');
context.drawImage(image, 0, 0);
};
dfd.resolve();
return dfd.promise();
};
}); // end of targetElem.find('svg').map(function() {...});
dfd.resolve();
$.when(dfd).done(function(){
console.log('dfd done');
// http://www.kubilayerdogan.net/html2canvas-take-screenshot-of-web-page-and-save-it-to-server-javascript-and-php/
$('#dashboard').html2canvas({
onrendered: function (canvas) {
//Set hidden field's value to image data (base-64 string)
var dashboardPng = canvas.toDataURL('image/png');
console.log('dashboardPng: ' + dashboardPng);
$.ajax({
url:'save_dashboard_image.php',
data:{dashboardPngData: dashboardPng},
type:'POST',
dataType:'json',
success: function(){
console.log('success');
}
,
error: function(xhr, status, error){
console.log('The requested page was: ' + document.URL +
'. The error number returned was: ' + xhr.status +
'. The error message was: ' + error);
}
});
}
});
}); // end of $.when(dfd).done(...)
}); // end of save_dashboard click function
}); // end of document ready
已更新
注意,未经测试。将 click
事件调整为 return 多个 canvas
,承诺对象,为 .then()
如果正确解释问题,请尝试
$(document).ready(function() {
$( '#save_dashboard' ).click(function() {
// Create a deferred object
// dfd = new $.Deferred();
// https://github.com/niklasvh/html2canvas/issues/95#issuecomment-45114424
// First render all SVGs to canvases
targetElem = $('#dashboard');
var promises = $.when.apply(targetElem, $.map(targetElem.find('svg')
, function(el, index) {
return new $.Deferred(function(dfd) {
var svg = $(el);
var canvas = $('<canvas></canvas>');
svg.replaceWith(canvas);
// Get the raw SVG string and curate it
var content = svg.wrap('<p></p>').parent().html();
content = content.replace(/xlink:title='hide\/show'/g, '');
content = encodeURIComponent(content);
svg.unwrap();
// Create an image from the svg
var image = new Image();
image.onload = function() {
canvas[0].width = image.width;
canvas[0].height = image.height;
// Render the image to the canvas
var context = canvas[0].getContext('2d');
dfd.resolve(context.drawImage(image, 0, 0));
};
image.src = 'data:image/svg+xml,' + content;
}).promise();
})
); // end of targetElem.find('svg').map(function() {...});
promises.then(function(_canvas) {
console.log('dfd done', _canvas, arguments);
// http://www.kubilayerdogan.net/html2canvas-take-screenshot-of-web-page-and-save-it-to-server-javascript-and-php/
$('#dashboard').html2canvas({
onrendered: function (canvas) {
//Set hidden field's value to image data (base-64 string)
var dashboardPng = canvas.toDataURL('image/png');
console.log('dashboardPng: ' + dashboardPng);
$.ajax({
url:'save_dashboard_image.php',
data:{dashboardPngData: dashboardPng},
type:'POST',
dataType:'json',
success: function(){
console.log('success');
}
,
error: function(xhr, status, error){
console.log('The requested page was: ' + document.URL +
'. The error number returned was: ' + xhr.status +
'. The error message was: ' + error);
}
});
}
});
}); // end of $.when(dfd).done(...)
}); // end of save_dashboard click function
}); // end of document
解决方案 我不得不为每个连续的 svg 到 canvas 转换以及它们全部完成时使用一个数组。我可以将数组传递给 then() 到 post html2canvas.
- 在点击时创建一个新数组,用它来存储所有来自 SVG 的延迟
- 遍历所有 SVG 元素
- 在每个实例中,创建一个新的内部延迟对象
- 解决或拒绝延期
- 将其推入循环外的数组
使用$.when.apply($, arrayOfDeferredObjects)
检查数组中所有延迟对象的状态
$( '#save_dashboard' ).click(function() {
// Declare an array to store all deferred objects from each svg element
var svgDfds = [],
targetElem = $('#dashboard');
targetElem.find('svg').each(function() {
var dfd = new $.Deferred(),
svg = $(this),
canvas = $('<canvas></canvas>');
svg.replaceWith(canvas);
// Get the raw SVG string and curate it
var content = svg.wrap('<p></p>').parent().html();
content = content.replace(/xlink:title='hide\/show'/g, '');
content = encodeURIComponent(content);
svg.unwrap();
// Create an image from the svg
var image = new Image();
image.src = 'data:image/svg+xml,' + content;
image.onload = function() {
canvas[0].width = image.width;
canvas[0].height = image.height;
// Render the image to the canvas
var context = canvas[0].getContext('2d');
// Resolve or reject the deferred
dfd.resolve(context.drawImage(image, 0, 0));
};
// Push deferred object into array
svgDfds.push(dfd);
}); // end of targetElem.find('svg').map(function() {...});
// Check for all deferreds
$.when.apply($, svgDfds).then(function(_canvas) {
console.log('dfd done', _canvas);
// http://www.kubilayerdogan.net/html2canvas-take-screenshot-of-web-page-and-save-it-to-server-javascript-and-php/
$('#dashboard').html2canvas({
onrendered: function (canvas) {
//Set hidden field's value to image data (base-64 string)
var dashboardPng = canvas.toDataURL('image/png');
console.log('dashboardPng: ' + dashboardPng);
$.ajax({
url:'save_dashboard_image.php',
data:{dashboardPngData: dashboardPng},
type:'POST',
dataType:'json',
success: function(){
console.log('success');
}
,
error: function(xhr, status, error){
console.log('The requested page was: ' + document.URL +
'. The error number returned was: ' + xhr.status +
'. The error message was: ' + error);
}
});
}
});
});
}); // end of save_dashboard click function
在将 html 元素中的所有 svg 转换为 canvas 之后,我尝试使用 html2canvas post,但是 post 在 svg 到 canvas 转换完成之前立即执行,因为它需要几秒钟。我已经尝试使用 deferred 和 promises,但我仍然遇到同样的问题。
// https://github.com/niklasvh/html2canvas/issues/95#issuecomment-45114424
// First render all SVGs to canvases
targetElem = $('#dashboard');
var elements = targetElem.find('svg').map(function() {
var svg = $(this);
var canvas = $('<canvas></canvas>');
svg.replaceWith(canvas);
// Get the raw SVG string and curate it
var content = svg.wrap('<p></p>').parent().html();
content = content.replace(/xlink:title='hide\/show'/g, '');
content = encodeURIComponent(content);
svg.unwrap();
// Create an image from the svg
var image = new Image();
image.src = 'data:image/svg+xml,' + content;
image.onload = function() {
canvas[0].width = image.width;
canvas[0].height = image.height;
// Render the image to the canvas
var context = canvas[0].getContext('2d');
context.drawImage(image, 0, 0);
};
return {
svg: svg,
canvas: canvas
};
}); // end of targetElem.find('svg').map(function() {...});
已编辑:这是我一直试图实现的延迟和承诺,以创建两个按顺序 运行 的操作。
$(document).ready(function() {
$( '#save_dashboard' ).click(function() {
// Create a deferred object
var dfd = $.Deferred();
// https://github.com/niklasvh/html2canvas/issues/95#issuecomment-45114424
// First render all SVGs to canvases
targetElem = $('#dashboard');
var elements = targetElem.find('svg').map(function() {
var svg = $(this);
var canvas = $('<canvas></canvas>');
svg.replaceWith(canvas);
// Get the raw SVG string and curate it
var content = svg.wrap('<p></p>').parent().html();
content = content.replace(/xlink:title='hide\/show'/g, '');
content = encodeURIComponent(content);
svg.unwrap();
// Create an image from the svg
var image = new Image();
image.src = 'data:image/svg+xml,' + content;
image.onload = function() {
canvas[0].width = image.width;
canvas[0].height = image.height;
// Render the image to the canvas
var context = canvas[0].getContext('2d');
context.drawImage(image, 0, 0);
};
dfd.resolve();
return dfd.promise();
};
}); // end of targetElem.find('svg').map(function() {...});
dfd.resolve();
$.when(dfd).done(function(){
console.log('dfd done');
// http://www.kubilayerdogan.net/html2canvas-take-screenshot-of-web-page-and-save-it-to-server-javascript-and-php/
$('#dashboard').html2canvas({
onrendered: function (canvas) {
//Set hidden field's value to image data (base-64 string)
var dashboardPng = canvas.toDataURL('image/png');
console.log('dashboardPng: ' + dashboardPng);
$.ajax({
url:'save_dashboard_image.php',
data:{dashboardPngData: dashboardPng},
type:'POST',
dataType:'json',
success: function(){
console.log('success');
}
,
error: function(xhr, status, error){
console.log('The requested page was: ' + document.URL +
'. The error number returned was: ' + xhr.status +
'. The error message was: ' + error);
}
});
}
});
}); // end of $.when(dfd).done(...)
}); // end of save_dashboard click function
}); // end of document ready
已更新
注意,未经测试。将 click
事件调整为 return 多个 canvas
,承诺对象,为 .then()
如果正确解释问题,请尝试
$(document).ready(function() {
$( '#save_dashboard' ).click(function() {
// Create a deferred object
// dfd = new $.Deferred();
// https://github.com/niklasvh/html2canvas/issues/95#issuecomment-45114424
// First render all SVGs to canvases
targetElem = $('#dashboard');
var promises = $.when.apply(targetElem, $.map(targetElem.find('svg')
, function(el, index) {
return new $.Deferred(function(dfd) {
var svg = $(el);
var canvas = $('<canvas></canvas>');
svg.replaceWith(canvas);
// Get the raw SVG string and curate it
var content = svg.wrap('<p></p>').parent().html();
content = content.replace(/xlink:title='hide\/show'/g, '');
content = encodeURIComponent(content);
svg.unwrap();
// Create an image from the svg
var image = new Image();
image.onload = function() {
canvas[0].width = image.width;
canvas[0].height = image.height;
// Render the image to the canvas
var context = canvas[0].getContext('2d');
dfd.resolve(context.drawImage(image, 0, 0));
};
image.src = 'data:image/svg+xml,' + content;
}).promise();
})
); // end of targetElem.find('svg').map(function() {...});
promises.then(function(_canvas) {
console.log('dfd done', _canvas, arguments);
// http://www.kubilayerdogan.net/html2canvas-take-screenshot-of-web-page-and-save-it-to-server-javascript-and-php/
$('#dashboard').html2canvas({
onrendered: function (canvas) {
//Set hidden field's value to image data (base-64 string)
var dashboardPng = canvas.toDataURL('image/png');
console.log('dashboardPng: ' + dashboardPng);
$.ajax({
url:'save_dashboard_image.php',
data:{dashboardPngData: dashboardPng},
type:'POST',
dataType:'json',
success: function(){
console.log('success');
}
,
error: function(xhr, status, error){
console.log('The requested page was: ' + document.URL +
'. The error number returned was: ' + xhr.status +
'. The error message was: ' + error);
}
});
}
});
}); // end of $.when(dfd).done(...)
}); // end of save_dashboard click function
}); // end of document
解决方案 我不得不为每个连续的 svg 到 canvas 转换以及它们全部完成时使用一个数组。我可以将数组传递给 then() 到 post html2canvas.
- 在点击时创建一个新数组,用它来存储所有来自 SVG 的延迟
- 遍历所有 SVG 元素
- 在每个实例中,创建一个新的内部延迟对象
- 解决或拒绝延期
- 将其推入循环外的数组
使用
$.when.apply($, arrayOfDeferredObjects)
检查数组中所有延迟对象的状态$( '#save_dashboard' ).click(function() { // Declare an array to store all deferred objects from each svg element var svgDfds = [], targetElem = $('#dashboard'); targetElem.find('svg').each(function() { var dfd = new $.Deferred(), svg = $(this), canvas = $('<canvas></canvas>'); svg.replaceWith(canvas); // Get the raw SVG string and curate it var content = svg.wrap('<p></p>').parent().html(); content = content.replace(/xlink:title='hide\/show'/g, ''); content = encodeURIComponent(content); svg.unwrap(); // Create an image from the svg var image = new Image(); image.src = 'data:image/svg+xml,' + content; image.onload = function() { canvas[0].width = image.width; canvas[0].height = image.height; // Render the image to the canvas var context = canvas[0].getContext('2d'); // Resolve or reject the deferred dfd.resolve(context.drawImage(image, 0, 0)); }; // Push deferred object into array svgDfds.push(dfd); }); // end of targetElem.find('svg').map(function() {...}); // Check for all deferreds $.when.apply($, svgDfds).then(function(_canvas) { console.log('dfd done', _canvas); // http://www.kubilayerdogan.net/html2canvas-take-screenshot-of-web-page-and-save-it-to-server-javascript-and-php/ $('#dashboard').html2canvas({ onrendered: function (canvas) { //Set hidden field's value to image data (base-64 string) var dashboardPng = canvas.toDataURL('image/png'); console.log('dashboardPng: ' + dashboardPng); $.ajax({ url:'save_dashboard_image.php', data:{dashboardPngData: dashboardPng}, type:'POST', dataType:'json', success: function(){ console.log('success'); } , error: function(xhr, status, error){ console.log('The requested page was: ' + document.URL + '. The error number returned was: ' + xhr.status + '. The error message was: ' + error); } }); } }); }); }); // end of save_dashboard click function