一、序
如题,最近工作中遇到一个移动端用户上传照片,然后在线编辑,添加一些别的图片合成的功能,类似于超级简化版美图秀秀。总结了一下,大致操作包含 上传图片,图片压缩、触摸拖动图片、放大/缩小、添加别的图片进行合成,最后生成一张新图片。功能比较多,问遍了度娘,也没什么系统的有用信息。蛋疼。。。于是挽起袖子自己撸代码。此过程略痛苦,手机型号不同,兼容性问题比较多。这个我会一一细说。
额外话,这个demo还涉及到 微信分享,手机验证码,这些代码也没有删,感兴趣的可以看看。
废话不多说,下面是目录。先看效果图,然后我再简单说说实现过程,把源码贴出来, 有需要的可以去我的 github 下载源码。
二、目录
1.效果图
2.原理
3.问题分析、解决方案
4.demo下载
1.效果图
2.原理
图片处理,直接想到 canvas , 这里也是用画布来做的,分析下流程需要上传、编辑、生成新图 这3个步骤。
a. 上传。 input 文件上传,然后将上传的文件转换为 base64 的格式,这里主要做图片的处理。
b. 压缩。通过画布将上传的图片进行等比例压缩,图片一般会压缩到100KB左右,具体的看宽高设置,会大、会小。不压缩,无法在线编辑,图片太大了,会卡的要命。
c. 拖拽。将图片设置为背景图,捕捉 touch 坐标,进行计算,调整图片的横纵坐标。此 demo 电脑手机通用,只需要将 touch 部分的坐标值改成 mouseX,mouseY 或者 clientX、clientY即可。
d. 图片的裁剪、放大、缩小,旋转。裁剪是根据背景图的坐标,设置画布大小裁剪图片。缩放、旋转,canvas有api,主要做数据的计算。这里这些操作没有采用touch的手势计算。因为我的素材很小,手指操作不方便。所以加的按钮,如果想做手势的逻辑类似,做一下坐标转换即可。
d. 图片合成。还是canvas的api,添加图片,然后编辑一番,最终保存成base64,传给后台,生成一张图片,本地生成没办法直接使用。所以配合服务端生成最合适。
e. demo引入了 jQuery ,请使用1.1以上版本的 jQuery ,我用的是 jquery-1.11.3.min.js 。
3.问题分析、解决方案
现在说一下做这个东西遇到的问题,也说明一下为什么会写这么多代码
a、canvas 兼容性,IOS8.0 以上,低了貌似都不支持。安卓不太清楚,低级版本肯定是不行了。市面上的手机基本都是OK的。
b、reader.readAsDataURL(oFile) 手机上传图片,iOS不支持 FileReader 的onload回调,无奈,加了 setTimeout 做延时处理。
c、手机上传的图片有横屏的,有竖屏的。超级麻烦,导致我们不知道哪个是宽,而且默认展示总不能倒着展示吧。这里引入 exif.js 这个js包可以判断照片的拍摄角度。牛逼啊。拿到拍摄角度之后,我们就可以放到画布里面,再把它旋转,压缩一下。就OK了。
d、手机的图片太大。现在手机照片动不动就好几MB,画布处理图片是转化成base64计算的,想想吧,一张几兆的图,转换成base64,还得大20%左右,用它编辑,页面一般就卡死了。所以上传成功后,先把图片用画布压缩到100KB以内,这个大小清晰度和处理速度是比较合适的。
e、压缩图片的时候还有个问题。canvas 的实际大小一定是显示大小的2倍,这样图片才不会是真,否则,你会发现你的图片超级模糊,和马赛克差不多了。
f、图片移动,这个比较简单了,就是注意移动端、PC端获取到事件对象后,坐标属性名不同,记得别搞错了。
g、最后图片的生成。canvas 最终生成的是base64,他可以直接保存成图片,不过保存之后我们就取不到了,所以建议发到服务端,服务端生成,返回公网链接。
4.demo下载
以上就是整个项目了,有什么问题,可以评论区留言。
源代码,我会上传到 github ,如果帮到你了,记得给个 star 奥。 下载
核心代码:
(function (win) {
var obj = {
a: 1,
oldX: "",
oldY: "",
ratio: 1,
ratioBig: 0,
jsonUrl: 'https://xxxxxxx/api/xxxx',
radioSmall: 0,
num: 1,
setWidth: 432, //图片需要压缩到的尺寸 216,135
theDataBase: "",
yaSuoBase64: "",
hcBase64: "",
image: new Image(), //放到画布的img
bookCode: 12221212,
flag: true,
bodyWidth: '',
bodyHeight: '',
ifImgUpload: false,
base64Zong: "",
imgNewName: "",
//首页的js。横竖屏、微信分享、滑动跳转
page1Init: function () {
var w = this;
if ($(win).width() >= $(win).height()) {
w.bodyWidth = parseInt($(window).height()) + 64;
w.bodyHeight = $(window).width();
$('body,html').width(w.bodyWidth);
$('body,html').height(w.bodyHeight);
} else {
w.bodyWidth = $(window).width();
w.bodyHeight = $(window).height();
$('body,html').width(w.bodyWidth);
$('body,html').height(w.bodyHeight);
}
window.addEventListener("onorientationchange" in window ? "orientationchange" : "resize", function () {
if (window.orientation === 180 || window.orientation === 0) {
$('body,html').width(bodyWidth);
$('body,html').height(bodyHeight);
}
if (window.orientation === 90 || window.orientation === -90) {
$('body,html').width(bodyWidth);
$('body,html').height(bodyHeight);
}
}, false);
// 初始化微信分享的
// w.wxConfig();
// w.wxReady();
var oldX = 0, oldY = 0;
$("body").on("touchstart", imgTouchStart);
$("body").on("touchmove", imgTouchMove);
//手指按下时,捕捉事件,取坐标值,设置参数
function imgTouchStart(e) {
//阻止事件冒泡的
e.stopImmediatePropagation();
oldX = e.originalEvent.touches[0].clientX;
oldY = e.originalEvent.touches[0].clientY;
}
function imgTouchMove(e) {
e.stopImmediatePropagation();
var x = e.originalEvent.touches[0].clientX - oldX;
var y = e.originalEvent.touches[0].clientY - oldY;
if (y < -150) {
window.location.href = 'getBooks.html?';
}
}
},
//上传照片页的js。横竖屏、微信分享、上传照片
page2Init: function () {
var w = this;
if ($(win).width() >= $(win).height()) {
w.bodyWidth = parseInt($(window).height()) + 64;
w.bodyHeight = $(window).width();
$('body,html').width(w.bodyWidth);
$('body,html').height(w.bodyHeight);
} else {
w.bodyWidth = $(window).width();
w.bodyHeight = $(window).height();
$('body,html').width(w.bodyWidth);
$('body,html').height(w.bodyHeight);
}
window.addEventListener("onorientationchange" in window ? "orientationchange" : "resize", function () {
if (window.orientation === 180 || window.orientation === 0) {
$('body,html').width(bodyWidth);
$('body,html').height(bodyHeight);
}
if (window.orientation === 90 || window.orientation === -90) {
$('body,html').width(bodyWidth);
$('body,html').height(bodyHeight);
}
}, false);
// w.wxConfig();
// w.wxReady3();
//上传图片进行处理
w.uploadImg();
if (localStorage.getItem("imgFlag") == "true") {
$(".f-scInLock").hide();
}
//选好照片,准备制作
$('.m-loadBtn').on("tap", function () {
$('.m-loadBtn').css({"color": "#C64100"});
setTimeout(function () {
$('.m-loadBtn').css({"color": "white"});
}, 300);
if (w.ifImgUpload == true) {
$('.g-wrap2').hide();
$('.g-wrap3').show();
$("#m-loadImg").attr("src", w.yaSuoBase64);
} else {
$('.j-pop p').text("还没有选择喜欢照片吆!");
$('.j-pop').show();
setTimeout(function () {
$('.j-pop').hide();
}, 1500);
}
});
$(".m-step1 .f-scIn1").on("tap", function () {
$(".m-sucaiOut").show();
$(".m-sucaiOut").css({"width": "70px", "opacity": "1"});
$(".m-imgBox .f-sucai").attr("src", "img/sucai1.png");
});
$(".m-step1 .f-scIn2").on("tap", function () {
$(".m-sucaiOut").show();
$(".m-sucaiOut").css({"width": "70px", "opacity": "1"});
$(".m-imgBox .f-sucai").attr("src", "img/sucai2.png");
});
$(".m-step1 .f-scIn3").on("tap", function () {
var sucai3 = localStorage.getItem("imgFlag");
if (sucai3 == "true") {
$(".m-sucaiOut").show();
$(".m-sucaiOut").css({"width": "70px", "opacity": "1"});
$(".m-imgBox .f-sucai").attr("src", "img/sucai3.png");
} else {
$('.j-pop p').text("分享后可解锁吆!");
$('.j-pop').show();
setTimeout(function () {
$('.j-pop').hide();
}, 1500);
}
})
$(".f-sucaiDelete").on("tap", function () {
$(".m-sucaiOut").css({"width": "1px", "opacity": "0", "top": "4px", "left": "100px"});
$(".m-imgBox .f-sucai").attr("src", "img/wu.png");
});
$(".m-step2 .f-scIn1").on("tap", function () {
$(".imgKuang .imgK").attr("src", "img/sucai4.png");
});
$(".m-step2 .f-scIn2").on("tap", function () {
$(".imgKuang .imgK").attr("src", "img/sucai5.png");
});
$(".m-makeBtn").on("tap", function () {
$("#loadingSection").show();
setTimeout(function () {
$("#loadingSection").hide();
}, 1800);
w.imageMake();
});
$(".m-getBtn").on("tap", function () {
$(".m-login").show();
$(".m-mengBan").show();
});
$(".m-closeLogin").on("tap", function () {
$(".m-login").hide();
$(".m-mengBan").hide();
});
$(".wx-share").on("tap", function () {
$(".wx-share").hide();
$(".m-mengBan").hide();
});
$(".m-oldManBtn").on("tap", function () {
$(".wx-share").show();
$(".m-mengBan").show();
w.sendImgSouce();
w.wxReady2();
});
w.initEvent();
},
resize: function () {},
wxConfig: function () {
var w = this;
var jsapi_ticket, nonceStr, signature, timestamp, getCode;
var url = 'http://xxxxxxx/'; //正式库
//获取config配置
var Url = window.location.href;
$.ajax({
type: 'get',
url: 'http:/xxxxxxx',
data: {
weixinurl: Url
},
timeout: 10000, //10秒超时
callbackParameter: 'callback',
async: false,
jsonp: "jsonpcallback",
success: function (o) {
jsapi_ticket = o.jsapi_ticket;
nonceStr = o.nonceStr;
signature = o.signature;
timestamp = o.timestamp;
}
});
wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: 'xxxxxxxxx', // 必填,公众号的唯一标识
timestamp: timestamp, // 必填,生成签名的时间戳
nonceStr: nonceStr, // 必填,生成签名的随机串
signature: signature, // 必填,签名,见附录1
jsApiList: [
'checkJsApi',
'onMenuShareTimeline',
'onMenuShareAppMessage',
'onMenuShareQQ',
'onMenuShareWeibo',
'onMenuShareQZone',
'hideMenuItems',
'showMenuItems',
'hideAllNonBaseMenuItem',
'showAllNonBaseMenuItem',
'translateVoice',
'startRecord',
'stopRecord',
'onVoiceRecordEnd',
'playVoice',
'onVoicePlayEnd',
'pauseVoice',
'stopVoice',
'uploadVoice',
'downloadVoice',
'chooseImage',
'previewImage',
'uploadImage',
'downloadImage',
'getNetworkType',
'openLocation',
'getLocation',
'hideOptionMenu',
'showOptionMenu',
'closeWindow',
'scanQRCode',
'chooseWXPay',
'openProductSpecificView',
'addCard',
'chooseCard',
'openCard'
] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
});
},
wxReady: function () {
wx.ready(function () {
wx.onMenuShareAppMessage({
title: '嘿,我愿意做你的圣诞老人!', // 分享标题
link: 'http://xxxxxxxxx/index.html', // 分享链接
desc: '叮叮当,叮叮当,今年你愿意做我的圣诞老人吗……',
imgUrl: 'http://xxxxxxx/wxbanner.png', // 分享图标
trigger: function (res) {
},
success: function (res) {
localStorage.setItem("imgFlag", "true");
},
cancel: function (res) {
}
});
//alert('已注册获取“发送给朋友圈”状态事件');
wx.onMenuShareAppMessage({
title: '嘿,我愿意做你的圣诞老人!', // 分享标题
link: 'http://xxxxxxx/index.html', // 分享链接
desc: '叮叮当,叮叮当,今年你愿意做我的圣诞老人吗……',
imgUrl: 'http://xxxxxxx/wxbanner.png', // 分享图标
trigger: function (res) {
},
success: function (res) {
localStorage.setItem("imgFlag", "true");
},
cancel: function (res) {
}
});
});
},
wxReady3: function () {
wx.ready(function () {
wx.onMenuShareAppMessage({
title: '嘿,我愿意做你的圣诞老人!', // 分享标题
link: 'http://xxxxxx/index.html', // 分享链接
desc: '叮叮当,叮叮当,今年你愿意做我的圣诞老人吗……',
imgUrl: 'http://xxxxxxxxx/wxbanner.png', // 分享图标
trigger: function (res) {
},
success: function (res) {
localStorage.setItem("imgFlag", "true");
$(".f-scInLock").hide();
$(".f-scInLock").css({"width": "0px", "height": "0px", "display": "none"});
},
cancel: function (res) {
}
});
//alert('已注册获取“发送给朋友圈”状态事件');
wx.onMenuShareAppMessage({
title: '嘿,我愿意做你的圣诞老人!', // 分享标题
link: 'http://xxxxxxx/index.html', // 分享链接
desc: '叮叮当,叮叮当,今年你愿意做我的圣诞老人吗……',
imgUrl: 'http://xxxxxxx/img/wxbanner.png', // 分享图标
trigger: function (res) {
},
success: function (res) {
localStorage.setItem("imgFlag", "true");
$(".f-scInLock").hide();
$(".f-scInLock").css({"width": "0px", "height": "0px", "display": "none"});
},
cancel: function (res) {
}
});
});
},
wxReady2: function () {
var w = this;
wx.ready(function () {
wx.onMenuShareAppMessage({
title: '嘿,我愿意做你的圣诞老人!', // 分享标题
link: 'http://xxxxxxx/sharePage.html?imgName=' + w.imgNewName, // 分享链接
desc: '叮叮当,叮叮当,今年你愿意做我的圣诞老人吗……',
imgUrl: 'http://xxxxx/img/wxbanner.png', // 分享图标
trigger: function (res) {
},
success: function (res) {
localStorage.setItem("imgFlag", "true");
$(".wx-share").hide();
$(".m-mengBan").hide();
$(".f-scInLock").hide();
$(".f-scInLock").css({"width": "0px", "height": "0px", "display": "none"});
},
cancel: function (res) {
}
});
//alert('已注册获取“发送给朋友圈”状态事件');
wx.onMenuShareAppMessage({
title: '嘿,我愿意做你的圣诞老人!', // 分享标题
link: 'http://xxxxx/sharePage.html?imgName=' + w.imgNewName, // 分享链接
desc: '叮叮当,叮叮当,今年你愿意做我的圣诞老人吗……',
imgUrl: 'http://xxxxxx/img/wxbanner.png', // 分享图标
trigger: function (res) {
},
success: function (res) {
localStorage.setItem("imgFlag", "true");
$(".wx-share").hide();
$(".m-mengBan").hide();
$(".f-scInLock").hide();
$(".f-scInLock").css({"width": "0px", "height": "0px", "display": "none"});
},
cancel: function (res) {
}
});
});
},
//照片上传函数
uploadImg: function () {
var w = this;
var loadFile = document.getElementById("file");
loadFile.addEventListener("change", function () {
$(".m-thewen33").hide();
$(".m-thewen").show();
$(".f-theImg").css({"width": "100%"});
w.ifImgUpload = true;
$("#loadingSection").show();
setTimeout(function () {
$("#loadingSection").hide();
}, 2700);
var oFile = loadFile.files[0];
console.log(oFile);
if (!new RegExp("(jpg|jpeg|png)+", "gi").test(oFile.type)) {
alert("照片上传:文件类型必须是JPG、JPEG、PNG");
return;
}
//新建一个文件对象
var reader = new FileReader();
//读出这个文件的 base64 的数据流,这个函数是专门转base64的,不加他,下面没法用base64
reader.readAsDataURL(oFile);
//因为 iOS 不支持 FileReader 的onload回调,所以,这里只能加延迟处理了
setTimeout(function () {
//先取照片的拍摄方向角
EXIF.getData(oFile, function () {
EXIF.getAllTags(this);
var zzz = EXIF.getTag(this, 'Orientation');
var spanData = document.getElementsByClassName("tspanme");
if (zzz == 1 || zzz == undefined) {
spanData[0].innerText = 0;
// alert("0度");
// console.log("0度");
} else if (zzz == 6) {
spanData[0].innerText = 90;
// alert("90度");
// console.log("90度");
} else if (zzz == 8) {
spanData[0].innerText = 270;
// alert("270度");
// console.log("270度");
} else if (zzz == 3) {
spanData[0].innerText = 180;
// alert("180度");
// console.log("180度");
}
});
var img = new Image();
img.src = reader.result;
//根据拍摄角度不同,把图片旋转适当角度,纠正图片
//除了修改方向,不做其他任何修改
setTimeout(function () {
var spanData = document.getElementsByClassName("tspanme");
var theText = spanData[0].innerText;
console.log("这个保存的角度" + theText);
var canvas = document.createElement("canvas");
var cantent = canvas.getContext("2d");
var width = img.naturalWidth,
height = img.naturalHeight;
if (theText == 0) { //0
canvas.width = width;
canvas.height = height;
cantent.drawImage(img, 0, 0, width, height, 0, 0, width, height);
console.log("0");
} else if (theText == 90) {
canvas.width = height;
canvas.height = width;
cantent.save();
cantent.rotate(90 * Math.PI / 180);
cantent.drawImage(img, 0, -height);
cantent.restore();
console.log("90");
} else if (theText == 180) {
canvas.width = width;
canvas.height = height;
cantent.save();
cantent.rotate(180 * Math.PI / 180);
cantent.drawImage(img, -width, -height);
cantent.restore();
console.log("180");
} else if (theText == 270) {
canvas.width = height;
canvas.height = width;
cantent.save();
cantent.rotate(270 * Math.PI / 180);
cantent.drawImage(img, -width, 0);
cantent.restore();
console.log("270");
}
w.theDataBase = canvas.toDataURL();
setTimeout(function () {
w.yaSuoImg();
}, 200);
}, 300);
}, 400);
})
},
//处理图片的函数
imageMake: function () {
var w = this,
theAngle = 0,
imgHat = document.getElementsByClassName("f-sucai")[0];
theAngle = getEletAngle();
console.log("当前素材的角度:" + theAngle);
var canvasHat = document.createElement("canvas"),
cantentHat = canvasHat.getContext("2d"),
widthHat = imgHat.naturalWidth,
heightHat = imgHat.naturalWidth;
console.log(widthHat);
console.log(heightHat);
console.log(theAngle);
canvasHat.width = widthHat;
canvasHat.height = heightHat;
cantentHat.save();
cantentHat.translate(widthHat / 2, heightHat / 2);
cantentHat.rotate(theAngle * Math.PI / 180);
cantentHat.translate(-widthHat / 2, -heightHat / 2);
cantentHat.drawImage(imgHat, 0, 0);
cantentHat.restore();
imgHat.src = canvasHat.toDataURL();
setTimeout(function () {
var img1 = document.getElementById("m-loadImg"),
width = img1.naturalWidth,
height = img1.naturalHeight,
canvas = document.createElement("canvas"),
cantent = canvas.getContext("2d"),
oldTop = $("#m-loadImg")[0].offsetTop,
oldLeft = $("#m-loadImg")[0].offsetLeft,
imgK = document.getElementsByClassName("imgK")[0],
imgKuangOut = document.getElementsByClassName("imgKuang")[0],
imgSuCai = document.getElementsByClassName("f-sucai")[0],
imgSuCaiOut = document.getElementsByClassName("m-sucaiOut")[0],
//缩放之后图片的宽度
scWidth = imgSuCai.width,
scHeight = imgSuCai.height,
scOffsetTop = imgSuCaiOut.offsetTop,
scOffsetLeft = imgSuCaiOut.offsetLeft;
// console.log("------------------------");
// console.log(imgSuCai);
// console.log(imgSuCaiOut);
// console.log(scWidth);
// console.log(scHeight);
// console.log(scOffsetTop);
// console.log(scOffsetLeft);
canvas.width = 270;
canvas.height = 194;
// console.log("原大小:");
// console.log(img1.naturalWidth);
// console.log(img1.naturalHeight);
// console.log(imgK.naturalWidth);
// console.log(imgK.naturalHeight);
// console.log("相框的上定位" + imgK.offsetTop);
// console.log("相框的下定位" + imgK.offsetLeft);
//
// console.log("插入素材的数据:");
// console.log(scWidth);
// console.log(scHeight);
// console.log(scOffsetTop);
// console.log(scOffsetLeft);
var yasuobi = width / 270;
// console.log("压缩之后的宽度" + width);
// console.log("position的上定位" + oldTop);
// console.log("position的左定位" + oldLeft);
// alert(-oldLeft*yasuobi+"水平位移");
// alert(-oldTop*yasuobi+"垂直位移");
setTimeout(function () {
//画上照片
cantent.drawImage(img1, 0, 0, width, height, oldLeft, oldTop, 270, height / yasuobi);
//画上素材
cantent.drawImage(imgSuCai, 0, 0, imgSuCai.naturalWidth, imgSuCai.naturalHeight, scOffsetLeft, scOffsetTop, scWidth, scHeight);
//画上相框
cantent.drawImage(imgK, 0, 0, imgK.naturalWidth, imgK.naturalHeight, imgKuangOut.offsetLeft, imgKuangOut.offsetTop, imgK.width, imgK.height);
w.hcBase64 = canvas.toDataURL();
//做最终的合成
var imgZong = new Image();
imgZong.src = w.hcBase64;
setTimeout(function () {
var canvas111 = document.createElement("canvas"),
cantent111 = canvas111.getContext("2d"),
imgKuangTrue = document.getElementById("g-kuangTrue"),
theEWM = document.getElementById("g-ewm");
canvas.width = 326.5;
canvas.height = 335;
cantent.drawImage(imgKuangTrue, 0, 0, imgKuangTrue.naturalWidth, imgKuangTrue.naturalHeight, 0, 0, 326.5, 335);
cantent.drawImage(imgZong, 0, 0, imgZong.naturalWidth, imgZong.naturalHeight, 28, 47, 270, 194);
cantent.drawImage(theEWM, 0, 0, theEWM.naturalWidth, theEWM.naturalHeight, 236, 249, 64, 64);
w.base64Zong = canvas.toDataURL();
setTimeout(function () {
$(".g-wrap3").hide();
$(".g-wrap4").show();
$(".f-shuchu").attr("src", w.base64Zong);
}, 400)
}, 500)
// console.log("合成的图片");
//console.log(w.theDataBase.length/1024+"KB");
}, 400)
}, 700)
},
//压缩函数
yaSuoImg: function () {
var w = this;
yaWidth = w.setWidth / 2, // yaWidth 这个是实际照片一半的大小,通过设置它实现压缩
canvas = document.createElement("canvas"),
cantent = canvas.getContext("2d"),
img = new Image();
img.src = w.theDataBase;
//这个iOS是支持的,iOS不支持的是file对象的onload函数
img.onload = function () {
var width = img.naturalWidth,
height = img.naturalHeight,
//图片的压缩比
theRadio = img.naturalWidth / yaWidth;
//如果图片尺寸小于设定画布的尺寸,不压缩,输出原图
if (theRadio <= 1) {
theRadio = 1;
canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight;
canvas.style.width = img.naturalWidth / 2 + "px";
canvas.style.height = img.naturalHeight / 2 + "px";
cantent.drawImage(img, 0, 0, width, height, 0, 0, width, height);
} else {
//为了避免失真,canvas实际大小设置为显示大小的2倍
canvas.width = yaWidth * 2;
canvas.height = (height / theRadio) * 2;
canvas.style.width = yaWidth + "px";
canvas.style.height = height / theRadio + "px";
//注意,图片要取实际大小裁剪,但是显示大小选择和canvas同样的大小,这样显示的不失真、小,但实际的大。不失真
cantent.drawImage(img, 0, 0, width, height, 0, 0, yaWidth * 2, height / theRadio * 2);
console.log("压缩之后的图片大小,宽: " + yaWidth * 2 + "高: " + height / theRadio * 2);
}
// console.log("************************");
// console.log(theRadio);
// console.log(width);
// console.log(height);
// console.log(yaWidth * 2);
// console.log((height / theRadio) * 2);
w.yaSuoBase64 = canvas.toDataURL();
setTimeout(function () {
$(".g-wrap2 .f-theImg").attr("src", w.yaSuoBase64);
// console.log("压缩之后大小");
// console.log(w.yaSuoBase64.length / 1024 + "KB");
// alert("压缩之后大小:"+w.yaSuoBase64.length/1024+"KB");
}, 200)
};
},
initEvent: function () {
var w = this;
$('.getCode').on('tap', function () {
$('.m-phone').blur();
$('.m-code').blur();
var phoneNum = $('.m-phone').val();
if (phoneNum == '') {
$('.j-pop').fadeIn();
$('.j-pop p').text('手机号不能为空');
setTimeout(function () {
$('.j-pop').fadeOut();
}, 2000);
return false;
} else if (!/^1[3|4|5|7|8][0-9]{9}$/.test(phoneNum)) {
$('.j-pop').fadeIn();
$('.j-pop p').text('手机号格式不正确');
setTimeout(function () {
$('.j-pop').fadeOut();
}, 2000);
return false;
}
if (w.flag == true) {
w.codeAjax();
var time = 60;
$('.getCode').attr("disabled", "disabled");
w.flag = false;
var t = setInterval(function () {
time--;
$('.getCode').text(time + "s后再发送");
$('.getCode').css("background", '#EFEFEF');
$('.getCode').css("color", 'gray');
if (time == 0) {
$('.getCode').removeAttr('disabled');
clearInterval(t);
$('.getCode').text("获取验证码");
w.flag = true;
$('.getCode').css("color", '#CB402F');
}
}, 1000);
}
});
$('.m-getBook').on('tap', function () {
var codeTxt = $('.m-code').val();
var phoneNum = $('.m-phone').val();
if (phoneNum == '') {
$('.j-pop').fadeIn();
$('.j-pop p').text('手机号不能为空');
setTimeout(function () {
$('.j-pop').fadeOut();
}, 2000);
} else if (codeTxt == '') {
$('.j-pop').fadeIn();
$('.j-pop p').text('验证码不能为空');
setTimeout(function () {
$('.j-pop').fadeOut();
}, 2000);
return false;
} else if (/^1[3|4|5|7|8][0-9]{9}$/.test(phoneNum) && codeTxt != "") {
$.ajax({
type: 'post',
url: w.jsonUrl,
data: "method=xxxx" + "&content=" + JSON.stringify({
customerName: phoneNum,
sendBookActivityCode: w.bookCode,
checkCode: codeTxt
}),
callbackParameter: 'callback',
async: true,
jsonp: "jsonpcallback",
success: function (o) {
if (o.status == 1) {
$('.j-pop').fadeIn();
$('.j-pop p').text('领取成功!');
setTimeout(function () {
$('.j-pop').fadeOut();
window.location.href = "http://xxxxx";
}, 800);
} else if (o.status == 2) {
$('.j-pop').fadeIn();
$('.j-pop p').text("您已领取过该书籍");
setTimeout(function () {
$('.j-pop').fadeOut();
window.location.href = "http://xxxx";
}, 2000);
}
}
});
} else if (!/^1[3|4|5|7|8][0-9]{9}$/.test(phoneNum)) {
$('.j-pop').fadeIn();
$('.j-pop p').text('手机号错误');
setTimeout(function () {
$('.j-pop').fadeOut();
}, 2000);
}
});
},
codeAjax: function () {
var w = this;
var phoneNum = $('.m-phone').val();
if (/^1[3|4|5|6|7|8][0-9]{9}$/.test(phoneNum)) {
$.ajax({
type: 'post',
url: w.jsonUrl,
timeout: 2000, //10秒超时
data: "method=xxxx" + "&content=" + JSON.stringify({
mobileNum: phoneNum,
type: 'LOGIN_CHECK'
}),
callbackParameter: 'callback',
async: false,
jsonp: "jsonpcallback",
success: function (o) {
if (o.status == 1) {
$('.j-pop').fadeIn();
$('.j-pop p').text('短信发送成功');
setTimeout(function () {
$('.j-pop').fadeOut();
}, 2000);
} else if (o.status == 0) {
if (o.code == "10002006") {
$('.j-pop').fadeIn();
$('.j-pop p').text('请求过于频繁,一分钟只能请求一次');
setTimeout(function () {
$('.j-pop').fadeOut();
}, 2000);
} else if (o.code == "10002003") {
$('.j-pop').fadeIn();
$('.j-pop p').text('短信发送失败');
setTimeout(function () {
$('.j-pop').fadeOut();
}, 2000);
}
}
}
});
} else {
$('.j-pop').fadeIn();
$('.j-pop p').text('手机号格式不正确');
setTimeout(function () {
$('.j-pop').fadeOut();
}, 2000);
}
},
//上传做好的图片,并获取后台生成的图片路径
sendImgSouce: function () {
var w = this;
console.log("开始上传");
$.ajax({
type: 'post',
url: 'http://xxxxxxx/upload/activityBase64',
data: {
pictureStream: w.hcBase64,
activityId: "1508342400"
},
timeout: 10000, //10秒超时
callbackParameter: 'callback',
async: false,
jsonp: "jsonpcallback",
success: function (o) {
console.log("回调");
console.log(o);
var b = o.data.split("?");
var c = b[0].split("event/");
w.imgNewName = c[1];
console.log(w.imgNewName);
}
});
console.log("上传成功");
}
}
win.page = obj;
})(window)
//图片操作获取具体数据的函数
function imageMaker(eleID,otherID){
var oldX=0,
oldY=0,
ratio=1;
$(""+eleID+"").on("touchstart",imgTouchStart);
$(""+eleID+"").on("touchmove",imgTouchMove);
$(""+eleID+"").on("touchend",imgTouchEnd);
//手指按下时,捕捉事件,取坐标值,设置参数
function imgTouchStart(e){
//阻止事件冒泡的
e.stopImmediatePropagation();
e.preventDefault();
$(""+eleID+"").attr("draggable",true);
oldX = e.originalEvent.touches[0].clientX;
oldY = e.originalEvent.touches[0].clientY;
}
function imgTouchMove(e){
e.stopImmediatePropagation();
//阻止事件冒泡,避免,移动照片时,整个页面也会随滚动条移动
e.preventDefault();
if($(""+eleID+"").attr("draggable")) {
var x = e.originalEvent.touches[0].clientX - oldX;
var y = e.originalEvent.touches[0].clientY - oldY;
var oldTop = $(""+eleID+"")[0].offsetTop;
var oldLeft = $(""+eleID+"")[0].offsetLeft;
var NewTop = y + parseInt(oldTop);
var newLeft = x + parseInt(oldLeft);
$(""+eleID+"").css({"top":NewTop+"px","left":newLeft+"px"});
oldX = e.originalEvent.touches[0].clientX;
oldY = e.originalEvent.touches[0].clientY;
}
}
//手指拿开时,设置参数
function imgTouchEnd(e) {
e.stopImmediatePropagation();
e.preventDefault();
$(""+eleID+"").attr("draggable",false);
}
$(".shape1").on("touchstart",function(e){
setImgSmall();
});
$(".shape3").on("touchstart",function(e){
setImgBig();
});
$(".shape2").on("touchstart",function(e){
setImgAngle();
});
//放大、缩小的
function setImgBig() {
var width = parseInt($(""+otherID+"").width()) * 1.03;
var height = parseInt($(""+otherID+"").height()) * 1.03;
$(""+otherID+"").css({
'width': width+"px",
'height': height+"px",
});
console.log("打印我"+width);
}
function setImgSmall() {
var width = parseInt($(""+otherID+"").width()) * 0.97;
var height = parseInt($(""+otherID+"").height()) * 0.97;
$(""+otherID+"").css({
'width': width+"px",
'height': height+"px",
});
}
function setImgAngle(){
//这里只取图片的角度,值旋转图片。外框不做操作了
var theAngle = getEletAngle();
var angleNow = theAngle+10;
$(".f-sucai").css({'transform': "rotate("+angleNow+"deg)"});
}
}
//获取元素旋转角度
function getEletAngle(eletClass){
var el = document.getElementsByClassName("f-sucai")[0];
console.log(el);
var st = window.getComputedStyle(el, null);
var tr = st.getPropertyValue("-webkit-transform") ||
st.getPropertyValue("-moz-transform") ||
st.getPropertyValue("-ms-transform") ||
st.getPropertyValue("-o-transform") ||
st.getPropertyValue("transform") ||
"FAIL";
//console.log('Matrix: ' + tr);
var values = tr.split('(')[1].split(')')[0].split(',');
var a = values[0];
var b = values[1];
var angle = Math.round(Math.atan2(b, a) * (180 / Math.PI));
//console.log('Rotate: ' + angle + 'deg');
return angle;
}