Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/401.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 HTML画布-在传递base64数据的同时将背景图像传递到画布_Javascript_Html_Canvas_Sketchjs - Fatal编程技术网

Javascript HTML画布-在传递base64数据的同时将背景图像传递到画布

Javascript HTML画布-在传递base64数据的同时将背景图像传递到画布,javascript,html,canvas,sketchjs,Javascript,Html,Canvas,Sketchjs,我目前正在尝试在Laserfice表单中执行一些Javascript工作,这要求我将图像的base64数据保存在单独的文本区域中,并将该数据反馈到图像中,以便将画布转换为图像,并在其中保存到系统中 问题是,我正在尝试创建一个背景图像,在这种情况下,用户可以在其中绘制一个车辆,他们可以在其上绘制一个圆圈,以指示损坏的位置。我使用sketch.js允许任务的绘图部分 据我所知,背景CSS无法保存到画布中。这很好,但是当我已经获取base64数据并将其传递回画布时,如何传递背景图像 saveimage

我目前正在尝试在Laserfice表单中执行一些Javascript工作,这要求我将图像的base64数据保存在单独的文本区域中,并将该数据反馈到图像中,以便将画布转换为图像,并在其中保存到系统中

问题是,我正在尝试创建一个背景图像,在这种情况下,用户可以在其中绘制一个车辆,他们可以在其上绘制一个圆圈,以指示损坏的位置。我使用sketch.js允许任务的绘图部分

据我所知,背景CSS无法保存到画布中。这很好,但是当我已经获取base64数据并将其传递回画布时,如何传递背景图像

saveimage类属于文本区域,imagefinish属于它们在图像准备就绪时标记的复选框

html

我还为我的画布样式在onload中添加了两行。我有一种感觉,这个解决方案只会起作用,因为Laserfices forms软件是如何工作的,但标记的答案也是正确的

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);
  }
}