yuminge-app/yun-min-program-plugin-master/poster/poster.js

575 lines
16 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import drawQrcode from '../utils/weapp.qrcode.esm.js'
module.exports = Behavior({
behaviors: [],
properties: {
isshow:{
value:false,
type:Boolean
},
poster_id: {
type:null
},
showcarrfootBol:{
type:null
},
iPnoneBottomBol:{
type:null
}
},
data: {
errorFlag:false,
errorMsg:'',
poster:'',
loading:0,
getFlag:true,
step:1,
skipError:false, //是否跳过错误强制生成,将不显示错误信息,该功能还没做
unsafeList:[],
image_security_verification:false,//安全域名验证
},
observers:{
'isshow':function(isshow){
if(isshow && this.data.poster=='' && this.data.getFlag){
this.getPosterPic();
this.data.getFlag=false;
}
}
},
attached: function(){},
methods: {
loadImgError(err){
this.setData({
errorFlag:true,
errorMsg:err.detail.errMsg
})
},
// 隐藏二维码
clicktapshow() {
this.setData({
isshow: false
});
this.triggerEvent('closeMethod',{isshow:this.data.isshow})
// wx.showTabBar({})
},
previewImage() {
wx.showToast({
title: '长按图片分享好友',
icon: 'none',
duration: 1800
})
// wx.previewImage({
// urls: [this.data.poster] // 当前显示图片的链接
// })
},
//绘制图片
drawCanvasImage(ctx,imgInfo){
let step = this.data.step;
ctx.drawImage(imgInfo.img,
imgInfo.left*step,
imgInfo.top*step,
imgInfo.width*step,
imgInfo.height*step); // 推进去图片
},
//绘制圆形图片
drawCanvasCircular(ctx,imgInfo){
let step = this.data.step;
let left = imgInfo.left*step;
let top = imgInfo.top*step;
let width = imgInfo.width*step;
let height = imgInfo.height*step;
ctx.save();
ctx.beginPath(); //开始绘制
ctx.arc(width / 2 + left, height / 2 + top, width / 2, 0, Math.PI * 2, false);
ctx.clip();
ctx.drawImage(imgInfo.img,
left,
top,
width,
height); // 推进去图片
ctx.restore(); //恢复之前保存的绘图上下文 恢复之前保存的绘图上下午即状态 还可以继续绘制
},
//绘制矩形
drawCanvasFillRect(ctx,obj){
let step = this.data.step;
let left = obj.left*step;
let top = obj.top*step;
let width = obj.width*step;
let height = obj.height*step;
ctx.setFillStyle(obj.color)
ctx.fillRect(left, top, width, height);
//ctx.draw();
},
//绘制文字
drawCanvasText(ctx,textInfo){
let step = this.data.step;
let size = textInfo.size*step;
let top = (textInfo.top+textInfo.size)*step;
let left = (textInfo.left) * step;
ctx.setFillStyle(textInfo.color);
let bold = "normal";
let italic="normal";
if(textInfo.bold && textInfo.bold == 1){ //加粗
bold = "bold";
}
if(textInfo.italic && textInfo.italic == 1){ //字体倾斜
italic="italic";
}
ctx.font=italic+" small-caps "+bold+" 30px arial,sans-serif";
ctx.setFontSize(size);
if(textInfo.slide && textInfo.slide == 1){ //有删除线
this.drawCanvasFillRect(ctx,{
left:textInfo.left,
top:textInfo.top+(textInfo.size/2),
width:(ctx.measureText(textInfo.src).width/step),
height:3,
color:textInfo.color
})
}else if(textInfo.under && textInfo.under == 1){ //有下划线
this.drawCanvasFillRect(ctx,{
left:textInfo.left,
top:textInfo.top+textInfo.size,
width:(ctx.measureText(textInfo.src).width/step),
height:3,
color:textInfo.color
})
}
ctx.fillText(textInfo.src,left,top);
},
/**
* 绘制多行文字
* @param {*} ctx
* @param {*} textInfo
* width 宽度
* line 行数
*/
drawCanvasLineText(ctx,textInfo){
let step = this.data.step;
let size = textInfo.size*step;
let top = (textInfo.top+textInfo.size)*step;
let text = textInfo.src; //这是要绘制的文本';
let chr = text.split(""); //这个方法是将一个字符串分割成字符串数组
let temp = "";
let row = [];
ctx.setFontSize(size)
ctx.setFillStyle(textInfo.color)
for (let a = 0; a < chr.length; a++) {
if (ctx.measureText(temp).width < (textInfo.width*step)) {
temp += chr[a];
} else {
a--; //这里添加了a-- 是为了防止字符丢失,效果图中有对比
row.push(temp);
temp = "";
}
}
row.push(temp); //如果数组长度大于2 则截取前两个
if (row.length > textInfo.line) {
let rowCut = row.slice(0, row.length);
let rowPart = rowCut[(textInfo.line-1)];
let test = "";
let empty = [];
for (let a = 0; a < rowPart.length; a++) {
if (ctx.measureText(test).width < (textInfo.width*step)) {
test += rowPart[a];
} else {
break;
}
}
empty.push(test);
let group = empty[0] + "..."
//这里只显示两行,超出的用...表示
rowCut.splice((textInfo.line-1), 1, group);
row = rowCut;
}
for (let b = 0; b < row.length; b++) {
if(b<textInfo.line){
let bold = "normal";
let italic="normal";
if(textInfo.bold && textInfo.bold == 1){ //加粗
bold = "bold";
}
if(textInfo.italic && textInfo.italic == 1){ //字体倾斜
italic="italic";
}
ctx.font=italic+" small-caps "+bold+" 30px arial,sans-serif";
ctx.setFontSize(size);
if(textInfo.slide && textInfo.slide == 1){ //有删除线
this.drawCanvasFillRect(ctx,{
left:textInfo.left,
top:textInfo.top+(textInfo.size/2)+(b * textInfo.size+(b*10/step)),
width:(ctx.measureText(row[b]).width/step),
height:3,
color:textInfo.color
})
}else if(textInfo.under && textInfo.under == 1){ //有下划线
this.drawCanvasFillRect(ctx,{
left:textInfo.left,
top:textInfo.top+textInfo.size+(b * textInfo.size+(b*10/step)),
width:(ctx.measureText(row[b]).width/step),
height:3,
color:textInfo.color
})
}
ctx.fillText(row[b],textInfo.left*step,top + (b * size+(b*10)))
}
}
},
/**
* 测量文字width
* @param {*} ctx
* @param {*} obj
* width 宽度
*/
measureTextWidth(ctx,obj){
let {width,text,size} = obj;
//size = size*contentScale;
let step = this.data.step;
let chr = text.split(""); //这个方法是将一个字符串分割成字符串数组
let temp = "";
let row = [];
ctx.setFontSize(size*step)
for (let a = 0; a < chr.length; a++) {
if (ctx.measureText(temp).width < (width*step)) {
temp += chr[a];
} else {
a--; //这里添加了a-- 是为了防止字符丢失,效果图中有对比
row.push(temp);
temp = "";
}
}
row.push(temp);
let actualWidth = ctx.measureText(temp).width;
let actualText = temp;
if(row.length>1){
actualWidth = ctx.measureText((row[0]+"...")).width;
actualText = (row[0]+"...");
}
return {actualWidth:((actualWidth)/step),actualText};
},
//导出图片
toimage(canvasId,posterSize) {
return new Promise((resolve,reject)=>{
wx.canvasToTempFilePath({
x: 0,
y: 0,
// quality:1,
width: posterSize.width,
height:posterSize.height,
destWidth: posterSize.width * 4,
destHeight: posterSize.height * 4,
canvasId: canvasId,
success: (res) => {
var tempFilePath = res.tempFilePath;
resolve(tempFilePath);
},
fail: (res) => {
wx.showToast({
title: '图片导出失败'+res,
icon: 'success',
duration: 2000
})
}
},this)
})
},
drawRoundRectPath(ctx, width, height, radius) {
ctx.beginPath(0);
//从右下角顺时针绘制弧度从0到1/2PI
ctx.arc(width - radius, height - radius, radius, 0, Math.PI / 2);
//矩形下边线
ctx.lineTo(radius, height);
//左下角圆弧弧度从1/2PI到PI
ctx.arc(radius, height - radius, radius, Math.PI / 2, Math.PI);
//矩形左边线
ctx.lineTo(0, radius);
//左上角圆弧弧度从PI到3/2PI
ctx.arc(radius, radius, radius, Math.PI, Math.PI * 3 / 2);
//上边线
ctx.lineTo(width - radius, 0);
//右上角圆弧
ctx.arc(width - radius, radius, radius, Math.PI * 3 / 2, Math.PI * 2);
//右边线
ctx.lineTo(width, height - radius);
ctx.closePath();
ctx.clip();
},
downImage(item){
if(this.data.image_security_verification){
return this.readDownPicInfo(item.src)
}else {
return this.unsafeReadDownPicInfo(item);
}
},
//下载和读取图片
readDownPicInfo(url){
return new Promise((resolve,reject)=>{
wx.downloadFile({
url, //仅为示例,并非真实的资源
success:(res)=> {
wx.getImageInfo({
src: res.tempFilePath,
success (res1) { //确保是一张图片
resolve({img:res.tempFilePath,width:res1.width,height:res1.height});
},
fail:(err)=>{
this.data.getFlag=true;
let msg = "确认图片地址是否为404微信临时地址格式是不是png不是的话在服务端响应的 header 中指定合理的 Content-Type 字段,以保证客户端正确处理文件类型。";
this.setData({
errorFlag:true,
errorMsg:"图片读取出错,错误原因:"+err.errMsg+",图片地址:"+url+",微信临时文件地址格式:"+res.tempFilePath+","+msg
})
reject({error:'错误'});
}
})
},
fail:(err)=>{
this.data.getFlag=true;
let msg = "未知原因,自行检查图片地址是否存在";
if(err.errMsg == "downloadFile:fail createDownloadTask:fail url not in domain list" || err.errMsg == "downloadFile:fail url not in domain list"){
msg = "请查看是否设置downloadFile安全域名";
}
this.setData({
errorFlag:true,
errorMsg:"图片下载出错,错误原因:"+err.errMsg+",图片地址:"+url+','+msg
})
}
})
});
},
unsafeReadDownPicInfo(item){
return new Promise((resolve,reject)=>{
const query = this.createSelectorQuery()
query.select('#temp_security_id')
.fields({ node: true, size: true })
.exec((res) => {
const canvas = res[0].node
const ctx = canvas.getContext('2d');
let frontImg = canvas.createImage()
frontImg.src = item.src;
frontImg.onload = (res) => {
let width = item.width ? item.width : frontImg.width;
let height = item.height ? item.height : frontImg.height;
canvas.width = width;
canvas.height = height;
ctx.drawImage(frontImg, 0, 0, width, height);
let imgSrc = canvas.toDataURL('image/png');
var imgPath = wx.env.USER_DATA_PATH+'/poster_'+this.randomWord(5,10)+ '.png';
var imageData = imgSrc.replace(/^data:image\/\w+;base64,/, "");
var fs = wx.getFileSystemManager();
fs.writeFileSync(imgPath, imageData, "base64");
this.data.unsafeList.push(imgPath);
resolve({img:imgPath,width,height});
}
frontImg.onerror = (e) => {
let msg = "图片加载出错,检查图片地址是否存在,能不能在浏览器正常打开,能的话在服务端响应的 header 中指定合理的 Content-Type 字段,以保证客户端正确处理文件类型。";
this.setData({
errorFlag:true,
errorMsg:"图片地址:"+item.src+','+msg
})
}
})
})
},
removeUnsafeList(){
var fs = wx.getFileSystemManager();
for(let item of this.data.unsafeList){
fs.unlinkSync(item);
}
this.data.unsafeList=[];
},
randomWord(min,max){ //随机获取字符串
let str=(new Date()).valueOf();
let range=min;
let arr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
if(arguments.length==2){
range=Math.round(Math.random()*(max-min))+min;
}
for (var i = 0; i < range; i++) {
let pos = Math.round(Math.random() * (arr.length - 1));
str += arr[pos];
}
return str;
},
// 获取海报画布宽高
getMyCanvasMessage(w,h) {
return new Promise((resolve,reject)=>{
wx.getSystemInfo({
success: (res) => {
let scale = h/w;
let width = res.screenWidth - (res.screenWidth*0.2);
let height = width*scale;
let contentScale = width/w;
width=width*this.data.step,height=height*this.data.step;
resolve({
//width,height,contentScale
width:(w*this.data.step),height:(h*this.data.step),contentScale:1
});
},
fail:(res)=>{
this.data.getFlag=true;
}
})
})
},
getQRCodeUrl(item){
return new Promise((resolve,reject)=>{
let step=this.data.step;
this.setData({
tempQRCodeCanvasWidth:item.width*step,
tempQRCodeCanvasHeight:item.height*step
},async ()=>{
drawQrcode({
width: (item.width-10)*step,
height: (item.height-10)*step,
canvasId: 'tempQRCode',
background:'#fff',
_this:this,
x:5*step,
y:5*step,
text: item.src,
callback:()=>{
setTimeout(async ()=>{
let img = await this.toimage('tempQRCode',{
width:item.width*step,
height:item.height*step
});
resolve(img);
},500);
}
});
});
});
},
setProportion(sourceObj,targetObj){
if(targetObj.height>targetObj.width){
let p = (sourceObj.height)/targetObj.height;
targetObj.height = targetObj.height*p;
targetObj.width = targetObj.width*p;
}else {
let p = (sourceObj.width)/targetObj.width;
targetObj.width = targetObj.width*p;
targetObj.height = (targetObj.height*p);
}
if(targetObj.width>sourceObj.width){
targetObj.height = targetObj.height / (targetObj.width/sourceObj.width);
targetObj.width = sourceObj.width;
}
if(targetObj.height>sourceObj.height){
targetObj.width = targetObj.width / (targetObj.height/sourceObj.height);
targetObj.height = sourceObj.height;
}
},
pxToNum(px){
let num = px.substring(0,px.length-2);
return parseInt(num);
},
async checkWritePotosAlbum() {
var _this = this;
let writePhotosAlbum = await this.getAuthSetting('scope.writePhotosAlbum');
if(!writePhotosAlbum){
wx.showModal({
title: '请开启授权',
content: '是否跳转设置页开启授权',
success (res) {
if (res.confirm) {
wx.openSetting({
success(settingdata) {
if (settingdata.authSetting['scope.writePhotosAlbum']) {
_this.saveImg();
} else {
console.log("还是没授权");
}
}
});
} else if (res.cancel) {
console.log('用户点击取消')
}
}
});
return;
}
this.saveImg();
},
saveImg(){
var imgSrc = this.data.poster;
wx.downloadFile({
url: imgSrc,
success: function(res) {
wx.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: (data)=> {
wx.showToast({
title: '保存成功',
icon: 'none',
duration: 2000
})
},
fail: function(err) {
console.log(err);
}
})
},
fail:(err)=>{
wx.saveImageToPhotosAlbum({
filePath: imgSrc,
success: (data)=> {
wx.showToast({
title: '保存成功',
icon: 'none',
duration: 2000
})
},
fail: function(err) {
console.log(err);
}
})
//console.log(err,this.data.poster,"图片下载出错");
}
})
},
getAuthSetting(authName){
return new Promise((resolve,reject)=>{
wx.getSetting({
success(res) {
if (!res.authSetting[authName]) {
wx.authorize({
scope: authName,
success() {
resolve(true);
},
fail(){
resolve(false);
}
})
}else resolve(true);
},
fail(){
resolve(false);
}
})
});
}
}
})