Javascript HTML画布-在传递base64数据的同时将背景图像传递到画布
我目前正在尝试在Laserfice表单中执行一些Javascript工作,这要求我将图像的base64数据保存在单独的文本区域中,并将该数据反馈到图像中,以便将画布转换为图像,并在其中保存到系统中 问题是,我正在尝试创建一个背景图像,在这种情况下,用户可以在其中绘制一个车辆,他们可以在其上绘制一个圆圈,以指示损坏的位置。我使用sketch.js允许任务的绘图部分 据我所知,背景CSS无法保存到画布中。这很好,但是当我已经获取base64数据并将其传递回画布时,如何传递背景图像 saveimage类属于文本区域,imagefinish属于它们在图像准备就绪时标记的复选框 html 我还为我的画布样式在onload中添加了两行。我有一种感觉,这个解决方案只会起作用,因为Laserfices forms软件是如何工作的,但标记的答案也是正确的Javascript HTML画布-在传递base64数据的同时将背景图像传递到画布,javascript,html,canvas,sketchjs,Javascript,Html,Canvas,Sketchjs,我目前正在尝试在Laserfice表单中执行一些Javascript工作,这要求我将图像的base64数据保存在单独的文本区域中,并将该数据反馈到图像中,以便将画布转换为图像,并在其中保存到系统中 问题是,我正在尝试创建一个背景图像,在这种情况下,用户可以在其中绘制一个车辆,他们可以在其上绘制一个圆圈,以指示损坏的位置。我使用sketch.js允许任务的绘图部分 据我所知,背景CSS无法保存到画布中。这很好,但是当我已经获取base64数据并将其传递回画布时,如何传递背景图像 saveimage
img.onload = function() {
ctx.drawImage(this, 0, 0, myCanvas.width, myCanvas.height);
myCanvas.style.backgroundRepeat = "no-repeat";
myCanvas.style.backgroundImage = 'url('+image+')'
}
img.src = $('.saveimage .cf-field').text();
}
在页面加载时加载背景图像,或者在适当的时间,当客户端准备就绪时,使用ctx.globalCompositeOperation=destination over将背景绘制到用户内容后面的画布上 创建一个图像来保存背景
const backgroundImage = new Image();
backgroundImage.src = "http://localhost/forms/img/vanImage.jpg";
您需要确保在客户端单击ready时已加载映像,如果尚未加载映像,则可以设置回调函数,以便在需要时回调ready函数
var backgroundLoadedCallback = null;
backgroundImage.onload = function(){
if( typeof backgroundLoadedCallback === "function"){
backgroundLoadedCallback();
}
}
然后创建canvas->textarea函数
function canvasToTextarea(){
const myCanvas = document.getElementById('colors_sketch');
const ctx = myCanvas.getContext("2d");
ctx.globalCompositeOperation = "destination-over"; // make sure the background go under the drawn pixels
// draw and fit background to the canvas
ctx.drawImage(backgroundImage,0,0,ctx.canvas.width,ctx.canvas.height);
// then convert to URL for textarea
$('.saveimage textarea').val(myCanvas.toDataURL());
}
在checked函数中
$('.imagefinish input').change(function(){
if(this.checked) {
if(backgroundImage.complete) { // image has loaded so all good
canvasToTextarea(); // put canvas data URL to textarea
} else { // background has not yet loaded (or could be an error you will have to deal with that as well
// set the callback to the canvasToTextarea function
backgroundLoadedCallback = canvasToTextarea;
// when the background has loaded the canvas and background
// will be moved to the textarea as a data URL
}
}
});
或者修改sketch.js
下面是sketch.js中的draw函数,它非常老派
Sketch.prototype.redraw = function() {
var sketch;
this.el.width = this.canvas.width();
this.context = this.el.getContext('2d');
sketch = this;
$.each(this.actions, function() {
if (this.tool) {
return $.sketch.tools[this.tool].draw.call(sketch, this);
}
});
if (this.painting && this.action) {
return $.sketch.tools[this.action.tool].draw.call(sketch, this.action);
}
};
只需将其替换为以下内容。您不需要修改sketch.js文件,只需覆盖重新绘制的原型即可
在代码中加载背景并设置新的重画
const backgroundImage = new Image();
backgroundImage.src = "http://localhost/forms/img/vanImage.jpg";
// replace Sketch.js redraw function
Sketch.prototype.redraw = function(){
var sketch;
// dont need the next line use clear instead
// this.el.width = this.canvas.width();
const ctx = this.context = this.el.getContext('2d');
// clear canvas
this.context.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
// If backgroundimage complete draw it first
if(backgroundImage && backgroundImage.complete){
ctx.drawImage(backgroundImage,0,0,ctx.canvas.width,ctx.canvas.height);
}
// back to the original code. :P
sketch = this;
$.each(this.actions, function() {
if (this.tool) {
return $.sketch.tools[this.tool].draw.call(sketch, this);
}
});
if (this.painting && this.action) {
return $.sketch.tools[this.action.tool].draw.call(sketch, this.action);
}
}
我找到了一个超级解决方案,它有一个占位符背景url,根本不用于保存,只是放在CSS中。然后,我为我的路径添加了一个变量,然后在图像绘制完成后加载。myCanvas.style.backgroundRepeat=不重复;myCanvas.style.backgroundImage='url'+image+。我的解决方案相当特定于我正在构建的软件,但您的解决方案也可以工作,因此我将把它标记为一个答案,并更新我的OP。
$('.imagefinish input').change(function(){
if(this.checked) {
if(backgroundImage.complete) { // image has loaded so all good
canvasToTextarea(); // put canvas data URL to textarea
} else { // background has not yet loaded (or could be an error you will have to deal with that as well
// set the callback to the canvasToTextarea function
backgroundLoadedCallback = canvasToTextarea;
// when the background has loaded the canvas and background
// will be moved to the textarea as a data URL
}
}
});
Sketch.prototype.redraw = function() {
var sketch;
this.el.width = this.canvas.width();
this.context = this.el.getContext('2d');
sketch = this;
$.each(this.actions, function() {
if (this.tool) {
return $.sketch.tools[this.tool].draw.call(sketch, this);
}
});
if (this.painting && this.action) {
return $.sketch.tools[this.action.tool].draw.call(sketch, this.action);
}
};
const backgroundImage = new Image();
backgroundImage.src = "http://localhost/forms/img/vanImage.jpg";
// replace Sketch.js redraw function
Sketch.prototype.redraw = function(){
var sketch;
// dont need the next line use clear instead
// this.el.width = this.canvas.width();
const ctx = this.context = this.el.getContext('2d');
// clear canvas
this.context.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
// If backgroundimage complete draw it first
if(backgroundImage && backgroundImage.complete){
ctx.drawImage(backgroundImage,0,0,ctx.canvas.width,ctx.canvas.height);
}
// back to the original code. :P
sketch = this;
$.each(this.actions, function() {
if (this.tool) {
return $.sketch.tools[this.tool].draw.call(sketch, this);
}
});
if (this.painting && this.action) {
return $.sketch.tools[this.action.tool].draw.call(sketch, this.action);
}
}