我是靠谱客的博主 机灵学姐,最近开发中收集的这篇文章主要介绍使用fabricjs制作一个diy明信片功能前言一、fabric.js是一个很好用的 canvas 操作插件二、代码示例实现效果总结,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

用fabric.js做一个明信片diy功能

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

    • **用fabric.js做一个明信片diy功能**
  • 前言
  • 一、fabric.js是一个很好用的 canvas 操作插件
  • 二、代码示例
  • 实现效果
  • 总结


前言

要求需要添加,拷贝,删除,双指放大缩小。


提示:以下是本篇文章正文内容,下面案例可供参考

一、fabric.js是一个很好用的 canvas 操作插件

示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。

二、代码示例

代码如下(示例):

<!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);" >添加图片</div>
    <div class="end" onclick="linkcanvas()">生成图片</div>
    <button id="inline-btn" onclick="canvasonclick()">删除图片按钮</button>
    <button id="addinline-btn" onclick="copy()">复制图片按钮</button>
    <canvas id="c"></canvas>
</body>
</html>
<script>
    //参考链接
    //https://blog.csdn.net/daicooper/article/details/79800718    比较详细的API中文解释
    //http://fabricjs.com/     fabric.js官网

    //diy功能需要有复制功能 删除功能 放大缩小移动旋转

    //添加新图片
    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),//图片左右居中
                    top: webheight - (webheight / 2), //图片上下居中 ,屏幕高度-(图片高度/2)的总值/2
                    angle: 0, //角度为0
                    originX: 'center',
                    originY: 'center',
                });
                //图片默认宽度充满屏幕一边留白20 高度自适应
                img.scaleToWidth(webwidth - 40)
                canvas.add(img).setActiveObject(img);
                //清除线条
                img.hasBorders = false;
                //自定义图片功能按钮  , 隐藏多余功能按钮,只保留4个角的按钮
                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 btn = document.getElementById('inline-btn')
    // 添加按钮            
    var addbtn = document.getElementById('addinline-btn')

    // 获取屏幕高宽度 
    var webwidth = $(window).width()
    var webheight = $(window).height()
    //创建画板
    var canvas = new fabric.Canvas('c');
    //canvas默认充满屏幕
        canvas.setWidth(webwidth)
        canvas.setHeight(webheight)
        //导入图片 
        fabric.Image.fromURL('./imgs/2.jpg', function (img) {
            img.scale(1).set({
                left: webwidth - (webwidth/2),//图片左右居中
                top: webheight-(webheight/2), //图片上下居中 ,屏幕高度-(图片高度/2)的总值/2
                angle: 0, //角度为0
                originX: 'center',
                originY: 'center',
            });
            //图片默认宽度充满屏幕一边留白20 高度自适应
            img.scaleToWidth(webwidth-40)
            canvas.add(img).setActiveObject(img);
            //清除线条
            img.hasBorders = false;
            //自定义图片功能按钮  , 隐藏多余功能按钮,只保留4个角的按钮
            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);
            })
        });

        //取消多选
        canvas.selection = false;
        //新建图层不出现在顶层      
        canvas.preserveObjectStacking = true;        
        //注:要自定义修改按钮功能需要引入fabric的另一个叫customiseControls的JS插件 否则无法操作
        //全局修改4个按钮的功能
        fabric.Canvas.prototype.customiseControls({
            bl: {
                action: 'rotate' //添加图片旋转功能
            },
            // only is hasRotatingPoint is not set to false
        }, function () {
            canvas.renderAll();
        });   

        //因为默认的按钮样式不是我们想要的 所以需要自定义一些icon在上面
        fabric.Object.prototype.customiseCornerIcons({
            tl: {
                icon: './img/+1@2x.png',  //图片路径
                cornerSize: 70,      //按钮点击范围 相当于css的padding属性
                settings: {
                    cornerSize: 25 //icon大小
                },        
            },
            tr: {
                icon: './img/X@2x.png',
                cornerSize: 70,   
                settings: {
                    cornerSize: 25
                },                  
            },
            bl: {
                icon: './img/xuanzhuan@2x.png',
                cornerSize: 70,   
                settings: {
                    cornerSize: 25
                },                  
            },
            br: {
                icon: './img/fangda@2x.png',
                cornerSize: 70,
                settings: {
                    cornerSize: 25
                },                  
            },
        }, function () {
            canvas.renderAll();
        }); 

        //按钮跟随图片定位
        function positionBtn(obj) {
            //获取当前选中图片单位参数
            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,
            };
        }


        //删除当前选中图片
        function canvasonclick(){
            var t = canvas.getActiveObject()
            canvas.remove(t);
        }

        //拷贝当前选中图片
        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();
            // 再次克隆,这样你就可以复制多个副本。
            t.clone(function (clonedObj) {
                canvas.discardActiveObject();
                clonedObj.set({
                    left: clonedObj.left + 20,
                    top: clonedObj.top + 20,
                    evented: true,
                    hasBorders:false
                });
                if (clonedObj.type === 'activeSelection') {
                    // 活动选择需要对画布的引用。
                    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);
                        })                                           
                    });
                    // 解决不可选择的问题
                    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 = {}
        //计算平均值
        var getDistance = function (start, stop) {
            return Math.hypot(stop.x - start.x, stop.y - start.y);
        };        

        //监听positionBtn事件  鼠标以上点击图片时移动时触发我们自定义的复制按钮和删除按钮跟随图片定位以及双指放大缩小功能
        canvas.on('mouse:down',function(options){
            //判断是否点击到了图片单位
            if(options.target){
                //运行事件
                positionBtn(options.target);

                //双指放大缩小
                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           
            }
        });  

        //生成明信片
        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>



实现效果

在这里插入图片描述

总结

具体一些方法知识点建议大家可以去参考一下这篇文章https://blog.csdn.net/daicooper/article/details/79800718

最后

以上就是机灵学姐为你收集整理的使用fabricjs制作一个diy明信片功能前言一、fabric.js是一个很好用的 canvas 操作插件二、代码示例实现效果总结的全部内容,希望文章能够帮你解决使用fabricjs制作一个diy明信片功能前言一、fabric.js是一个很好用的 canvas 操作插件二、代码示例实现效果总结所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(37)

评论列表共有 0 条评论

立即
投稿
返回
顶部