主页面
<template>
<view class="page">
<!-- 自定义导航栏-->
<Navbar title="我的海报"></Navbar>
<view class="container">
<poster ref="poster" :imageUrl="image" :imageWidth="750" :imageHeight="1000" :drawData="drawData"
:config="config" :wechatCode="false" @wechatCodeConfig="wechatCodeConfig" @click="createdPoster"
@loading="onLoading" @success="onSuccess" @fail="onFail" class="poster">
<!-- <template v-slot:save>
<view @click="saveToAlbum">保存</view>
</template> -->
</poster>
<u-image width="222rpx" height="222rpx" :src="code" class="container_image"></u-image>
</view>
<!-- <view class="bottom"> -->
<!-- <view class="bottom_item" @click="share('微信好友')">
<u-image width="74rpx" height="74rpx"
src="xxxxxxxxxxxxxxstatic/poster/%E7%BC%96%E7%BB%84%206%402x.png"></u-image>
<text>微信好友</text>
</view> -->
<!-- <view class="bottom_item" @click="share('朋友圈')">
<u-image width="74rpx" height="74rpx"
src="xxxxxxxxxxxposter/%E7%BC%96%E7%BB%84%208%402x.png"></u-image>
<text>朋友圈</text>
</view> -->
<!-- <view class="bottom_item" @click="share('保存图片')">
<u-image width="74rpx" height="74rpx"
src="xxxxxxxxxoster/%E7%BC%96%E7%BB%84%2012%402x.png"></u-image>
<text>保存图片</text>
</view> -->
<!-- </view> -->
</view>
</template>
<script>
import poster from "@/components/poster/index";
import {
saveImageToPhotosAlbum
} from '@/utils/poster.js';
export default {
components: {
poster
},
data() {
return {
code: '',
canvasImages: '',
image: 'xxxxxxter/static/poster/%E7%BC%96%E7%BB%84%205%402x.png',
config: {
imageMode: 'aspectFit',
posterHeight: '100%',
// canvasWidth 和 convasHeight使用的是px,防止不同设备Dpr不统一,导致最后图片留白边问题
canvasWidth: 275,
convasHeight: 600,
},
drawData: [],
wechatCodeConfig: {
serverUrl: '',
scene: '123123',
config: {
x: 84.5,
y: 320,
w: 100,
h: 100
}
}
}
},
created() {
this.usercode()
// 模拟异步请求获得到的数据
// setTimeout(() => {
// this.wechatCodeConfig.scene = '456787';
// this.drawData = [{
// type: 'image',
// config: {
// url: 'https://horifon.oss-cn-shanghai.aliyuncs.com/hongyunartcenter/static/poster/%E7%BC%96%E7%BB%84%205.png',
// x: 0,
// y: 0,
// w: 275,
// h: 490
// },
// },
// {
// type: 'image',
// config: {
// url: this.code,
// x: 40,
// y: 380,
// w: 40,
// h: 40
// },
// },
// {
// type: 'text',
// config: {
// text: '',
// x: 140,
// y: 60,
// color: '#E60012',
// font: 'normal bold 16px 仿宋',
// textAlign: 'center'
// }
// }
// ];
// }, 1000)
// this.createdPoster();
},
methods: {
//二维码
usercode() {
let $this = this
uni.request({
url: "xxxxxxx/mobile/index.php?m=user&c=indexapi&a=affiliate",
method: 'POST',
header: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data: {
"user_id": parseInt(uni.getStorageSync('USER_ID'))
},
success(res) {
console.log(res.data.data, '数据');
$this.code = res.data.data
$this.wechatCodeConfig.serverUrl = res.data.data
}
});
},
// 保存到相册
saveToAlbum() {
this.$refs.poster.saveToAlbum()
},
onLoading() {
console.log('Loading:正在加载静态资源')
},
onSuccess(e) {
console.log('Success:创建海报成功', e)
this.canvasImages = e
wx.showShareImageMenu({
path: this.canvasImages,
style:"background-color:'black'"
})
},
onFail(e) {
console.log('Fail:创建海报失败', e)
},
createdPoster() {
console.log('点击')
// 调用 createImage 开始创建海报
// this.$refs.poster.createImage()
this.$refs.poster.cjian()
// wx.showShareImageMenu({
// path: this.canvasImages
// })
},
share(e) {
if (e === '微信好友') {
wx.showShareImageMenu({
path: this.canvasImages
})
} else if (e === '朋友圈') {
uni.share({
provider: "weixin",
scene: "WXSceneTimeline",
type: 2,
imageUrl: this.canvasImages,
success: function(res) {
console.log("success:" + JSON.stringify(res));
},
fail: function(err) {
console.log("fail:" + JSON.stringify(err));
}
});
} else if (e === '保存图片') {
saveImageToPhotosAlbum(this.canvasImages).then(res => {
uni.showToast({
icon: 'none',
title: '保存成功'
})
}).catch(err => {
})
}
}
}
}
</script>
<style scoped lang="scss">
.container {
position: relative;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.poster {
width: 100%;
height: 100%;
}
.container_image {
position: absolute;
bottom: 214rpx;
left: 76rpx;
}
}
.bottom {
display: flex;
justify-content: space-evenly;
align-items: center;
position: absolute;
bottom: 0;
width: 750rpx;
height: 218rpx;
background: #FFFFFF;
border-radius: 40rpx 40rpx 0rpx 0rpx;
// border: 2rpx solid #FF583D;
}
</style>
components/poster/index 组件
<template>
<view class="poster_wrapper">
<slot name="header"></slot>
<!-- 要生成海报的图片 -->
<image :src="imageUrl" mode="aspectFill" :style="{width:imageWidth + 'rpx'}" @click="click" class="imagebig"></image>
<!-- 这里把canvas移到了屏幕外面,如果需要查看canvas的话把定位去掉 -->
<!-- position:'fixed',left:'9999px',top:'0' -->
<canvas :style="{width:canvasWidth + 'px',height:canvasHeight + 'px',position:'fixed',left:'9999px',top:'0'}"
canvas-id="myCanvas" id="myCanvas" class="canvas"></canvas>
<!-- 遮罩层 -->
<!-- <view class="mask" v-if="showMask" @click="hideMask"> -->
<!-- 生成的海报图 -->
<!-- <image :style="posterSize" :src="lastPoster" :mode="config.imageMode" @click.stop=""></image> -->
<!-- <view class="btn_wrapper" @click.stop>
<slot name="save">
<button type="primary" @click="saveToAlbum">保存至相册</button>
</slot>
</view> -->
<!-- </view> -->
</view>
</template>
<script>
import {
loadImage,
createPoster,
canvasToTempFilePath,
saveImageToPhotosAlbum
} from '@/utils/poster.js';
import {
getWechatCode
} from "@/utils/appletCode.js";
export default {
props: {
// 展示图片的宽 单位 rpx
imageWidth: {
type: [String, Number],
default: 550
},
// 展示图片的高 单位 rpx
imageHeight: {
type: [String, Number],
default:980
},
// 展示图片的url
imageUrl: {
type: String,
default: '',
required: true
},
// 绘制海报的数据参数
// drawData: {
// type: Array,
// default: () => ([]),
// required: true
// },
// 海报的配置参数
config: {
type: Object,
default: () => ({
imageMode: 'aspectFit',
posterHeight:1000,
}),
},
// 是否需要小程序二维码
wechatCode: {
type: Boolean,
default: false
},
// 小程序二维码的配置参数
wechatCodeConfig: {
type: Object,
default: () => ({
serverUrl: '',
scene: '',
config: {
x: 0,
y: 0,
w: 100,
h: 100
}
}),
}
},
data() {
return {
// 资源是否加载成功的标志
readyed: false,
// 将网络图片转成静态图片后的绘制参数
imageMap: [],
// 最后生成的海报的本地缓存地址
lastPoster: '',
// 是否展示遮罩
showMask: false,
// 是否加载资源的标志
loadingShow: false,
// 是否可以创建海报
disableCreatePoster:false,
drawData :[
{
type: 'image',
config: {
url: '',
x: 0,
y: 0,
w: 275,
h: 490
},
},
{
type: 'image',
config: {
url: '',
x: 40,
y: 380,
w: 40,
h: 40
},
},
{
type: 'text',
config: {
text: '',
x: 140,
y: 60,
color: '#E60012',
font: 'normal bold 16px 仿宋',
textAlign: 'center'
}
}
],
}
},
computed: {
// 所生成海报图的大小
posterSize() {
let str = '';
this.config.posterWidth && (str += `width:${this.config.posterWidth};`);
this.config.posterHeight && (str += `height:${this.config.posterHeight};`);
return str
},
// 画布的宽,优先使用配置的宽,如果没用配置默认使用图片的宽
// 需要主要的是这里canvas和image的单位不同,不过并不影响
// 我们在绘制时(配置drawData)以px为基准进行绘制就行,用px的原因时防止不同设备Dpr不同导致无法确定画布的具体宽高,使得最后的图片可能会留白边
canvasWidth(){
return this.config.canvasWidth ? this.config.canvasWidth : this.imageWidth
},
// 画布的高,优先使用配置的高,如果没用配置默认使用图片的高
canvasHeight(){
return this.config.convasHeight ? this.config.convasHeight : this.imageHeight
}
},
watch: {
// 监听外部绘制参数的变化,重新加载资源
// drawData(newVlaue) {
// this.loadingResources(newVlaue)
// },
// 监听readyed变化
// readyed(newVlaue) {
// if (newVlaue == true && this.loadingShow == true) {
// uni.hideLoading()
// this.loadingShow = false;
// this.createImage();
// }
// }
// 会存在异步问题,还没解决。
// 目前的解决方法 1.在绘制之前先改变 scene 2.改变scene后手动调用this.loadingResources 函数,但是资源会重新加载
// "wechatCodeConfig.scene":function (newVlaue){
// console.log('wechatCodeConfig.scene',this.imageMap)
// this.loadingWechatCode(this.imageMap)
// }
},
created() {
this.usercode()
// this.$emit('click')
// this.loadingResources(this.drawData)
},
methods: {
cjian(){
this.usercode()
},
//二维码
usercode() {
let $this=this
uni.request({