用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)的总值/2angle: 0, //角度为0originX: '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)的总值/2angle: 0, //角度为0originX: '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].clientXstore.pageY = options.e.changedTouches[0].clientYif (options.e.changedTouches.length == 2) {store.pageY2 = options.e.changedTouches[1].clientYstore.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 = 0store.pageX = 0store.pageY2 = 0store.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明信片功能相关推荐

  1. ​用树莓派(Raspberry Pi)和机器学习制作一个DIY车牌阅读器

    全文共7733字,预计学习时长23分钟 来源:Pexels 几个月前,笔者有一些想法,想让自己的车能检测和识别物体.笔者之所以有如此想法,主要是因为已经见识了特斯拉的能力,虽然并不想马上买一辆特斯拉( ...

  2. android+蓝牙体温计,如何制作一个带蓝牙功能的电子体温计?

    一. 作品简介 该类型蓝牙电子体温计是以一颗具有高精度ADC的MCU为核心搭配高精度NTC温度传感器及高性能蓝牙4.0模块组成的一款低功耗.高精度.高性能的人体电子体温计. 蓝牙电子体温计需配合手机A ...

  3. 实战教程|使用知晓云快速制作一个简单的个人博客

    我们在向大家征集开发课程大纲后,便陆续收到了很多建议.大家的热情与支持,是我们持续更新的动力. 由于大家的课程建议比较散,需要结合实际案例进行讲解,因此我们先从最简单的开始.本文将介绍如何通过知晓云的 ...

  4. DIY一个低成本多功能点阵时钟!

    大家好,转发一篇正念同学的文章 ---- 大家好,我是ZhengN. 本次转载一篇保姆级的diy教程:基于Esp8266的多功能点阵时钟 . 简介 很早就了解ESP8266了,当时也用这个搞过一些小d ...

  5. php diy明信片代码,用ps制作一张简单的明信片

    这篇教程主要是向PHP中文网的朋友分享用ps简单制作一张明信片方法,教程制作出来的明信片非常漂亮,难度不是很大,推荐到PHP中文网,喜欢的朋友快快来学习吧 明信片对于很多朋友来说是一种纪念品,一般出去 ...

  6. android led闪烁功能,如何在Android应用层中制作一个LED指示灯效果

    如何在Android应用层中制作一个LED指示灯效果 发布时间:2020-12-08 16:12:59 来源:亿速云 阅读:86 作者:Leah 本篇文章给大家分享的是有关如何在Android应用层中 ...

  7. (原创)制作一个采用 LCD1602 显示的电子钟,在 LCD 上显示当前的时间。显示格式为“时时:分分:秒秒”。设有 4 个功能键k1~k4,功能如下:(1)k1——进入时间修改。

    (原创)制作一个采用 LCD1602 显示的电子钟,在 LCD 上显示当前的时间.显示格式为"时时:分分:秒秒".设有 4 个功能键k1-k4,功能如下: (1)k1--进入时间修 ...

  8. 【UE4】模仿《黑暗之魂》系列游戏制作一个简单的锁定敌人的功能

    这是我拆解游戏项目的CameraSystem做出的一点点小总结,然后写了一个非常非常简单的锁定敌人的功能: 第一步:设置敌人属性,标志为可被锁定 创建一个敌人蓝图,随便搞个模型进去 创建一个接口蓝图, ...

  9. 魔兽怎样利用编辑器制作一个能够利用漂浮文字显示伤害的功能

    魔兽编辑器使用脚本语言来制作功能,可以使用 Trigger 编辑器来制作一个触发器,在触发时显示伤害数值. 具体步骤如下: 打开魔兽编辑器,在触发器编辑器中新建一个触发器. 在触发器的事件中添加&qu ...

最新文章

  1. python urllib.request 爬虫 数据处理-Python爬虫学习之(二)| urllib进阶篇
  2. linux下安装mysql的方式_linux下安装mysql的两种方式
  3. 【Node.js】http-server 实现目录浏览服务
  4. 北方大学 ACM 多校训练赛 第十五场 蜘蛛牌A
  5. php一对一模型关联,通过实例学习Laravel模型中的一对一关联关系
  6. 关于js数组的六种算法---水桶排序,冒泡排序,选择排序,快速排序,插入排序,希尔排序的理解。...
  7. Amber Group创始人兼CEO Michael Wu:CBDC将成为更广义、重要的加密资产
  8. 装饰器模式(Decorator Pattern)
  9. 如何使用ShoeBox和PhotoShop制作出漂亮的Fnt字体
  10. 【安全狗高危安全通告】2月“微软补丁日” 发布多个高危漏洞
  11. natapp反向代理
  12. 系统集成项目管理工程师章节重点第一章
  13. linux每周2 4 6执行定时任务,linux计划任务crontab例子
  14. 《那些年啊,那些事——一个程序员的奋斗史》六
  15. 伊对和连信交友相亲聊天平台靠谱吗?
  16. 扩展卡尔曼滤波soc估算 基于EKF算法的锂电池SOC
  17. GTD时间管理简洁做法
  18. 时域变换到频域?到底什么是傅里叶变换?
  19. 七夕节送男朋友什么礼物、男生最渴望收到的礼物排行榜
  20. Checkout和Rest的所有谜题(git reset --files是要改一下)

热门文章

  1. ALRE-IT JDW5
  2. gitbook打包镜像
  3. 如何使用 Docker 安全地试用软件
  4. 编译原理中关于T形图的理解
  5. 如何在VC中使用7z SDK压缩文件
  6. 手写Spring-第七章-钩直饵咸?虚拟机钩子与bean的初始化和销毁
  7. 达人评测 R7 7735HS和R7 6800Hs选哪个 锐龙R77735HS和6800hs对比
  8. 【图文详解】搭建 Spring Authorization oauth2-server-resource-client-gateway-eureka 完整Demo
  9. matlab绘制庞加莱截面_matlab庞加莱截面法画Lorenz系统分岔图(附图).doc
  10. 手机浏览器服务器重置怎么办,移动路由器恢复出厂设置后怎么重新设置?