fenggu/pages/canvasposter/canvasposter.js

880 lines
22 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

// index.js
// 获取应用实例
let index = 0, // 当前点击图片的index
items = [], // 图片数组信息
itemId = 1, // 图片id用于识别点击图片
fliter = 'init', // 默认过滤类型(原图)
shape = 'init'; // 默认形状(原图)
const hCw = 1.62; // 图片宽高比
const canvasPre = 1; // 展示的canvas占mask的百分比
const maskCanvas = wx.createCanvasContext('maskCanvas', this); // 创建 canvas 的绘图上下文 CanvasContext 对象
const util = require('../../utils/util.js');
var urlPath = require('../../config.js');
const innerAudioContext = wx.createInnerAudioContext()
var srcurl=`${urlPath.host}/static/media/bg_audio.mp3`;
Page({
/**
* 页面的初始数据
*/
data: {
isLogin: false, //是否授权
funBox: true, //功能框
itemList: [],
showBtn: false, //按钮
showBox: false, //弹框
// titlelist: ['脸谱', '背景', '按钮', '川剧', '人物', '文字', '装饰'],
titlelist: [],
titleIndex: '-1',
allList: [],
allIndex: '-1',
zancunImg:[],//缓存中的图片
isOk: false,
isNo: false,
closeTime: null,
titleVal:'',
showTitle:false,
times:0,
haveData:true,
worksImg:false,
creat_close:true,
currentIndex:0,
worksBox:false,
isloading:false,
playAudio:false,
guiz:false
},
// 下一个
nextEv(){
if(this.data.allList.length-5 >= this.data.currentIndex) {
this.setData({
currentIndex:this.data.currentIndex + 1
})
}
},
// 上一个
preEv(){
if(this.data.currentIndex!=0) {
this.setData({
currentIndex:this.data.currentIndex - 1
})
}
},
changeCurrent(e){
this.setData({
currentIndex:e.detail.current
})
},
// 创建作品按钮
creatWorks(){
this.setData({
funBox:false,
worksBox:true,
creat_close:false
})
},
// 收起创作
closeWorks(){
this.setData({funBox:true,worksBox:false,creat_close:true})
},
// 标题点击事件
chooseTitle(e) {
if(this.data.isloading==false) {
let that = this;
if (that.data.titleIndex != e.currentTarget.dataset.index) {
that.setData({
allIndex: '-1'
})
}
this.setData({
titleIndex: e.currentTarget.dataset.index,
showBtn: true,
worksImg:true,
currentIndex:0
})
this.getBottleWidgets(that.data.titlelist[that.data.titleIndex].id);
} else {
wx.showToast({
title:'正在加载...',
icon:'loading'
})
}
},
chooseImg(e) {
let that = this;
that.setData({
allIndex: e.currentTarget.dataset.index,
showBox: false,
showBtn: false
})
if (that.data.titleIndex == 0) {
wx.getStorage({ //获取本地缓存
key: that.data.allList[that.data.allIndex].img,
success: function(res) {
console.log(res);
that.setBackGroundImg({
url: res.data
});
},
})
} else {
wx.getStorage({ //获取本地缓存
key: that.data.allList[that.data.allIndex].img,
success: function(res) {
that.setDropItem({
url: res.data
});
},
})
}
},
titleInput(e){
this.setData({
titleVal:e.detail.value
})
},
submit(){
if(this.data.titleVal==''){
wx.showToast({title:'请输入标题',icon:'none'})
} else {
wx.showToast({title:'设置标题成功',icon:'none'})
this.setData({showTitle:false})
}
},
onShow: function() {
if (typeof this.getTabBar === 'function' && this.getTabBar()) {
this.getTabBar().setData({
selected: 0
})
}
this.onmusicTap();
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function(options) {
if(wx.getStorageSync('guiz')!=false) {
this.setData({
guiz:true
})
}
let that = this;
items = this.data.itemList;
wx.getSystemInfo({ // 获取系统信息
success: sysData => {
this.sysData = sysData;
// 设置画布宽高this.sysData.windowWidth为屏幕的宽度
this.setData({
canvasWidth: this.sysData.windowWidth *
canvasPre, // 如果觉得不清晰的话,可以把所有组件、宽高放大一倍
canvasHeight: this.sysData.windowWidth * canvasPre * hCw,
backGroundWidth: this.sysData.windowWidth,
backGroundHeight: this.sysData.screenHeight
})
}
})
// 换取token
wx.login({
success: res => {
wx.request({
url: urlPath.getopenid,
method: 'post',
data: {code: res.code},
success(res) {
if (res.data.code == 0) {
wx.setStorageSync('token', res.data.data.token);
wx.setStorageSync('username', res.data.data.user.wx_name);
that.getBottleCategories();
}
}
});
}
})
that.setBackGroundImg({
url: '../../img/background/3.png'
});
},
// 上传图片
uploadImg() {
let that = this;
wx.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success(res) {
// tempFilePath可以作为img标签的src属性显示图片
that.setDropItem({
url: res.tempFilePaths[0]
});
}
})
},
// 设置背景图片
setBackGroundImg(imgData) {
let data = {}; // 存储图片信息
// 获取图片信息网络图片需先配置download域名才能生效
wx.getImageInfo({
src: imgData.url,
success: res => {
// 初始化数据
let maxWidth = this.data.backGroundWidth,
maxHeight = this.data.backGroundHeight; // 设置最大宽高
if (res.width > maxWidth || res.height > maxHeight) { // 原图宽或高大于最大值就执行
if (res.width / res.height > maxWidth / maxHeight) { // 判断比例使用最大值的宽或高作为基数计算
data.width = maxWidth;
data.height = Math.round(maxWidth * (res.height / res.width));
} else {
data.height = maxHeight;
data.width = Math.round(maxHeight * (res.width / res.height));
}
}
data.image = imgData.url; // 显示地址
data.initImage = imgData.url; // 原始地址
// data.id = ++itemId; // id
data.id = 2; // id
data.top = 0; // top定位
data.left = 0; // left定位
// 圆心坐标
data.x = data.left + data.width / 2;
data.y = data.top + data.height / 2;
data.scale = 1; // scale缩放
data.rotate = 1; // 旋转角度
data.active = false; // 选中状态
data.angle = 0;
items[0] = data; // 每增加一张图片数据增加一条信息
this.setData({
itemList: items
})
}
})
},
// 设置图片的信息
setDropItem(imgData) {
let data = {}; // 存储图片信息
// 获取图片信息网络图片需先配置download域名才能生效
wx.getImageInfo({
src: imgData.url,
success: res => {
// 初始化数据
let maxWidth = 150,
maxHeight = 150; // 设置最大宽高
if (res.width > maxWidth || res.height > maxHeight) { // 原图宽或高大于最大值就执行
if (res.width / res.height > maxWidth / maxHeight) { // 判断比例使用最大值的宽或高作为基数计算
data.width = maxWidth;
data.height = Math.round(maxWidth * (res.height / res.width));
} else {
data.height = maxHeight;
data.width = Math.round(maxHeight * (res.width / res.height));
}
}
data.image = imgData.url; // 显示地址
data.initImage = imgData.url; // 原始地址
data.id = ++itemId + 1; // id
data.top = 10; // top定位
data.left = 10; // left定位
// 圆心坐标
data.x = data.left + data.width / 2;
data.y = data.top + data.height / 2;
data.scale = 1; // scale缩放
data.rotate = 1; // 旋转角度
data.active = false; // 选中状态
data.angle = 0;
items[items.length] = data; // 每增加一张图片数据增加一条信息
this.setData({
itemList: items
})
}
})
},
// 点击图片
WraptouchStart: function(e) {
if (e.currentTarget.dataset.id != 2) {
// 循环图片数组获取点击的图片信息
for (let i = 0; i < items.length; i++) {
items[i].active = false;
if (e.currentTarget.dataset.id == items[i].id) {
index = i;
items[index].active = true;
}
}
this.setData({
itemList: items
})
// 获取点击的坐标值
items[index].lx = e.touches[0].clientX;
items[index].ly = e.touches[0].clientY;
}
if(this.data.funBox){
if(!this.data.worksBox) {
this.setData({
funBox: false,
creat_close:true
})
} else {
this.setData({
funBox: false,
})
}
} else {
if(!this.data.creat_close){
this.setData({
worksBox:false,
creat_close:false
})
}
}
},
// 拖动图片
WraptouchMove(e) {
if (e.currentTarget.dataset.id != 2) {
items[index]._lx = e.touches[0].clientX;
items[index]._ly = e.touches[0].clientY;
items[index].left += items[index]._lx - items[index].lx;
items[index].top += items[index]._ly - items[index].ly;
items[index].x += items[index]._lx - items[index].lx;
items[index].y += items[index]._ly - items[index].ly;
items[index].lx = e.touches[0].clientX;
items[index].ly = e.touches[0].clientY;
this.setData({
itemList: items,
showBtn: true,
worksBox:false
})
this.showWorksBtn();
}
},
// 放开图片
WraptouchEnd() {
this.synthesis(); // 调用合成图方法
this.showWorksBtn();
},
// 显示创作按钮
showWorksBtn(){
clearTimeout(this.data.closeTime);
this.data.closeTime = setTimeout(() => {
this.setData({showBtn: false})
if(this.data.creat_close){
this.setData({funBox:true})
} else {
this.setData({worksBox:true})
}
}, 1000)
},
// 点击伸缩图标
oTouchStart(e) {
//找到点击的那个图片对象,并记录
for (let i = 0; i < items.length; i++) {
items[i].active = false;
if (e.currentTarget.dataset.id == items[i].id) {
index = i;
items[index].active = true;
}
}
//获取作为移动前角度的坐标
items[index].tx = e.touches[0].clientX;
items[index].ty = e.touches[0].clientY;
//移动前的角度
items[index].anglePre = this.countDeg(items[index].x, items[index].y, items[index].tx, items[index].ty);
//获取图片半径
items[index].r = this.getDistancs(items[index].x, items[index].y, items[index].left, items[index].top);
},
oTouchMove: function(e) {
//记录移动后的位置
items[index]._tx = e.touches[0].clientX;
items[index]._ty = e.touches[0].clientY;
//移动的点到圆心的距离
items[index].disPtoO = this.getDistancs(items[index].x, items[index].y, items[index]._tx, items[index]._ty - 10)
console.log(items[index].disPtoO);
if(items[index].disPtoO > 80 && items[index].disPtoO <200 ){//设置贴图最小值和最大值
items[index].scale = items[index].disPtoO / items[index].r;
}
//移动后位置的角度
items[index].angleNext = this.countDeg(items[index].x, items[index].y, items[index]._tx, items[index]._ty)
//角度差
items[index].new_rotate = items[index].angleNext - items[index].anglePre;
//叠加的角度差
items[index].rotate += items[index].new_rotate;
items[index].angle = items[index].rotate; //赋值
//用过移动后的坐标赋值为移动前坐标
items[index].tx = e.touches[0].clientX;
items[index].ty = e.touches[0].clientY;
items[index].anglePre = this.countDeg(items[index].x, items[index].y, items[index].tx, items[index].ty)
//赋值setData渲染
this.setData({
itemList: items
})
},
// 计算坐标点到圆心的距离
getDistancs(cx, cy, pointer_x, pointer_y) {
this.setData({
showBtn: true,
funBox: false
})
var ox = pointer_x - cx;
var oy = pointer_y - cy;
return Math.sqrt(
ox * ox + oy * oy
);
},
/*
*参数cx和cy为图片圆心坐标
*参数pointer_x和pointer_y为手点击的坐标
*返回值为手点击的坐标到圆心的角度
*/
countDeg: function(cx, cy, pointer_x, pointer_y) {
var ox = pointer_x - cx;
var oy = pointer_y - cy;
var to = Math.abs(ox / oy);
var angle = Math.atan(to) / (2 * Math.PI) * 360;
if (ox < 0 && oy < 0) //相对在左上角第四象限js中坐标系是从左上角开始的这里的象限是正常坐标系
{
angle = -angle;
} else if (ox <= 0 && oy >= 0) //左下角,3象限
{
angle = -(180 - angle)
} else if (ox > 0 && oy < 0) //右上角1象限
{
angle = angle;
} else if (ox > 0 && oy > 0) //右下角2象限
{
angle = 180 - angle;
}
return angle;
},
// 删除
deleteItem: function(e) {
let newList = [];
for (let i = 0; i < items.length; i++) {
if (e.currentTarget.dataset.id != items[i].id) {
newList.push(items[i])
}
}
if (newList.length > 1) { //大于0背景图可被删除大于1背景图不能被删除
newList[newList.length - 1].active = true; // 剩下图片组最后一个选中
}
items = newList;
this.setData({
itemList: items
})
},
// 打开遮罩层
openMask() {
if (wx.getStorageSync('username')!='' && wx.getStorageSync('username')!=undefined ) {
this.synthesis();
// this.setData({showCanvas: true,showTitle:true})
this.setData({showCanvas: true})
} else {
this.setData({
isLogin: true
})
}
},
downLoadImg(netUrl, storageKeyUrl) {
wx.getImageInfo({
src: netUrl, //请求的网络图片路径
success: function(res) {
//请求成功后将会生成一个本地路径即res.path,然后将该路径缓存到storageKeyUrl关键字中
wx.setStorage({
key: storageKeyUrl,
data: res.path,
});
}
})
},
synthesis(whereIndex=0) { // 合成图片
maskCanvas.save();
maskCanvas.beginPath();
// 画背景色(白色)
maskCanvas.setFillStyle('#fff');
maskCanvas.fillRect(0, 0, this.data.canvasWidth, this.data.backGroundHeight);
items.forEach((currentValue, index) => {
maskCanvas.save();
maskCanvas.translate(0, 0);
maskCanvas.beginPath();
maskCanvas.translate(currentValue.x, currentValue.y); // 圆心坐标
maskCanvas.rotate(currentValue.angle * Math.PI / 180);
maskCanvas.translate(-(currentValue.width * currentValue.scale / 2), -(currentValue.height *
currentValue.scale / 2))
maskCanvas.drawImage(currentValue.image, 0, 0, currentValue.width * currentValue.scale,
currentValue.height * currentValue.scale);
maskCanvas.restore();
})
// reserve 参数为 false则在本次调用绘制之前 native 层会先清空画布再继续绘制
maskCanvas.draw(false, (e) => {
wx.canvasToTempFilePath({
canvasId: 'maskCanvas',
success: res => {
this.setData({
canvasTemImg: res.tempFilePath
})
if(whereIndex==1){
wx.uploadFile({
url: urlPath.composeBottle,
filePath: this.data.canvasTemImg,
name: 'image',
formData: {
'name': this.data.titleVal
},
header: {
"Content-Type": "multipart/form-data",
'Content-Type': 'application/json',
'token': wx.getStorageSync('token')
},
success: (res)=> {
let newRes = JSON.parse(res.data);
if(newRes.code==0){
wx.downloadFile({
url: urlPath.host + newRes.data.src,
success: (res) => {
wx.hideToast();
this.setData({
times:0
})
wx.showShareImageMenu({
path: res.tempFilePath,
success:(res)=>{}
})
}
})
}
},
fail: function(data) {
console.log(data);
}
})
}
}
}, this);
})
},
// 关闭遮罩层
disappearCanvas() {
this.setData({
showCanvas: false
})
},
// 保存图片到系统相册
saveImg: function() {
wx.saveImageToPhotosAlbum({
filePath: this.data.canvasTemImg,
success: res => {
wx.showToast({
title: '保存成功',
icon: "success"
})
this.saveImgEv(this.data.canvasTemImg);
},
fail: res => {
wx.showModal({
title: '提示',
content: '保存失败,请确保相册权限已打开',
success: (e) => {
if (e.confirm) {
wx.openSetting({
success: settingdata => {
if (settingdata.authSetting['scope.writePhotosAlbum']) {
console.log('获取权限成功,给出再次点击图片保存到相册的提示。')
} else {
console.log('获取权限失败,给出不给权限就无法正常使用的提示')
}
},
fail: error => {
console.log(error)
}
})
}
}
})
}
})
},
// 保存图片接口
saveImgEv(imgSrc) {
wx.uploadFile({
url: urlPath.composeBottle,
filePath: imgSrc,
name: 'image',
formData: {
'name': this.data.titleVal
},
header: {
"Content-Type": "multipart/form-data",
'token': wx.getStorageSync('token')
},
success: (data)=> {
if(data.statusCode==200){
wx.showToast({
title:'保存成功',
icon:'none'
})
this.setData({
showCanvas:false
})
}
},
fail: function(data) {
console.log(data);
}
})
},
// 首页左下角分享
homeShare(){
if(this.data.times==0){
wx.showToast({title:'正在调起分享',duration:50000})
this.data.times++
this.synthesis(1);
}
},
// 分享图片
shareImg(e) {
let newIndex = e.currentTarget.dataset.index;
if(this.data.times==0){
this.setData({
times:this.data.times++
})
if(newIndex==0){
wx.showToast({title:'正在调起分享',duration:50000})
}
wx.uploadFile({
url: urlPath.composeBottle,
filePath: this.data.canvasTemImg,
name: 'image',
formData: {
'name': this.data.titleVal
},
header: {
"Content-Type": "multipart/form-data",
'Content-Type': 'application/json',
'token': wx.getStorageSync('token')
},
success: (res)=> {
let newRes = JSON.parse(res.data);
if(newRes.code==0){
if(newIndex==0){
wx.downloadFile({
url: urlPath.host + newRes.data.src,
success: (res) => {
wx.hideToast();
this.setData({
times:0
})
wx.showShareImageMenu({
path: res.tempFilePath,
success:(res)=>{}
})
}
})
} else {
this.shareEv(newRes.data.id);
}
}
},
fail: function(data) {
console.log(data);
}
})
}
},
// 分享事件
shareEv(id) {
wx.request({
url: urlPath.publishMyBottle,
data: {id: id},
header: {'token': wx.getStorageSync('token')},
method: 'post',
success: (res) => {
if (res.data.code == 0) {
wx.showToast({title: '参加活动成功'});
this.setData({
showCanvas:false
})
}
}
});
},
// 关闭授权
chooseBtn(e) {
let loginIndex = e.currentTarget.dataset.index;
this.setData({
isOk: false,
isNo: false
})
loginIndex == 1 ? this.setData({
isOk: true
}) : this.setData({
isNo: true
})
},
// 确认授权
shouq(e) {
wx.getUserProfile({ //获取用户昵称
desc: '用于完善会员资料',
success: (res) => {
this.setData({
userInfo: res.userInfo,
isLogin: false
})
wx.showToast({
title: '授权成功',
icon: 'none'
})
this.setData({
isOk: false
})
wx.login({ //调用授权登录
success: res => {
wx.request({
url: urlPath.getopenid,
method: 'post',
data: {
code: res.code,
wx_name: this.data.userInfo.nickName,
avater: this.data.userInfo.avatarUrl,
},
success:(res)=> {
if (res.data.code == 0) {
wx.setStorageSync('token', res.data.data.token);
wx.setStorageSync('openid', res.data.data.openid);
wx.setStorageSync('username', res.data.data.user.wx_name);
console.log(wx.getStorageSync('username'));
}
}
});
}
})
},
fail: (res) => {
wx.showToast({
title: '授权失败',
icon: 'none'
})
this.setData({
isOk: false
})
}
})
},
// 获取标题
getBottleCategories() {
wx.request({
url: urlPath.getBottleCategories,
success: (res) => {
if (res.data.code == 0) {
if (res.data.data.length) {
this.setData({
titlelist: res.data.data
})
// this.getBottleWidgets(res.data.data[0].id);
let arrImg = [];
for (var i = 0; i < res.data.data.length; i++) {
arrImg.push([]);
}
this.setData({
zancunImg:arrImg
})
}
}
}
});
},
// 获取标题下的图片
getBottleWidgets(id) {
this.setData({
isloading:true,
allList: []
})
if(this.data.zancunImg[this.data.titleIndex].length==0){
wx.request({
url: urlPath.getBottleWidgets,
method: 'post',
data: {
category_id: id,
size: 60
},
success: (res) => {
if (res.data.code == 0) {
if (res.data.data.length) {
this.setData({
haveData: true
})
let newArr = [];
res.data.data.forEach(item => {
let url = urlPath.host + item.img;
this.downLoadImg(url, urlPath.host + item.img);
let obj = {
id: item.id,
name: item.name,
img: urlPath.host + item.img,
img_thumb:urlPath.host + item.img_thumb,
}
newArr.push(obj)
})
this.data.zancunImg[this.data.titleIndex] = newArr;
this.setData({
zancunImg:this.data.zancunImg
})
this.setData({
allList: newArr,
isloading:false
})
} else {
this.setData({
haveData: false,
isloading:false
})
}
}
}
});
} else {
this.setData({
allList: this.data.zancunImg[this.data.titleIndex],
isloading:false,
haveData: true
})
}
},
// 查看我的作品
checkWorkEv() {
wx.navigateTo({
url: '/pages/works/works'
})
},
onmusicTap: function (event) {
// var srcurl="http://ws.stream.qqmusic.qq.com/C400003ve1uC4XLn3d.m4a?guid=689499762&vkey=B1D022604613407E7D095A017630F160F652877AAD8834515F05D5777E57F7F08467145E6879B04A2694BA6B7CD82AB028B7C2635D21F49B&uin=&fromtag=66"
innerAudioContext.autoplay = true
innerAudioContext.src = srcurl
innerAudioContext.onPlay(() => {
console.log('开始播放')
this.setData({
playAudio:false
})
})
},
onHide(){
this.closeAudio()
},
playAudio(){
innerAudioContext.play();
this.setData({
playAudio:false
})
},
closeAudio(){
innerAudioContext.pause();
this.setData({
playAudio:true
})
},
closeTank(){
wx.setStorageSync('guiz',false);
this.setData({
guiz:false
})
}
})