vue上传图片通过fabric.js实现移动端双指的缩放,移动

1,920 阅读1分钟

vue上传图片通过fabric.js实现移动端双指的缩放,移动

效果演示:

1.双指缩放

0.jpg

1.jpg

注意事项:

1.使用vue 和fabric.js

fabric.js官网

  在这个例子中我是参考demos-touch event 这个例子 http://fabricjs.com/touch-events

2.注意fabric的版本,我使用的是fabric_with_gestures.js 他里面有封装手势事件(当时是在demos,检查发现他用的不是fabric.js 而是fabric_with_gestures.js)

3.注意查看官方api 虽说fabric 的api 写的不怎么清楚,但这个库确实很好用

4.使用fabric_with_gestures.js 这个库因为它缩放和移动都生效,有时候就会不那么正常,我的解决方式是双指 放大缩小的时候禁止移动,单指才能移动,就正常很多

5.注意使用 new FileReader(); 这是异步的,可能会导致函数顺序有点问题

代码实现:

我在public 文件内 引用了 fabric_with_gestures.js 

template:

  <div>
    <input
      type="file"
      name=""
      id=""
      @change="uploadImg"
      style="position: relative"
    />
    <img :src="this.uploaderUrl" @load="draw" alt="" style="display:none"/>
      <canvas
        id="c"
        width="400"
        height="400"
        style="border: 1px solid red; position: relative; top: 0"
      ></canvas>
  </div>
</template>

script:

<script>
const fabric = window.fabric;
export default {
  name: "fabric-test",
  data() {
    return {
      uploaderUrl: "",
      canvas: "",
    };
  },
  mounted() {
    // this.draw();
  },
  methods: {
    uploadImg(e) {
      let file = e.target.files[0];
      //异步获取文件
      let reader = new FileReader();
      reader.onload = (e) => {
        this.uploaderUrl = e.target.result;
      };
      reader.readAsDataURL(file);
    },
    draw() {
      console.log(this.canvas);
      if (this.canvas) {
        console.log("canvas!!!!");
        this.canvas.dispose(); //释放
      }
      this.canvas = new fabric.Canvas("c");
      let uploadImg = document.createElement("img");
      uploadImg.src = this.uploaderUrl;

      let img = new fabric.Image(uploadImg, {
        left: 30,
        top: 30,
      });
      this.canvas.add(img).setActiveObject(img);
      // 设置边框和缩放隐藏
      // this.canvas.item(0).hasControls = this.canvas.item(0).hasBorders = false;
      // 双指手势取消移动
      this.canvas.on("touch:gesture", () => {
        // getActiveObject 返回当前活动对象
        const activeObj = this.canvas.getActiveObject();
        if (activeObj) {
          activeObj.set({
            lockMovementX: true,
            lockMovementY: true,
          });
        }
      });
      this.canvas.on("mouse:up", () => {
        const activeObj = this.canvas.getActiveObject();
        if (activeObj) {
          activeObj.set({
            lockMovementX: false,
            lockMovementY: false,
          });
        }
      });
    },
  },
};
</script>

1.我把画canvas 的函数放在图片加载之后调用,这样就可以避免 new FileReader() 异步带来的影响

2.重新上传图片我是直接 this.canvas.dispose() 把canvas 直接释放了,然后在new canvas 这样不会影响重新上传 

3.禁止移动 可以参考这个例子的Locked X movement和Locked Y movementCustomization | Fabric.js Demos

我是通过getActiveObject()拿到当前元素,然后改变该元素的属性 

在查看demos 的时候可以使用检查来查看源码,哈哈哈可以收获满满