本文实例为大家分享了fabricjs实现diy明信片功能的具体代码,供大家参考,具体内容如下
前言
要求需要添加,拷贝,删除,双指放大缩小。
提示:以下是本篇文章正文内容,下面案例可供参考
一、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>
//参考链接
//文末查看比较详细的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>
实现效果
总结
具体一些方法知识点建议大家可以去参考一下这篇文章