uni-app
imgCode页面
<template>
<view class="register">
<view class="content">
<!-- 注册input主体 -->
<view class="main">
<view class="canvas-img-code" @click="refresh()">
<canvas :style="{width:width+'px',height:height+'px'}" canvas-id="imgcanvas" @error="canvasIdErrorCallback"></canvas>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
var _this;
export default {
data() {
return {
logoImage: '../../static/images/logo.png', //logo图
phoneData: '', // 手机号
passData: '', //密码
verCode: "", //验证码
passDataAgain: "", //确认密码
isRotate: false, //注册按钮是否加载旋转特效
width: 100,
height: 32
}
},
onShow() {
this.init();
},
methods: {
// 初始化验证码
init: function() {
console.log('start');
var context = uni.createCanvasContext('imgcanvas', this),
w = this.width,
h = this.height;
context.setFillStyle("white"); //填充绘画的颜色、渐变或模式
context.setLineWidth(5);
context.fillRect(0, 0, w, h); //绘制“被填充”的矩形
var pool = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"
],
str = '';
for (var i = 0; i < 4; i++) {
var c = pool[this.rn(0, pool.length - 1)];
var deg = this.rn(-30, 30);
context.setFontSize(18);
context.setTextBaseline("top");
context.setFillStyle(this.rc(80, 150));
context.save();
context.translate(30 * i + 15, parseInt(h / 1.5));
context.rotate(deg * Math.PI / 180);
context.fillText(c, -15, -15);
context.restore();
str += c;
}
uni.setStorage({
key: 'imgcode',
data: str,
});
this.$emit("getImgCode",str);
for (var i = 0; i < 40; i++) {
context.beginPath();
context.arc(this.rn(0, w), this.rn(0, h), 1, 0, 2 * Math.PI);
context.closePath();
context.setFillStyle(this.rc(150, 200));
context.fill();
}
context.draw();
console.log('end');
},
rc: function(min, max) {
var r = this.rn(min, max);
var g = this.rn(min, max);
var b = this.rn(min, max);
return "rgb(" + r + "," + g + "," + b + ")";
},
rn: function(max, min) {
return parseInt(Math.random() * (max - min)) + min;
},
refresh: function() {
this.init();
},
canvasIdErrorCallback: function(e) {
console.error(e.detail.errMsg)
}
},
mounted() {
this.init()
}
}
</script>
<style>
.codeView {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
}
.canvas-img-code {
display: inline-block;
border: 1px solid #eee;
height: 64rpx;
width: 200rpx;
margin-left: 14rpx;
border-radius: 10rpx;
}
</style>
引入
<imgCode @getImgCode="getImgCode" style="padding: 0 10rpx;"></imgCode>
import imgCode from './components/imgCode.vue';
components:{
imgCode
},
/*验证码 */
getImgCode(data){
this.YZM=data;
},
uni-app示意图
vue
<template>
<div class="s-canvas">
<canvas id="s-canvas" :width="contentWidth" :height="contentHeight" @click="changeNum"></canvas>
</div>
</template>
<script>
export default {
name: 'SIdentify',
data(){
return{
identifyCode:'',
fontSizeMin:25,
fontSizeMax:35,
backgroundColorMin:200,
backgroundColorMax:200,
dotColorMin:120,
dotColorMin:60,
contentWidth:116,
contentHeight:38
}
},
methods: {
changeNum(){
let randomNum=(this.randomNum(1000,9999));
this.identifyCode=randomNum.toString();
this.$emit('emitCode',this.identifyCode);
this.drawPic();
},
// 生成一个随机数
randomNum(min, max) {
return Math.floor(Math.random() * (max - min) + min)
},
// 生成一个随机的颜色
randomColor(min, max) {
let r = this.randomNum(min, max)
let g = this.randomNum(min, max)
let b = this.randomNum(min, max)
return 'rgb(' + r + ',' + g + ',' + b + ')'
},
drawPic() {
let canvas = document.getElementById('s-canvas')
let ctx = canvas.getContext('2d')
ctx.textBaseline = 'bottom'
// 绘制背景
ctx.fillStyle = this.randomColor(this.backgroundColorMin, this.backgroundColorMax)
ctx.fillRect(0, 0, this.contentWidth, this.contentHeight)
// 绘制文字
for (let i = 0; i < this.identifyCode.length; i++) {
this.drawText(ctx, this.identifyCode[i], i)
}
this.drawLine(ctx)
this.drawDot(ctx)
},
drawText(ctx, txt, i) {
ctx.fillStyle = this.randomColor(50, 160) //随机生成字体颜色
ctx.font = this.randomNum(this.fontSizeMin, this.fontSizeMax) + 'px SimHei' //随机生成字体大小
let x = (i + 1) * (this.contentWidth / (this.identifyCode.length + 1))
let y = this.randomNum(this.fontSizeMax, this.contentHeight - 5)
var deg = this.randomNum(-30, 30)
// 修改坐标原点和旋转角度
ctx.translate(x, y)
ctx.rotate(deg * Math.PI / 180)
ctx.fillText(txt, 0, 0)
// 恢复坐标原点和旋转角度
ctx.rotate(-deg * Math.PI / 180)
ctx.translate(-x, -y)
},
drawLine(ctx) {
// 绘制干扰线
for (let i = 0; i < 4; i++) {
ctx.strokeStyle = this.randomColor(100, 200)
ctx.beginPath()
ctx.moveTo(this.randomNum(0, this.contentWidth), this.randomNum(0, this.contentHeight))
ctx.lineTo(this.randomNum(0, this.contentWidth), this.randomNum(0, this.contentHeight))
ctx.stroke()
}
},
drawDot(ctx) {
// 绘制干扰点
for (let i = 0; i < 30; i++) {
ctx.fillStyle = this.randomColor(0, 255)
ctx.beginPath()
ctx.arc(this.randomNum(0, this.contentWidth), this.randomNum(0, this.contentHeight), 1, 0, 2 * Math.PI)
ctx.fill()
}
}
},
/* watch: {
identifyCode() {
this.drawPic()
}
}, */
mounted() {
this.changeNum();
}
}
</script>
引入
<codeP @emitCode="emitCode"></codeP>
import codeP from './code.vue';
components: {
loading
},
/*验证码 */
emitCode(data) {
this.code = data;
},
示意图: