使用fabric.js添加背景图片

时间:2017-05-16 19:31:16

标签: javascript jquery html css fabricjs

我可以使用输入类型=“文件”id =“文件”来添加图像,但是希望能够上传可以移动的图像并将其作为背景图像保留在其他所有位置之后。现在我可以添加一些内容并将其发送到后面,但移动它很困难,因为控件在画布上运行。任何帮助将不胜感激 - 提前感谢。

// Add image from local
var canvas = new fabric.Canvas('c');

// display/hide text controls
canvas.on('object:selected', function(e) {
  if (e.target.type === 'i-text') {
    document.getElementById('textControls').hidden = false;
  }
});
canvas.on('before:selection:cleared', function(e) {
  if (e.target.type === 'i-text') {
    document.getElementById('textControls').hidden = true;
  }
});
document.getElementById('file').addEventListener("change", function(e) {
  var file = e.target.files[0];
  var reader = new FileReader();
  reader.onload = function(f) {
    var data = f.target.result;
    fabric.Image.fromURL(data, function(img) {
      var oImg = img.set({
        left: 0,
        top: 0,
        angle: 00,
        border: '#000',
        stroke: '#F0F0F0', //<-- set this
        strokeWidth: 40 //<-- set this
      }).scale(0.2);
      canvas.add(oImg).renderAll();
      //var a = canvas.setActiveObject(oImg);
      var dataURL = canvas.toDataURL({
        format: 'png',
        quality: 1
      });
    });
  };
  reader.readAsDataURL(file);
});
// Delete selected object
window.deleteObject = function() {
  var activeGroup = canvas.getActiveGroup();
  if (activeGroup) {
    var activeObjects = activeGroup.getObjects();
    for (let i in activeObjects) {
      canvas.remove(activeObjects[i]);
    }
    canvas.discardActiveGroup();
    canvas.renderAll();
  } else canvas.getActiveObject().remove();
}
// Refresh page
function refresh() {
  setTimeout(function() {
    location.reload()
  }, 100);
}
// Add text
function Addtext() {
  canvas.add(new fabric.IText('Tap and Type', {
    left: 50,
    top: 100,
    fontFamily: 'helvetica neue',
    fill: '#000',
    stroke: '#fff',
    strokeWidth: .1,
    fontSize: 45
  }));
}
// Edit Text
document.getElementById('text-color').onchange = function() {
  canvas.getActiveObject().setFill(this.value);
  canvas.renderAll();
};
document.getElementById('text-color').onchange = function() {
  canvas.getActiveObject().setFill(this.value);
  canvas.renderAll();
};
document.getElementById('text-bg-color').onchange = function() {
  canvas.getActiveObject().setBackgroundColor(this.value);
  canvas.renderAll();
};
document.getElementById('text-lines-bg-color').onchange = function() {
  canvas.getActiveObject().setTextBackgroundColor(this.value);
  canvas.renderAll();
};
document.getElementById('text-stroke-color').onchange = function() {
  canvas.getActiveObject().setStroke(this.value);
  canvas.renderAll();
};
document.getElementById('text-stroke-width').onchange = function() {
  canvas.getActiveObject().setStrokeWidth(this.value);
  canvas.renderAll();
};
document.getElementById('font-family').onchange = function() {
  canvas.getActiveObject().setFontFamily(this.value);
  canvas.renderAll();
};
document.getElementById('text-font-size').onchange = function() {
  canvas.getActiveObject().setFontSize(this.value);
  canvas.renderAll();
};
document.getElementById('text-line-height').onchange = function() {
  canvas.getActiveObject().setLineHeight(this.value);
  canvas.renderAll();
};
document.getElementById('text-align').onchange = function() {
  canvas.getActiveObject().setTextAlign(this.value);
  canvas.renderAll();
};
radios5 = document.getElementsByName("fonttype"); // wijzig naar button
for (var i = 0, max = radios5.length; i < max; i++) {
  radios5[i].onclick = function() {
    if (document.getElementById(this.id).checked == true) {
      if (this.id == "text-cmd-bold") {
        canvas.getActiveObject().set("fontWeight", "bold");
      }
      if (this.id == "text-cmd-italic") {
        canvas.getActiveObject().set("fontStyle", "italic");
      }
      if (this.id == "text-cmd-underline") {
        canvas.getActiveObject().set("textDecoration", "underline");
      }
      if (this.id == "text-cmd-linethrough") {
        canvas.getActiveObject().set("textDecoration", "line-through");
      }
      if (this.id == "text-cmd-overline") {
        canvas.getActiveObject().set("textDecoration", "overline");
      }
    } else {
      if (this.id == "text-cmd-bold") {
        canvas.getActiveObject().set("fontWeight", "");
      }
      if (this.id == "text-cmd-italic") {
        canvas.getActiveObject().set("fontStyle", "");
      }
      if (this.id == "text-cmd-underline") {
        canvas.getActiveObject().set("textDecoration", "");
      }
      if (this.id == "text-cmd-linethrough") {
        canvas.getActiveObject().set("textDecoration", "");
      }
      if (this.id == "text-cmd-overline") {
        canvas.getActiveObject().set("textDecoration", "");
      }
    }
    canvas.renderAll();
  }
}

// Send selected object to front or back
var selectedObject;
canvas.on('object:selected', function(event) {
  selectedObject = event.target;
});
var sendSelectedObjectBack = function() {
  canvas.sendToBack(selectedObject);
}
var sendSelectedObjectToFront = function() {
  canvas.bringToFront(selectedObject);
}
// Download
var imageSaver = document.getElementById('lnkDownload');
imageSaver.addEventListener('click', saveImage, false);

function saveImage(e) {
  this.href = canvas.toDataURL({
    format: 'png',
    quality: 0.8
  });
  this.download = 'custom.png'
}
// Do some initializing stuff
fabric.Object.prototype.set({
  transparentCorners: true,
  cornerColor: '#22A7F0',
  borderColor: '#22A7F0',
  cornerSize: 12,
  padding: 5
});
body {
  padding: 10px 10px 10px 10px;
  font-family: "HelveticaNeue";
}

canvas {
  border: 1px solid #bdc3c7;
  margin: 10px 0px 0px 0px;
  /*  background-image: url("images/bg.png"); */
}

.myFile {
  position: relative;
  overflow: hidden;
  float: left;
  clear: left;
}

.myFile input[type="file"] {
  display: block;
  position: absolute;
  top: 0;
  right: 0;
  opacity: 0;
  font-size: 30px;
  filter: alpha(opacity=0);
}

.title {
  color: black;
  text-decoration: none;
  margin-bottom: 20px;
  display: block;
}

hr {
  text-align: left;
  margin: 30px auto 0 0;
  width: 700px;
}

a:visited {
  text-decoration: none;
  color: #000;
}

a:active {
  text-decoration: none;
  color: #000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.11/fabric.js"></script>
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8" />
  <title>Brand</title>
  <link rel="stylesheet" type="text/css" href="styles.css">
  <link rel="stylesheet" type="text/css" href="icons/css/materialdesignicons.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>

<body>
  <label><a style="text-decoration: none;" href="#"><span class="mdi mdi-lightbulb-on-outline">Brand</span></a></label><br><br>
  <label title="Add an image" class="myFile"><span class="mdi mdi-image"> Add Photo</span>&nbsp;<input type="file" id="file" /></label>
  <a onclick="Addtext()" title="Add text"><span class="mdi mdi-format-text"> Add Text</span></a>&emsp;
  <a onclick="sendSelectedObjectToFront()" title="Bring selected to front"><span class="mdi mdi-arrange-bring-forward"> Front</span></a>
  <a onclick="sendSelectedObjectBack()" title="Send selected to back"><span class="mdi mdi-arrange-send-backward"> Back</span></a>
  <a onClick="deleteObject()" title="Delete Anything Selected"><span class="mdi mdi-delete"> Delete</span></a>&emsp;
  <a onclick="refresh()" title="Start fresh"><span class="mdi mdi-shredder"> Clear All</span></a>&emsp;
  <a id="lnkDownload" title="Save"><span class="mdi mdi-download"> Save</span></a>
  <div id="textControls" hidden>
    <div id="text-wrapper" data-ng-show="getText()">
      <div id="text-controls">
        <select id="font-family">
            <option value="arial">Arial</option>
            <option value="HelveticaNeue" selected>Helvetica Neue</option>
            <option value="myriad pro">Myriad Pro</option>
            <option value="delicious">Delicious</option>
            <option value="verdana">Verdana</option>
            <option value="georgia">Georgia</option>
            <option value="courier">Courier</option>
            <option value="comic sans ms">Comic Sans MS</option>
            <option value="impact">Impact</option>
            <option value="monaco">Monaco</option>
            <option value="optima">Optima</option>
            <option value="hoefler text">Hoefler Text</option>
            <option value="plaster">Plaster</option>
            <option value="engagement">Engagement</option>
          </select>
        <input type="color" id="text-color" size="10">
        <select id="text-align">
            <option value="left">Align Left</option>
            <option value="center">Align Center</option>
            <option value="right">Align Right</option>
            <option value="justify">Align Justify</option>
          </select>
        <label for="text-stroke-color">Stroke C:</label>
        <input type="color" id="text-stroke-color">
        <label for="text-stroke-width">Stroke W:</label>
        <input type="number" value="1" min="1" max="5" id="text-stroke-width">
        <label for="text-font-size">Font S:</label>
        <input type="number" min="12" max="120" step="1" id="text-font-size">
        <label for="text-line-height">Line H:</label>
        <input type="number" min="0" max="10" step="0.1" id="text-line-height">
        <label for="text-bg-color">BG Color:</label>
        <input type="color" id="text-bg-color" size="10">
        <label for="text-lines-bg-color">BG Text Color:</label>
        <input type="color" id="text-lines-bg-color" size="10">
        <input type='checkbox' name='fonttype' id="text-cmd-bold"> <b>B</b>
        <input type='checkbox' name='fonttype' id="text-cmd-italic"> <em>I</em>
        <input type='checkbox' name='fonttype' id="text-cmd-underline"> Underline
        <input type='checkbox' name='fonttype' id="text-cmd-linethrough"> Linethrough
        <input type='checkbox' name='fonttype' id="text-cmd-overline"> Overline
      </div>
    </div>
  </div>
  <canvas id="c" width="700" height="500"></canvas>
  <script src="fabric/fabric.min.js"></script>
  <script src="javascript.js"></script>
</body>

</html>

2 个答案:

答案 0 :(得分:12)

您可以使用setBackgroundImage()方法使用fabric.js将背景图像添加到画布。

document.getElementById(id).addEventListener("change", function(e) {
   var file = e.target.files[0];
   var reader = new FileReader();
   reader.onload = function(f) {
      var data = f.target.result;
      fabric.Image.fromURL(data, function(img) {
         // add background image
         canvas.setBackgroundImage(img, canvas.renderAll.bind(canvas), {
            scaleX: canvas.width / img.width,
            scaleY: canvas.height / img.height
         });
      });
   };
   reader.readAsDataURL(file);
});

ᴡᴏʀᴋɪɴɢᴡᴏʀᴋɪɴɢxᴀᴍᴘʟᴇᴀᴍᴘʟᴇ

// Add image from local
var canvas = new fabric.Canvas('c');
// display/hide text controls
canvas.on('object:selected', function(e) {
   if (e.target.type === 'i-text') {
      document.getElementById('textControls').hidden = false;
   }
});
canvas.on('before:selection:cleared', function(e) {
   if (e.target.type === 'i-text') {
      document.getElementById('textControls').hidden = true;
   }
});
document.getElementById('file').addEventListener("change", function(e) {
   var file = e.target.files[0];
   var reader = new FileReader();
   reader.onload = function(f) {
      var data = f.target.result;
      fabric.Image.fromURL(data, function(img) {
         var oImg = img.set({
            left: 0,
            top: 0,
            angle: 0,
            border: '#000',
            stroke: '#F0F0F0', //<-- set this
            strokeWidth: 40 //<-- set this
         }).scale(0.2);
         canvas.add(oImg).renderAll();
         //var a = canvas.setActiveObject(oImg);
         var dataURL = canvas.toDataURL({
            format: 'png',
            quality: 1
         });
      });
   };
   reader.readAsDataURL(file);
});


document.getElementById('file2').addEventListener("change", function(e) {
   var file = e.target.files[0];
   var reader = new FileReader();
   reader.onload = function(f) {
      var data = f.target.result;
      fabric.Image.fromURL(data, function(img) {
         // add background image
         canvas.setBackgroundImage(img, canvas.renderAll.bind(canvas), {
            scaleX: canvas.width / img.width,
            scaleY: canvas.height / img.height
         });
      });
   };
   reader.readAsDataURL(file);
});

// Delete selected object
window.deleteObject = function() {
      var activeGroup = canvas.getActiveGroup();
      if (activeGroup) {
         var activeObjects = activeGroup.getObjects();
         for (let i in activeObjects) {
            canvas.remove(activeObjects[i]);
         }
         canvas.discardActiveGroup();
         canvas.renderAll();
      } else canvas.getActiveObject().remove();
   }
   // Refresh page
function refresh() {
   setTimeout(function() {
      location.reload()
   }, 100);
}
// Add text
function Addtext() {
   canvas.add(new fabric.IText('Tap and Type', {
      left: 50,
      top: 100,
      fontFamily: 'helvetica neue',
      fill: '#000',
      stroke: '#fff',
      strokeWidth: .1,
      fontSize: 45
   }));
}
// Edit Text
document.getElementById('text-color').onchange = function() {
   canvas.getActiveObject().setFill(this.value);
   canvas.renderAll();
};
document.getElementById('text-color').onchange = function() {
   canvas.getActiveObject().setFill(this.value);
   canvas.renderAll();
};
document.getElementById('text-bg-color').onchange = function() {
   canvas.getActiveObject().setBackgroundColor(this.value);
   canvas.renderAll();
};
document.getElementById('text-lines-bg-color').onchange = function() {
   canvas.getActiveObject().setTextBackgroundColor(this.value);
   canvas.renderAll();
};
document.getElementById('text-stroke-color').onchange = function() {
   canvas.getActiveObject().setStroke(this.value);
   canvas.renderAll();
};
document.getElementById('text-stroke-width').onchange = function() {
   canvas.getActiveObject().setStrokeWidth(this.value);
   canvas.renderAll();
};
document.getElementById('font-family').onchange = function() {
   canvas.getActiveObject().setFontFamily(this.value);
   canvas.renderAll();
};
document.getElementById('text-font-size').onchange = function() {
   canvas.getActiveObject().setFontSize(this.value);
   canvas.renderAll();
};
document.getElementById('text-line-height').onchange = function() {
   canvas.getActiveObject().setLineHeight(this.value);
   canvas.renderAll();
};
document.getElementById('text-align').onchange = function() {
   canvas.getActiveObject().setTextAlign(this.value);
   canvas.renderAll();
};
radios5 = document.getElementsByName("fonttype"); // wijzig naar button
for (var i = 0, max = radios5.length; i < max; i++) {
   radios5[i].onclick = function() {
      if (document.getElementById(this.id).checked == true) {
         if (this.id == "text-cmd-bold") {
            canvas.getActiveObject().set("fontWeight", "bold");
         }
         if (this.id == "text-cmd-italic") {
            canvas.getActiveObject().set("fontStyle", "italic");
         }
         if (this.id == "text-cmd-underline") {
            canvas.getActiveObject().set("textDecoration", "underline");
         }
         if (this.id == "text-cmd-linethrough") {
            canvas.getActiveObject().set("textDecoration", "line-through");
         }
         if (this.id == "text-cmd-overline") {
            canvas.getActiveObject().set("textDecoration", "overline");
         }
      } else {
         if (this.id == "text-cmd-bold") {
            canvas.getActiveObject().set("fontWeight", "");
         }
         if (this.id == "text-cmd-italic") {
            canvas.getActiveObject().set("fontStyle", "");
         }
         if (this.id == "text-cmd-underline") {
            canvas.getActiveObject().set("textDecoration", "");
         }
         if (this.id == "text-cmd-linethrough") {
            canvas.getActiveObject().set("textDecoration", "");
         }
         if (this.id == "text-cmd-overline") {
            canvas.getActiveObject().set("textDecoration", "");
         }
      }
      canvas.renderAll();
   }
}
// Send selected object to front or back
var selectedObject;
canvas.on('object:selected', function(event) {
   selectedObject = event.target;
});
var sendSelectedObjectBack = function() {
   canvas.sendToBack(selectedObject);
}
var sendSelectedObjectToFront = function() {
      canvas.bringToFront(selectedObject);
   }
   // Download
var imageSaver = document.getElementById('lnkDownload');
imageSaver.addEventListener('click', saveImage, false);

function saveImage(e) {
   this.href = canvas.toDataURL({
      format: 'png',
      quality: 0.8
   });
   this.download = 'custom.png'
}
// Do some initializing stuff
fabric.Object.prototype.set({
   transparentCorners: true,
   cornerColor: '#22A7F0',
   borderColor: '#22A7F0',
   cornerSize: 12,
   padding: 5
});
body {
   padding: 10px 10px 10px 10px;
   font-family: "HelveticaNeue";
}

canvas {
   border: 1px solid #bdc3c7;
   margin: 10px 0px 0px 0px;
   /*  background-image: url("images/bg.png"); */
}

.myFile {
   position: relative;
   overflow: hidden;
   float: left;
   clear: left;
}

.myFile input[type="file"] {
   display: block;
   position: absolute;
   top: 0;
   right: 0;
   opacity: 0;
   font-size: 30px;
   filter: alpha(opacity=0);
}

.myFile2 input[type="file"] {
   display: block;
   position: absolute;
   top: 0;
   right: 0;
   opacity: 0;
   font-size: 30px;
   filter: alpha(opacity=0);
}

.title {
   color: black;
   text-decoration: none;
   margin-bottom: 20px;
   display: block;
}

hr {
   text-align: left;
   margin: 30px auto 0 0;
   width: 700px;
}

a:visited {
   text-decoration: none;
   color: #000;
}

a:active {
   text-decoration: none;
   color: #000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.0.0-beta.7/fabric.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label><a style="text-decoration: none;" href="#"><span class="mdi mdi-lightbulb-on-outline">Brand</span></a></label>
<br>
<br>
<label title="Add an image" class="myFile"><span class="mdi mdi-image"> Add Photo</span>&nbsp;
   <input type="file" id="file" />
</label>
<label title="Add a background" class="myFile2"><span class="mdi mdi-image"> Add Background</span>&nbsp;
   <input type="file" id="file2" />
</label>
<a onclick="Addtext()" title="Add text"><span class="mdi mdi-format-text"> Add Text</span></a>&emsp;
<a onclick="sendSelectedObjectToFront()" title="Bring selected to front"><span class="mdi mdi-arrange-bring-forward"> Front</span></a>
<a onclick="sendSelectedObjectBack()" title="Send selected to back"><span class="mdi mdi-arrange-send-backward"> Back</span></a>
<a onClick="deleteObject()" title="Delete Anything Selected"><span class="mdi mdi-delete"> Delete</span></a>&emsp;
<a onclick="refresh()" title="Start fresh"><span class="mdi mdi-shredder"> Clear All</span></a>&emsp;
<a id="lnkDownload" title="Save"><span class="mdi mdi-download"> Save</span></a>
<div id="textControls" hidden>
   <div id="text-wrapper" data-ng-show="getText()">
      <div id="text-controls">
         <select id="font-family">
            <option value="arial">Arial</option>
            <option value="HelveticaNeue" selected>Helvetica Neue</option>
            <option value="myriad pro">Myriad Pro</option>
            <option value="delicious">Delicious</option>
            <option value="verdana">Verdana</option>
            <option value="georgia">Georgia</option>
            <option value="courier">Courier</option>
            <option value="comic sans ms">Comic Sans MS</option>
            <option value="impact">Impact</option>
            <option value="monaco">Monaco</option>
            <option value="optima">Optima</option>
            <option value="hoefler text">Hoefler Text</option>
            <option value="plaster">Plaster</option>
            <option value="engagement">Engagement</option>
         </select>
         <input type="color" id="text-color" size="10">
         <select id="text-align">
            <option value="left">Align Left</option>
            <option value="center">Align Center</option>
            <option value="right">Align Right</option>
            <option value="justify">Align Justify</option>
         </select>
         <label for="text-stroke-color">Stroke C:</label>
         <input type="color" id="text-stroke-color">
         <label for="text-stroke-width">Stroke W:</label>
         <input type="number" value="1" min="1" max="5" id="text-stroke-width">
         <label for="text-font-size">Font S:</label>
         <input type="number" min="12" max="120" step="1" id="text-font-size">
         <label for="text-line-height">Line H:</label>
         <input type="number" min="0" max="10" step="0.1" id="text-line-height">
         <label for="text-bg-color">BG Color:</label>
         <input type="color" id="text-bg-color" size="10">
         <label for="text-lines-bg-color">BG Text Color:</label>
         <input type="color" id="text-lines-bg-color" size="10">
         <input type='checkbox' name='fonttype' id="text-cmd-bold"> <b>B</b>
         <input type='checkbox' name='fonttype' id="text-cmd-italic"> <em>I</em>
         <input type='checkbox' name='fonttype' id="text-cmd-underline"> Underline
         <input type='checkbox' name='fonttype' id="text-cmd-linethrough"> Linethrough
         <input type='checkbox' name='fonttype' id="text-cmd-overline"> Overline
      </div>
   </div>
</div>
<canvas id="c" width="700" height="500"></canvas>

答案 1 :(得分:1)

您也可以使用setBackgroundColor()方法将背景图像添加到画布。

setCanvasImage (canvasImage) {
    self = this;
    if (canvasImage) {
      this.canvas.setBackgroundColor({ source: canvasImage, repeat: 'repeat' }, function () {
        self.canvas.renderAll();
      })
    }
  }