Fabric.js implements DIY postcard function

Fabric.js implements DIY postcard function

This article shares the specific code of fabricjs to realize the DIY postcard function for your reference. The specific content is as follows

Preface

Requirements include adding, copying, deleting, and zooming in and out with two fingers.

Tip: The following is the main content of this article. The following cases can be used for reference

1. fabric.js is a very useful canvas operation plug-in

Example: pandas is a tool based on NumPy that was created to solve data analysis tasks.

2. Code Examples

The code is as follows (example):

<!DOCTYPE html>
<html lang="en">
<head>
<title>diy</title>
<meta charset="utf-8">
<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1">
<meta http-equiv="Access-Control-Allow-Origin" content="*" />
<meta http-equiv="Expires" content="-1">
<meta http-equiv="Cache-Control" content="no-cache">
<meta http-equiv="Pragma" content="no-cache">
<script src="./js/jquery-3.4.1.min.js"></script>
<script src="./js/fabric.js"></script>
<script src="./js/customiseControls.min.js"></script>
</head>
<style>
  body{
    margin: 0;
    padding: 0;
    border: 0;
    font-size: 100%;
    font-weight: normal;
    vertical-align: baseline;    
  }  
  .end{
    position: fixed;
    top: 0;
    right: 0;
    width: 50px;
    height: 20px;
    background-color: #000000;
    color: #ffffff;
    font-size: 12px;
    line-height: 20px;
    z-index: 9999;
  }
  .canvasimg{
    position: fixed;
    top: 0;
    left: 0;
    width: 50px;
    height: 20px;
    background-color: #000000;
    color: #ffffff;
    font-size: 12px;
    line-height: 20px;
    z-index: 9999;
  }
  .canvasimg input{
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
  }
  #inline-btn{
    position: fixed;
    opacity: 0;
    z-index: 999;
  }
  #addinline-btn{
    opacity: 0;
    position: fixed;
    z-index: 999;
  }  
  .canvassrc{
    position: fixed;
    top: 0;
    right: 0;
    width: 100%;
    height: 100%;
    z-index: 9999;
  }
</style>
<body>
  <div class="canvasimg"><input type="file" name="" id="canvasimg" class="canvasimgadd" type="file" accept="image/*" onchange="selectFileImage(this);" >Add picture</div>
  <div class="end" onclick="linkcanvas()">Generate image</div>
  <button id="inline-btn" onclick="canvasonclick()">Delete image button</button>
  <button id="addinline-btn" onclick="copy()">Copy image button</button>
  <canvas id="c"></canvas>
</body>
</html>
<script>
  //Reference link//See the detailed Chinese explanation of the API at the end of the article//http://fabricjs.com/ fabric.js official website//DIY function requires copy function, delete function, zoom in, zoom out, move and rotate//Add new image function selectFileImage(fileObj){
    var file = fileObj.files['0'];
    var reader = new FileReader();
    reader.readAsDataURL(file)
    reader.onload = function (e) {
      fabric.Image.fromURL(e.target.result, function (img) {
        img.scale(1).set({
          left: webwidth - (webwidth / 2), //Center the image left and right top: webheight - (webheight / 2), //Center the image top and bottom, total value of screen height - (image height / 2) / 2
          angle: 0, //angle is 0
          originX: 'center',
          originY: 'center',
        });
        //The default width of the image fills the screen and leaves 20 pixels of space on one side. The height is adaptive img.scaleToWidth(webwidth - 40)
        canvas.add(img).setActiveObject(img);
        // Clear the lines img.hasBorders = false;
        //Customize the image function buttons, hide the redundant function buttons, and only keep the buttons in the four corners canvas.forEachObject(function (em) {
          em['setControlVisible']('mtr', false);
          em['setControlVisible']('mt', false);
          em['setControlVisible']('ml', false);
          em['setControlVisible']('mb', false);
          em['setControlVisible']('mr', false);
          em['setControlVisible']('mt', false);
        })
      });
    }
  }


  // Delete button var btn = document.getElementById('inline-btn')
  // Add button var addbtn = document.getElementById('addinline-btn')

  // Get the screen height and width var webwidth = $(window).width()
  var webheight = $(window).height()
  //Create a canvas var canvas = new fabric.Canvas('c');
  //The canvas fills the screen by default canvas.setWidth(webwidth)
    canvas.setHeight(webheight)
    //Import image fabric.Image.fromURL('./imgs/2.jpg', function (img) {
      img.scale(1).set({
        left: webwidth - (webwidth/2), //Center the image left and right top: webheight-(webheight/2), //Center the image top and bottom, total value of screen height - (image height/2)/2
        angle: 0, //angle is 0
        originX: 'center',
        originY: 'center',
      });
      //The default width of the image fills the screen with 20 pixels of white space on one side and is highly adaptive img.scaleToWidth(webwidth-40)
      canvas.add(img).setActiveObject(img);
      // Clear the lines img.hasBorders = false;
      //Customize the image function buttons, hide the redundant function buttons, and only keep the buttons in the four corners canvas.forEachObject(function(em){
        em['setControlVisible']('mtr', false); 
        em['setControlVisible']('mt', false);
        em['setControlVisible']('ml', false);
        em['setControlVisible']('mb', false);
        em['setControlVisible']('mr', false);
        em['setControlVisible']('mt', false);
      })
    });

    //Cancel multiple selection canvas.selection = false;
    //The new layer does not appear on the top layer canvas.preserveObjectStacking = true;    
    //Note: To customize the button function, you need to introduce another JS plug-in called customiseControls of fabric, otherwise it will not work. //Globally modify the functions of the four buttons fabric.Canvas.prototype.customiseControls({
      bl: {
        action: 'rotate' //Add image rotation function},
      // only hasRotatingPoint is not set to false
    }, function () {
      canvas.renderAll();
    });  

    //Because the default button style is not what we want, we need to customize some icons on it fabric.Object.prototype.customiseCornerIcons({
      tl: {
        icon: './img/[email protected]', //Picture path cornerSize: 70, //Button click range is equivalent to the CSS padding attribute settings: {
          cornerSize: 25 //icon size},    
      },
      tr: {
        icon: './img/[email protected]',
        cornerSize: 70,  
        settings: {
          cornerSize: 25
        },         
      },
      bl: {
        icon: './img/[email protected]',
        cornerSize: 70,  
        settings: {
          cornerSize: 25
        },         
      },
      br: {
        icon: './img/[email protected]',
        cornerSize: 70,
        settings: {
          cornerSize: 25
        },         
      },
    }, function () {
      canvas.renderAll();
    }); 

    //Button follows the image position function positionBtn(obj) {
      //Get the unit parameters of the currently selected image var absCoords = canvas.getAbsoluteCoords(obj);
      btn.style.width = '30px';
      btn.style.height = '30px';
      btn.style.opacity = '0';
      btn.style.left = (absCoords.right - 30 / 2) + 'px';
      btn.style.top = (absCoords.top - 30 / 2) + 'px';

      addbtn.style.width = '30px';
      addbtn.style.height = '30px';
      addbtn.style.opacity = '0';
      addbtn.style.left = (absCoords.left - 30 / 2) + 'px';
      addbtn.style.top = (absCoords.leftTop - 30 / 2) + 'px';
    }

    fabric.Canvas.prototype.getAbsoluteCoords = function (object) {
      return {
        right: object.aCoords.tr.x + this._offset.left,
        top:object.aCoords.tr.y + this._offset.top,
        left: object.aCoords.tl.x + this._offset.left,
        leftTop: object.aCoords.tl.y + this._offset.top,
      };
    }


    //Delete the currently selected image function canvasonclick(){
      var t = canvas.getActiveObject()
      canvas.remove(t);
    }

    //Copy the currently selected image function copy(){
      var _self = this;
      canvas.getActiveObject().clone(function (cloned) {
        _self.paste(cloned);
        canvas.discardActiveObject().renderAll()
      })
    }    
    function paste(_clipboard){
      console.log(_clipboard)
      var t = canvas.getActiveObject();
      // Clone again so you can have multiple copies.
      t.clone(function (clonedObj) {
        canvas.discardActiveObject();
        clonedObj.set({
          left: clonedObj.left + 20,
          top: clonedObj.top + 20,
          evented: true,
          hasBorders:false
        });
        if (clonedObj.type === 'activeSelection') {
          // The activity selection requires a reference to the canvas.
          clonedObj.canvas = canvas;
          clonedObj.forEachObject(function (obj) {
            canvas.add(obj);  
            canvas.forEachObject(function (em) {
              em['setControlVisible']('mtr', false);
              em['setControlVisible']('mt', false);
              em['setControlVisible']('ml', false);
              em['setControlVisible']('mb', false);
              em['setControlVisible']('mr', false);
              em['setControlVisible']('mt', false);
            })                      
          });
          // Solve the problem of unselectability clonedObj.setCoords();
        } else {
          canvas.add(clonedObj);
          canvas.forEachObject(function (em) {
            em['setControlVisible']('mtr', false);
            em['setControlVisible']('mt', false);
            em['setControlVisible']('ml', false);
            em['setControlVisible']('mb', false);
            em['setControlVisible']('mr', false);
            em['setControlVisible']('mt', false);
          })          
        }
      });     
    }

    var store = {}
    //Calculate the average value var getDistance = function (start, stop) {
      return Math.hypot(stop.x - start.x, stop.y - start.y);
    };    

    //Monitor positionBtn event When the mouse is above the image, click on it and move it to trigger our custom copy button and delete button to follow the image positioning and double-finger zoom in and out function canvas.on('mouse:down',function(options){
      //Determine whether the image unit is clicked if (options.target) {
        //Run event positionBtn(options.target);

        //Double-finger zoom in and out store.pageX = options.e.changedTouches[0].clientX
        store.pageY = options.e.changedTouches[0].clientY
        if (options.e.changedTouches.length == 2) {
          store.pageY2 = options.e.changedTouches[1].clientY
          store.pageX2 = options.e.changedTouches[1].clientX
        }
        store.originScale = options.target.scaleX || 0.5;
        store.originleft = options.target.left;
        store.origintop = options.target.top;
      }
    });                
    canvas.on('mouse:move',function(options){
      if(options.target){
        positionBtn(options.target);
        if (options.e.changedTouches.length == 2) {
          if (!store.pageX2) {
            store.pageX2 = options.e.changedTouches[1].clientX
          }
          if (!store.pageY2) {
            store.pageY2 = options.e.changedTouches[1].clientY
          }
          var zoom = getDistance({
            x: options.e.changedTouches[0].clientX,
            y: options.e.changedTouches[0].clientY
          }, {
            x: options.e.changedTouches[1].clientX,
            y: options.e.changedTouches[1].clientY
          }) /
            getDistance({
              x: store.pageX,
              y: store.pageY
            }, {
              x: store.pageX2,
              y: store.pageY2
            });
          var newScale = store.originScale * zoom;
          if (newScale > 3) {
            newScale = 3;
          } 
          options.target.scaleX = newScale;
          options.target.scaleY = newScale;
          canvas.renderAll();
        }          
      }
    });  
    canvas.on('mouse:up',function(options){
      if(options.target){
        positionBtn(options.target);   
        store.pageY = 0
        store.pageX = 0
        store.pageY2 = 0
        store.pageX2 = 0    
        store.originScale = options.target.scaleX 
        store.originleft = options.target.left  
        store.origintop = options.target.top      
      }
    }); 

    //Generate postcard function linkcanvas(){
      let xheight = $('#c').height()
      let xwidth = $('#c').width()
      canvas.setBackgroundColor('rgba(255, 255, 255, 1)', canvas.renderAll.bind(canvas));
      var exportedArt = this.canvas.toDataURL({
        format: "jpeg",
        quality: 1.0,
        multiplier: 2.4,
        left: 0,
        top: 0,
        width: xwidth,
        height: xheight,
      });
      $('body').append(`<img class="canvassrc" src="${exportedArt}"/>`)
    }

</script>

Achieve results

Summarize

For some specific methods and knowledge points, I suggest you refer to this article

The above is the full content of this article. I hope it will be helpful for everyone’s study. I also hope that everyone will support 123WORDPRESS.COM.

You may also be interested in:
  • Detailed explanation of how to use the canvas operation plugin fabric.js

<<:  How to create a stored procedure in MySQL and add records in a loop

>>:  A brief analysis of how to upgrade PHP 5.4 to 5.6 in CentOS 7

Recommend

When MySQL is upgraded to 5.7, WordPress reports error 1067 when importing data

I recently upgraded MySQL to 5.7, and WordPress r...

Use mysql to record the http GET request data returned from the url

Business scenario requirements and implementation...

iview implements dynamic form and custom verification time period overlap

Dynamically adding form items iview's dynamic...

Detailed explanation of the correct use of the count function in MySQL

1. Description In MySQL, when we need to get the ...

Detailed steps and problem solving methods for installing MySQL 8.0.19 on Linux

I recently bought a Tencent Cloud server and buil...

Some tips on deep optimization to improve website access speed

<br />The website access speed can directly ...

How to monitor array changes in JavaScript

Preface When introducing defineProperty before, I...

5 Commands to Use the Calculator in Linux Command Line

Hello everyone, I am Liang Xu. When using Linux, ...

Use Python to connect to MySQL database using the pymysql module

Install pymysql pip install pymysql 2|0Using pymy...

How to optimize MySQL performance through MySQL slow query

As the number of visits increases, the pressure o...

How to deploy Vue project under nginx

Today I will use the server nginx, and I also nee...

JavaScript ES new feature block scope

Table of contents 1. What is block scope? 2. Why ...

How to install and configure WSL on Windows

What is WSL Quoting a passage from Baidu Encyclop...

Example of how to deploy a Django project using Docker

It is also very simple to deploy Django projects ...