介绍一个canvas绘图神器zwibbler

官方文档网站:https://zwibbler.com/docs/

这个插件使用起来超级方便,它已经实现了画笔、画基本几何图形、橡皮擦、放大缩小等功能,具体大家可以参考官方介绍文档(文档是英文的)

废话不多说,先上效果图

源码如下(vue+elementui编写的)

<template>
  <div class="pgtp">
     <div id="zwibbler" style="margin-left:auto;margin-right:auto;" :style="{width:CWidth,height:CHeight}">

     </div>
    <div class="tools">
         <x-button mini class="tools_button" @click.native="showColor = true"><img src="../../../static/img/tools/color.png" class="tools_img"/></x-button>
         <x-button mini class="tools_button" @click.native="pen(true)"><img src="../../../static/img/tools/pen.png" class="tools_img"/></x-button>
         <x-button mini class="tools_button" @click.native="true1"><img src="../../../static/img/tools/true.png" class="tools_img"/></x-button>
         <x-button mini class="tools_button" @click.native="error1"><img src="../../../static/img/tools/false.png" class="tools_img"/></x-button>
         <x-button mini class="tools_button" @click.native="rect"><img src="../../../static/img/tools/juxing.png" class="tools_img"/></x-button>
         <x-button mini class="tools_button" @click.native="arrow"><img src="../../../static/img/tools/jiantou.png" class="tools_img"/></x-button>
         <x-button mini class="tools_button" @click.native="text"><img src="../../../static/img/tools/text.png" class="tools_img"/></x-button>
         <br>
         <x-button mini class="tools_button" @click.native="scale(-1)"><img src="../../../static/img/tools/xiao.png" class="tools_img"/></x-button>
         <x-button mini class="tools_button" @click.native="scale(1)"><img src="../../../static/img/tools/da.png" class="tools_img"/></x-button>
         <x-button mini class="tools_button" @click.native="eraser"><img src="../../../static/img/tools/xiangpi.png" class="tools_img"/></x-button>
         <x-button mini class="tools_button" @click.native="back"><img src="../../../static/img/tools/back.png" class="tools_img"/></x-button>
         <x-button mini class="tools_button" @click.native="clear"><img src="../../../static/img/tools/clear.png" class="tools_img"/></x-button>
         <x-button mini class="tools_button" @click.native="saveTu"><img src="../../../static/img/tools/save.png" class="tools_img"/></x-button>
         <x-button mini class="tools_button" @click.native="close"><img src="../../../static/img/tools/close.png" class="tools_img"/></x-button>
    </div>
     <popup v-model="showColor">
            <popup-header 
            left-text="取消" 
           right-text="确定" 
           title="选择颜色"
           @on-click-left="showColor = false"
           @on-click-right="showColor = false"></popup-header>
            <div class="color_tool">
                <span class="color_item" style="background:red" @click="selectColor('red')"></span>
                <span class="color_item" style="background:#33CC33" @click="selectColor('#33CC33')"></span>
                <span class="color_item" style="background:#0099FF" @click="selectColor('#0099FF')"></span>
                <span class="color_item" style="background:#FF9933" @click="selectColor('#FF9933')"></span>
                <span class="color_item" style="background:#CC3366" @click="selectColor('#CC3366')"></span>
                <span class="color_item" style="background:#CC0033" @click="selectColor('#CC0033')"></span>
                <span></span>
            </div>
        </popup>
  </div>
  
</template>

<script>
import { Toast } from 'mint-ui';
export default {
    props: ['dataInfo'],
    watch:{
        dataInfo(val1,val2){
            this.dataInfo  = val2
        }
    },
    data(){
        return {
            zwibbler:{},
            showColor:false,
            color:'red',
            CWidth:0,
            CHeight:0,
            scaleSize:1,
        }
    },created(){
         this.CWidth = document.body.clientWidth+"px" //获取图片的宽
        this.CHeight = document.body.clientHeight-86+"px";//获取图片的高
    },mounted(){
        let this_ = this;
        this.init();
    },
    methods:{
        init(){
             let path = "../../../static/img/tools/"
            this.zwibbler = Zwibbler.create("zwibbler", {
                    showToolbar: false,
                    showColourPanel: true,
                    defaultBrushWidth: 2,
                    showColourPanel:false,
                    //效果图如下 显示工具栏 和下方色彩栏
            });
            this.zwibbler.setConfig("backgroundImage", this.dataInfo.imgSrc+'?tamp='+(new Date()).valueOf());
            this.pen();
        },
        selectColor(color){
            this.color = color;
            this.showColor = false;
            this.pen();
        },
        scale(type){
            if(type==-1){//缩小
                 this.zwibbler.zoomOut()
            }
            if(type==1){//放大
                 this.zwibbler.zoomIn()
            }
        },
        eraser(){
            this.zwibbler.useBrushTool({
                lineWidth: 20,
                strokeStyle: "erase",
                // optional: prevents the user from being able to move the erase stroke.
                layer: "my_eraser_layer"
            });
        },
       pen(){
           this.zwibbler.useBrushTool(
               {
                   lineWidth: 4,
                   strokeStyle:this.color
               }
           );
       },
       arrow(){
          this.zwibbler.useArrowTool({
              fillStyle:this.color,
              lineWidth:4
          },true) 
       },
       text(){
           this.zwibbler.useTextTool({
               strokeStyle:this.color,
               fillStyle:this.color,
               wrap:true,
           },true);
       },
       true1(){
           this.zwibbler.useStampTool({
                url: "/static/img/tools/true1.png",
                lockSize: false,
                width: 16,
            }, true);
       },
       error1(){
            this.zwibbler.useStampTool({
                url: "/static/img/tools/false1.png",
                lockSize: false,
                width: 16,
            }, true);
       },
       rect(){
            this.zwibbler.useRectangleTool({
                lineWidth: 2,
                strokeStyle:this.color
            },true);
       },
       back(){
            this.zwibbler.undo();
       },
       clear(){
            this.zwibbler.destroy();
            this.init();
       },
       saveTu(){
            let this_ = this;
           
            let imgs = new Image();;
            imgs.setAttribute('crossOrigin', 'anonymous');
            imgs.onload= function(){
                let tempCanvas = document.createElement("canvas"); 
                tempCanvas.width = imgs.width
                tempCanvas.height = imgs.height
                let tempCtx = tempCanvas.getContext('2d');  
                let imageObj = document.createElement('img');
                imageObj.src = this_.zwibbler.save('png',{x:0,y:0,width:imgs.width,height:imgs.height});
                imageObj.onload = function(){
                    tempCtx.drawImage(imgs,0,0,imgs.width,imgs.height);
                    tempCtx.drawImage(imageObj,0,0,imgs.width,imgs.height);
                    tempCanvas.toBlob(function(data){
                        //上传文件到服务器
                        let formData = new FormData();
                        formData.append('file',data)
                        var xhr = new XMLHttpRequest();
                        xhr.open('post','/xclient/upload_origin.do','true');
                        xhr.send(formData);
                        xhr.onload = function(){
                            let result = JSON.parse(this.response)
                            if(result.respCode == '0000'){
                                this_.dataInfo.imgSrc = result.fileUrl;
                                this_.$emit('changePgzy',false);
                                this_.$emit('changeDataInfo', this_.dataInfo);
                            }else{
                                Toast({
                                    message: '批改保存失败',
                                    position: 'bottom',
                                    duration: 1000
                                });
                            }
                        } 
                    })
                }
            }
            imgs.src = this_.dataInfo.imgSrc+'?tamp='+(new Date()).valueOf();
       },
       close(){
           this.$emit('changePgzy',false);
       },
    },
}
</script>

<style scoped >
.tools{
     text-align:left;
     height: 70px;
     line-height: 35px;
     padding: 0px 8px;
     bottom: 10px;
     position: absolute;
 }
 .tools_img{
    width:12px;
    height:12px;
 }
 .tools_button{
     margin-top: 0px !important;
     width: 12%;
 }
.color_tool{
     background-color:rgba(0,0,0,0) ;
     height: 40px;
     padding: 15px 0px;
 }
 .color_item{
     display: inline-block;
     width: 40px;
     height: 40px;
     margin-left:10px ;
     border-radius: 20px;
 }
</style>

最后附上一个同僚的github:https://github.com/Lilystudy/zwibbler

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值