小程序用canvas 实现一个简易的移动端名片可编辑小程序
Posted 李猫er
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了小程序用canvas 实现一个简易的移动端名片可编辑小程序相关的知识,希望对你有一定的参考价值。
效果预览:
信息输入完成后,点击【确定生成】,将生成图片,并出现【保存】&&【取消】按钮,点击保存即可保存到相册,取消则回到编辑页面:
保存的图片效果:
这个很简单,主要用微信小程序的canvas实现,具体代码:
card.wxml:
<view class="content">
<scroll-view scroll-y="true" style="height: 1334rpx;"
bindscroll="scroll" scroll-into-view="{{toView}}" scroll-top="{{scrollTop}}">
<!-- 模板生成弹框 -->
<view class="canvas-content">
<view class="con">
<canvas canvas-id='myCanvas' class='canvas'></canvas>
<view class="info">
<!-- 行业 -->
<view class="show-post-text">{{upost}}</view>
<!-- 姓名 -->
<view class="show-name-text">{{uname}}</view>
<!-- 联系电话 -->
<view class="show-company-text">{{ucompany}}</view>
</view>
</view>
<view class="canvas-bottom" hidden="{{isHidde}}">
<view class="btn-save" bindtap="saveImg">保存</view>
<view class="btn-close" bindtap="closeDialog">取消</view>
</view>
</view>
<!-- 编辑区域 -->
<view class="edit-tips">编辑:</view>
<view class="form-container">
<view class="show-name item">
<label class="name-label">姓名:</label>
<input type="text" v-model="name" placeholder="" bindinput="onchangeName" class="input" />
</view>
<view class="line"></view>
<view class="show-company item">
<label class="company-name-label">联系电话:</label>
<input type="text" v-model="company" placeholder="" bindinput="onchangeCompany" class="input" />
</view>
<view class="line"></view>
<view class="show-post item">
<label class="name-post-label">从业行业:</label>
<input type="text" v-model="post" placeholder="" bindinput="onchangePost" class="input" />
</view>
</view>
<view class="create-btn">
<button bindtap="createImg" hidden="{{hiddeButton}}" class="btn">确定生成</button>
</view>
</scroll-view>
</view>
card.js:(主要的逻辑功能)
基本都有写上注释了,不清楚的可以看官方文档的API
Page({
data: {
imgUrl: "http://pic.51yuansu.com/backgd/cover/00/40/00/5be62bbb6ac3f.jpg!/fw/780/quality/90/unsharp/true/compress/true",
isHidde: true,
hiddeButton: false,
ucompany: '',
uname: '',
upost:''
},
/* 监听input输入值的变化 实时更新*/
onchangeCompany(e) {
var that = this;
that.setData({
ucompany: e.detail.value,
})
},
onchangePost(e) {
var that = this;
that.setData({
upost:e.detail.value,
})
},
onchangeName(e) {
var that = this;
that.setData({
uname: e.detail.value
})
// console.log("输入监听变化:" + this.data.uname);
},
scrollToTop() {
this.setAction({
scrollTop: 0
})
},
/* 初始化加载显示 */
onLoad: function (options) {
//把网络图片转成在本地
wx.getImageInfo({
src: this.data.imgUrl,
success: (res) => {
this.setData({
imgUrl: res.path
})
this.getcanvas();
}
})
},
/* 生成图片 */
createImg() {
this.getcanvas();
this.setData({
isHidde: false,
// hiddeButton: true,
ucompany: '',
uname: '',
upost: ''
})
},
/* 绘制canvas内容 */
getcanvas() {
let that = this;
let ctx = wx.createCanvasContext('myCanvas');
// ctx.setFillStyle('red');
let metrics = ctx.measureText(that.data.ucompany); // 获取字体的宽度
let name = ctx.measureText(that.data.uname); // 获取字体的宽度
let rpx = 1;
wx.getSystemInfo({
success(res) {
rpx = res.windowWidth / 375;
},
})
ctx.drawImage(this.data.imgUrl, 0, 0, 300 * rpx, 460 * rpx);
// 绘制行业文字
ctx.setFontSize(20 * rpx);
ctx.setFillStyle('#fff');
ctx.setTextAlign('center');
ctx.fillText(that.data.upost,60 * rpx,30* rpx); // 参数:文本内容,x,y
// 绘制名字文字
ctx.setFontSize(40 * rpx);
ctx.setFillStyle('#fff');
ctx.setTextAlign('center');
ctx.fillText(that.data.uname, 150 * rpx, 80 * rpx);
// 绘制联系电话
ctx.setFontSize(20 * rpx);
ctx.setFillStyle('#fff');
ctx.setTextAlign('left')
ctx.fillText(that.data.ucompany, 80 * rpx, 120 * rpx);
ctx.draw(); // 将内容添加到canvas上
},
/* 保存图片 */
saveImg() {
wx.showLoading({
title: '正在保存',
mask: true,
})
wx.canvasToTempFilePath({
canvasId: 'myCanvas',
success: (res) => {
wx.hideLoading();
wx.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success(res) {
wx.showToast({
title: '保存成功!',
})
}
})
}
});
},
/* 取消保存 */
closeDialog() {
wx.showToast({
title: '已取消保存!',
});
this.setData({
isHidde: true,
});
this.resetCanvas();
},
/* 重置图片模板内容 */
resetCanvas() {
this.setData({
hiddeButton: false,
});
this.getcanvas();
},
})
其中还有一个就是用v-model
绑定数据,通过bindinput
绑定事件监听用户动态输入的信息,在事件处理中,通过setData
设置变量的值为所输入的信息:
that.setData({
ucompany: e.detail.value,
})
其他也是类似如此。
card.wxss:
.canvas-bottom {
display: flex;
flex-direction: row;
margin-top: 70rpx;
width: auto;
box-sizing: border-box;
justify-content: space-around;
}
.btn-save {
text-align: center;
border-radius: 30rpx;
/* margin-left: 50rpx; */
width: 130rpx;
font-size: 14px;
padding: 13rpx 40rpx;
/* background-color: #2fa5ff; */
background-color:#7F7AA6 ;
color: #fff;
}
.btn-close {
text-align: center;
border-radius: 30rpx;
width: 130rpx;
/* margin-right: 50rpx; */
font-size: 14px;
padding: 13rpx 40rpx;
border: 1rpx solid #7F7AA6 ;
color: #7F7AA6 ;
}
.create-btn {
width: 100%;
height: 60rpx;
font-size: 14px;
background-color: #7F7AA6 ;
}
.content {
height: 100vh;
}
.canvas-content {
background: #ffffff;
position: relative;
margin: 0 auto;
}
.canvas-content .con {
/* background: #AE0001; */
width: 690rpx;
position: relative;
margin: 0 auto;
}
.canvas {
margin: 15rpx auto;
}
.canvas-content {
width: 750rpx;
padding-bottom: 60rpx;
}
.info {
position: absolute;
left: 0rpx;
top: 0rpx;
height: 300rpx;
}
.show-name-text {
font-size: 72px;
color: #fff;
width: 600rpx;
text-align: center;
}
.show-post-text {
font-size: 32px;
color: #fff;
width: 600rpx;
text-align: center;
}
.choose {
width: 100vw;
margin-top: 100rpx;
display: flex;
justify-content: center;
}
.choose .choose-btn {
width: 60%;
margin-top: 30rpx;
display: flex;
justify-content: space-around;
}
.choose .choose-btn .abtn,
.bbtn {
margin-right: 20rpx;
font-size: 16px;
color: #424242;
text-align: center;
}
.choose .choose-btn .abtn {
border: 1rpx solid #7F7AA6 ;
color: #7F7AA6 ;
}
.edit-tips {
height: 160rpx;
background: #eee;
padding-left: 30rpx;
font-size: 24rpx;
color: #969696;
line-height: 240rpx;
}
.edit-canvas {
width: 750rpx;
height: 300rpx;
text-align: center;
line-height: 300rpx;
background: #F80101;
}
.line {
width: 100%;
height: 1rpx;
}
.company-text {
line-height: 60rpx;
height: 60rpx;
}
.show-company-text {
line-height: 60rpx;
height: 60rpx;
padding-left: 30rpx;
color: #fff;
width: 750rpx;
text-align: left;
font-size: 40rpx;
}
.input {
width: 440rpx;
height:70rpx;
margin-top: 15rpx;
padding-left: 30rpx;
border-radius: 44rpx;
background: #f5f5f5;
display: inline-block;
}
.company-name-label,.name-post-label {
float: left;
margin-right: 30rpx;
color: #747474;
}
.name-label,.post-label {
float: left;
color: #747474;
width: 160rpx;
}
.show-post{
background: #fff;
height: 80rpx;
padding-left: 30rpx;
line-height: 80rpx;
}
.show-company {
background: #fff;
height: 80rpx;
padding-left: 30rpx;
line-height: 80rpx;
}
.show-name {
padding-left: 30rpx;
background: #fff;
height: 80rpx;
line-height: 80rpx;
}
.show-post {
padding-left: 30rpx;
background: #fff;
height: 80rpx;
line-height: 80rpx;
}
.create-btn {
height: 80rpx;
text-align: center;
font-size: 32rpx;
color: #fff;
text-align: center;
border-radius: 0rpx;
background:#7F7AA6 ;
margin-top: 160rpx;
width: 100%;
position: fixed;
bottom: 0;
left: 0;
}
.create-btn .btn {
text-align: center;
color: #fff;
font-size: 16px;
background: none;
}
card.json:
{
"usingComponents": {},
"navigationBarTitleText":"模板编辑"
}
因为图片网络上拿来的,需要设置不检验合法域名,纯属周末瞎玩!
源码下载:
以上是关于小程序用canvas 实现一个简易的移动端名片可编辑小程序的主要内容,如果未能解决你的问题,请参考以下文章
一种基于AndroidiOS平台的移动端名片识别SDK,商务得力助手
使用 rollup 打包一个原生 js + canvas 实现的移动端手势解锁功能组件