如何将 FabricJS canvas 的背景图片设置为来自 Web 服务的图片?

How to set the background image of FabricJS canvas to image from a web service?

我有以下代码,当用户按下按钮时执行。它

  1. 连接到网络服务,
  2. 从中获取图像,
  3. 将其存储在 myDataURL 变量中并且
  4. 显示在 canvas。

代码如下:

function downloadButtonPressed() {
    var username = $("input#username").val();
    var password = $("input#password").val();
    $.ajax({
        type: "GET",
        url: "http://myserver/myapp/map",
        headers: {
            "Authorization": "Basic " + btoa(username + ":" + password),
          },
        crossDomain: true,
        xhrFields: {
                withCredentials: true
            },
        success: function (data, status, xhr) {
            alert("success");
        }
    }).fail(function ($xhr) {
        console.log("response: " + $xhr);
        var myDataURL = "data:image/png;base64," + $xhr.responseText;
        var canvas = document.getElementById('canvas');
        var context = canvas.getContext('2d');
        var img = new Image();
        img.onload = function() {
            context.drawImage(this, 0, 0, canvas.width, canvas.height);
        };
        img.src = myDataURL;
    });
}

这是浏览器 window 在我按下下载按钮后的样子:

现在我想将该图像设为 canvas 的背景图像,以便我可以在其上添加其他对象(例如矩形、其他图像)。

我该怎么做?

官方FabricJS tutorial推荐这个:

var myDataURL = "data:image/png;base64," + $xhr.responseText;
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var img = new Image();
img.onload = function() {
    // context.drawImage(this, 0, 0, canvas.width, canvas.height);
};
img.src = myDataURL;
canvas.setBackgroundImage(myDataURL, canvas.renderAll.bind(canvas));

但随后出现以下错误:

Update 1 (02.12.2015 13:23 MSK):无论我用哪种方法,下载后一点击背景图就消失了。

Here 是一个视频,它显示了我的意思。

更新 2(02.12.2015 13:28 MSK):

这是代码的当前版本:

选项 1:

function ($xhr) {
    var myDataURL = "data:image/png;base64," + $xhr;
    var canvas = new fabric.Canvas('canvas');
    var img = new Image();
    img.onload = function() {
        var f_img = new fabric.Image(img);
        canvas.setBackgroundImage(f_img);
        canvas.renderAll();
    };
    img.src = myDataURL;
}

选项 2:

function ($xhr) {
    var myDataURL = "data:image/png;base64," + $xhr;
    var canvas = new fabric.Canvas('canvas');
    canvas.setBackgroundImage(myDataURL, canvas.renderAll.bind(canvas));
}

更新 3(02.12.2015 14:07 MSK):

如果我尝试使用以下代码向 canvas 添加一个矩形,则会出现同样的问题。

function rectButtonPressed() {
    var canvas = new fabric.Canvas('canvas');
    var rect = new fabric.Rect({
      left: 100,
      top: 100,
      fill: 'red',
      width: 20,
      height: 20
    });
    canvas.add(rect);
}

首先,它出现了,但是当我点击 canvas 时,它又变空了。

您的代码的主要问题是您使用的是 canvas 元素而不是 fabricJS canvas。

要使用 canvas.renderAll() 函数,您必须初始化一个 fabric.Canvas 对象。

检查代码段:

var myDataURL = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAKkklEQVR4nO3dMW4cRxqGYfWaoZOFADnYRMAm4gGcSKkV2KDCPcFeYQGHS0eG4TPsBTY1YQZySiV7AAqOlDiQAMGJU6E3tERB9WO+YrF6Zp4nE1rT3TND80Vp5nct67qu9wBgR3+ZfQMA7CcBASAiIABEBASAiIAAEBEQACICAkBEQACICAgAEQEBICIgAEQEBICIgAAQERAAIgICQORk9g3AUMsy9vy20+GIWYEAEBEQACICAkBEQACICAgAEQEBICIgAESWdfVFdo7X8l37+HpujgQ+xQoEgIiAABAREAAiAgJAREAAiAgIABEBASBiPxAO2tK5H0jvFIgxKw6ZFQgAEQEBICIgAEQEBICIgAAQERAAIgICQMQcCFNdvHg59PzlHMYvxYYghde//9E8Xj2/s8ePuq4/+vWr9N4/+80KBICIgAAQERAAIgICQERAAIgICAARAQEgsqw2LGCiy2K/jndX10Ov/+Vv/+l6/P/+9s/m8bMnp83jl8X5q+d/+vBB8/j1qzfN48+K+6v49XHcrEAAiAgIABEBASAiIABEBASAiIAAEBEQACLmQJiqmgOpVHMS1RxG5aLz/NWcR6/q+X/W+fy/KY779XHcrEAAiAgIABEBASAiIABEBASAiIAAEBEQACIns2+A/VbNcXzdef7q8ZfFnMPr//6refyLv37ePF7NUVRzHr3Pvzp/75xHdX8/d52dQ2cFAkBEQACICAgAEQEBICIgAEQEBICIgAAQMQfCVL1zEr1e//5H8/jXz8/bJ3haHC+MniPpvr79PmiwAgEgIiAARAQEgIiAABAREAAiAgJAREAAiCzr6ovefFq130evcr+PzsdXLq6um8dPHz5oHr9+9aZ5/Gzj+4mU5/frgQYrEAAiAgJAREAAiAgIABEBASAiIABEBASAiDkQmi5evOx6/GfFHESl2o9i9JzKu8FzIr2vT8WcByNZgQAQERAAIgICQERAAIgICAARAQEgIiAARE5m3wD7rZyDKOYozh4/6rp+NSdyr5gTqfbLePa8fX8/PW3PyVSvz9+L61eq+zfnwUhWIABEBASAiIAAEBEQACICAkBEQACICAgAEXMgdPn86vvm8bN//HhHd5Kp9sv4+bw9R/LNvfacRfX4X4vrV8o5GBjICgSAiIAAEBEQACICAkBEQACICAgAEQEBILKsqy+SH7Vfvpt7/a/+PfT0S7EfSGV9fn47N/IJy9O+8/vPl5msQACICAgAEQEBICIgAEQEBICIgAAQERAAIuZA2LTLzjmOXtV+Ict5334g1fkvi+P2A2EmKxAAIgICQERAAIgICAARAQEgIiAARAQEgIg5EIba+hxHpZrzWIs5j0o159HLnAgjWYEAEBEQACICAkBEQACICAgAEQEBICIgAETMgdBn8pxHZfScxWi9cyz2E2EkKxAAIgICQERAAIgICAARAQEgIiAARAQEgIg5EPoUcyDlHELn5Wfvp1Htd1I9v977NyfCTFYgAEQEBICIgAAQERAAIgICQERAAIgICAARcyA0VXMOld45hV6z5xx650Rmm/36sW1WIABEBASAiIAAEBEQACICAkBEQACICAgAkZPZN8BcFy9etv/C1XXfBZ6cNg/37hey9TmFre8n8q73/eWoWYEAEBEQACICAkBEQACICAgAEQEBICIgAETMgdB0+vBB8/j1qzfN471zCveKOYqt76dR6Z5T6dyvpVK9/9Uc0dnjR7d5O2yMFQgAEQEBICIgAEQEBICIgAAQERAAIgICQGRZ18kbJjBU9T393jmPZ8V+H368tq3cD6bQ+/NjTmS/WYEAEBEQACICAkBEQACICAgAEQEBICIgAETMgey52XMeFT9e27YU+4n8dHXddX5zIofNCgSAiIAAEBEQACICAkBEQACICAgAEQEBIHIy+wYYy5wHLdX71zsnUv38sd+sQACICAgAEQEBICIgAEQEBICIgAAQERAAIuZADpw5D3qMnhNhv1mBABAREAAiAgJAREAAiAgIABEBASAiIABEzIFs3MWLl83j5jyYyZzIcbMCASAiIABEBASAiIAAEBEQACICAkBEQACImAOZrJrzOH34oOv85jyYqZrzqH6+qzkSP99zWYEAEBEQACICAkBEQACICAgAEQEBICIgAETMgQxWfY999vV9j56Rzh4/ah6v5qDYNisQACICAkBEQACICAgAEQEBICIgAEQEBIDIshoEACYZPSfl19tYViAARAQEgIiAABAREAAiAgJAREAAiAgIABH7gQDTmNPYb1YgAEQEBICIgAAQERAAIgICQERAAIgICAARAQEgIiAARAQEgIiAABAREAAiAgJAREAAiAgIABEBASAiIABEBASAiIAAEBEQACICAkBEQACICAgAEQEBICIgAEQEBICIgAAQOZl9A9ytZVlm38JRW9e1eXzf35/q+XFYrEAAiAgIABEBASDiM5Aj9/btk6Hnv3//auj1t37+6vGV3vPPfjyHzQoEgIiAABAREAAiPgOBO7Tvcx7wPisQACICAkBEQACI+AzkyG19DmDfzz/79YORrEAAiAgIABEBASDiM5AjM3o/ikPf7wL4kxUIABEBASAiIABEltUmxrzn5mcU67fF3//hwz/v+hlIdf7KzevfNPv8s++v0nv/H53Pr5OjYgUCQERAAIgICAARcyBwQGbP+XBcrEAAiAgIABEBASBiDoQPfDSnUf39G3/eeQ5kx/Pv6tjOP/r19+uC91mBABAREAAiAgJAxBwI3CH7pXBIrEAAiAgIABEBASDiMxA2bWtzFsCfrEAAiAgIABEBASAiIABEBASAiIAAEBEQACLmQGgaPQfh/Id9fg6bFQgAEQEBICIgAETsiQ5AxAoEgIiAABAREAAiAgJAREAAiAgIABEBASDi/4XVaVn2+/8mVI0BjX5+s6/PWL1jZrN//mizAgEgIiAARAQEgIjPQG7Z27dPhp7//v2rrutXj6/0Pr/R1x/9+mz9/d36+Xtt/f6OjRUIABEBASAiIABEfAZy5MxZMJKfr8NmBQJAREAAiAgIABGfgdyxrX8PffQcyb6bPYdTmX3+2XM63C0rEAAiAgJAREAAiPgMZOMOfb+Mrd//6Nf/0N9fDpsVCAARAQEgIiAARJbVpsBdbv4b9fpt5/l++PDPu/4beXX9m+e/afTjK6PPv+v1R7/+t33+yuz3r7K195c2KxAAIgICQERAAIgICAARAQEgIiAARAQEgIg5kE4ffU+/+vs7nn/nOYFbvv5H99P5+NHXr86/6+NHv/779v7e9ut722779afNCgSAiIAAEBEQACL2A5ls9r/Bzt6PYvb1gZwVCAARAQEgIiAARHwGwk565wAYa/YcRq/Zc0bsxgoEgIiAABAREAAiPgOhyZwG+2z2nNWhswIBICIgAEQEBICIz0Bu2exPBA79+r3n3/r97fv5Zz+eu2UFAkBEQACICAgAEXuiAxCxAgEgIiAARAQEgIiAABAREAAiAgJAREAAiAgIABEBASAiIABEBASAiIAAEBEQACICAkBEQACICAgAEQEBICIgAEQEBICIgAAQERAAIgICQERAAIgICAARAQEgIiAARAQEgMj/ARYVSURm9DRHAAAAAElFTkSuQmCC";

var canvas = new fabric.Canvas('canvas');
var img = new Image();
img.onload = function() {
    // this is syncronous
    var f_img = new fabric.Image(img);
    canvas.setBackgroundImage(f_img);
    canvas.renderAll();
};
img.src = myDataURL;
<script src="http://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.5.0/fabric.min.js"></script>
<canvas id='canvas' width="400" height="400" style="border:#000 1px solid;"></canvas>

此外,如果您出于某种原因不需要 img 元素,您可以按照您之前的说明进行操作:

var canvas = new fabric.Canvas('canvas');
canvas.setBackgroundImage(myDataUrl, canvas.renderAll.bind(canvas));

更短更好。