weex實現手勢密碼效果

實現手勢密碼效果需要使用weex-gcanvas,繼承weex-gcanvas請參考Weex Gcanves集成和使用

效果圖:

手勢密碼
手勢密碼效果

 

組件封裝代碼:

<template>
    <div class="container" :style="{width:width,height:height}">
        <div class="pan" :style="{width:size,height:size,backgroundColor:backgroundColor}">
            <gcanvas class="canvas" @touchstart="touchStart" @touchmove="touchMove" @touchend="touchEnd" ref="areas"
                     :style="{width:size,height:size,left:0,top:0}">
            </gcanvas>
            <div ref="dot" :class="[item.select?'dot_select':'dot']" :index="index" v-for="(item,index) in dots"
                 :style="{left:(item.select?45:70)+size/3*item.x,top:(item.select?45:70)+size/3*item.y}"></div>
        </div>

    </div>
</template>

<script>
    var libGCanvas=require("weex-gcanvas");
    let modal=weex.requireModule('modal');
    let dom=weex.requireModule('dom');
    export default {
        name: "gesture-password",
        props:{
            //手勢面板大小
            size:{
                default:600,
                type:Number
            },
            //手勢面板背景色
            backgroundColor:{
                default:"orange",
                type:String
            },
            //整個組件的寬度
            width:{
                default:750,
                type:Number
            },
            //整個組件的高度
            height:{
                default:800,
                type:Number
            },
            touchRadius:{
                default:50,
                type:Number
            }
        },
        data(){
            return{
                dots:[ {x:0,y:0,select:false},{x:1,y:0,select:false},{x:2,y:0,select:false},
                       {x:0,y:1,select:false},{x:1,y:1,select:false},{x:2,y:1,select:false},
                       {x:0,y:2,select:false},{x:1,y:2,select:false},{x:2,y:2,select:false}
                    ],
                real_x_y_done:false,
                path:[],
                context:{}
            }
        },
        methods:{
            clear(){
                this.dots.forEach(item=>{
                    item.select=false;
                });
                this.path=[];
                this.context.fillStyle=this.backgroundColor;
                this.context.beginPath();
                this.context.fillRect(0,0,this.size,this.size);
                this.context.closePath();
            },
            touchStart(event){
                let self=this;
                if(!this.real_x_y_done){
                    this.setReal_X_Y()
                }
                // modal.alert({message:event.changedTouches[0]})
                let touchX=event.changedTouches[0].screenX;
                let touchY=event.changedTouches[0].screenY;
                this.dots.forEach(item=>{
                    if(touchX>item.realX-this.touchRadius&&touchX<item.realX+this.touchRadius
                        &&touchY>item.realY-this.touchRadius&&touchY<item.realY+this.touchRadius){
                        item.select=true;
                        self.path.push({x:item.realX-(self.width-self.size)/2+25,y:item.realY
                            -(self.height-self.size)/2+25,dataX:item.x,dataY:item.y});
                    }
                })
            },
            touchMove(event){
                let self=this;
                let touchX=event.changedTouches[0].screenX;
                let touchY=event.changedTouches[0].screenY;
                // if(self.path.length!=0){
                //     let lastIndex=self.path.length-1;
                //     self.context.restore()
                //     self.context.moveTo(self.path[lastIndex].x,self.path[lastIndex].y);
                //     self.context.lineTo(touchX-(750-self.size)/2+25,touchY-(1000-self.size)/2+25);
                //     self.context.stroke();
                //     self.context.save();
                // }
                this.dots.forEach(item=>{
                    if(touchX>item.realX-this.touchRadius&&touchX<item.realX+this.touchRadius&&
                        touchY>item.realY-this.touchRadius&&touchY<item.realY+this.touchRadius){
                        if(!item.select){
                            item.select=true;
                            if(self.path.length==0){
                                self.path.push({x:item.realX-(self.width-self.size)/2+25,y:item.realY
                                    -(self.height-self.size)/2+25,dataX:item.x,dataY:item.y});
                            }else{
                                self.path.push({x:item.realX-(self.width-self.size)/2+25,y:item.realY
                                    -(self.height-self.size)/2+25,dataX:item.x,dataY:item.y});
                                self.drawPath()
                            }

                        }
                    }
                })
            },
            drawPath(){
                let self=this;
                let lastIndex=self.path.length-2;
                let nowIndex=self.path.length-1;
                self.context.moveTo(self.path[lastIndex].x,self.path[lastIndex].y);
                self.context.lineTo(self.path[nowIndex].x,self.path[nowIndex].y);
                self.context.stroke();
            },
            touchEnd(event){
                 let self=this;
                 //返回繪製的路徑數據,去每個點的x,y屬性對比
                 this.$emit("gestureEnd",self.path);
                 self.clear();
            },
            /*得到每個點在屏幕中的真實座標*/
            setReal_X_Y(){
                let self=this;
                for (let i=0;i<9;i++){
                    let dot=this.$refs['dot'][i].ref;
                    dom.getComponentRect(dot,function (res) {
                        self.$set(self.dots[i],"realX",res.size.left);
                        self.$set(self.dots[i],"realY",res.size.top);
                    });
                }
                this.real_x_y_done=true;
            }
        },
        created(){
            let self=this;
            /*獲取元素引用*/
            setTimeout(function () {
                let ref=self.$refs.areas;
                // modal.alert({message:ref})
                /*通過元素引用獲取canvas對象*/
                self.canvasObj =libGCanvas.start(ref);
                /*獲取繪圖所需的上下文,目前不支持3d*/
                self.context =  self.canvasObj.getContext('2d');
                self.context.lineWidth=10;
                self.context.strokeStyle = "#268cf0"
            },200);

        }
    }
</script>

<style scoped>
    .canvas{
        position: absolute;
        background-color: rgba(1,1,1,0);
    }
    .container{
        justify-content: center;
        align-items: center;
    }
    .pan{

    }
    .dot{
        width: 50px;
        height: 50px;
        border-radius: 50px;
        background-color: white;
        border-width: 10px;
        border-color: #eeeeee;
        position: absolute;
        transition-property: width,height,top,left;
        transition-duration:.25s;
        transition-delay: .1s;
        transition-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1.0);
    }
    .dot_select{
        width: 100px;
        height: 100px;
        border-radius: 50px;
        background-color: white;
        border-width:10px;
        border-color: #268cf0;
        position: absolute;
        transition-property: width,height,top,left;
        transition-duration:.25s;
        transition-delay: .1s;
        transition-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1.0);
    }
</style>

使用代碼:

<template>
    <div>
        <gesture-password height="1200" width="750" size="600" @gestureEnd="gestureEnd"></gesture-password>
    </div>
</template>

<script>
    import GesturePassword from "../components/gesturePassword.vue";
    let modal=weex.requireModule('modal');
    export default {
        components: {GesturePassword},
        name: "gesture-pwd-demo",
        data() {
            return {
                oldPwd:[],
                pwd:[]
            }
        },
        methods:{
            gestureEnd(path){
                let self=this;
                if(this.pwd.length!=0){
                    let can=true;
                    if(path.length!=this.pwd.length){
                        modal.toast({message:"密碼錯誤!"});
                        return;
                    }
                    path.forEach((item,index)=>{
                        if(item.x!=self.pwd[index].x||item.y!=self.pwd[index].y){
                            can=false;
                        }
                    });
                    if(can){
                        modal.toast({message:"密碼正確!"});
                    }else{
                        modal.toast({message:"密碼錯誤!"});
                    }
                    return;
                }
                if(this.oldPwd.length==0){
                    this.oldPwd=path;
                    modal.toast({message:"在繪製一次確認密碼"});
                }else{
                    let can=true;
                    if(this.oldPwd.length!=path.length){
                        modal.toast({message:"兩次繪製不一致"});
                        this.oldPwd=[];
                        return;
                    }
                    this.oldPwd.forEach((item,index)=>{
                           if(item.x!=path[index].x||item.y!=path[index].y){
                               can=false;
                           }
                    });
                    if(can){
                        this.pwd=path;
                        modal.toast({message:"設置手勢密碼成功"});
                    }else{
                        this.oldPwd=[];
                        modal.toast({message:"兩次繪製不一致"});
                    }
                }



            }
        }
    }
</script>

<style scoped>

</style>

示例代碼均會同步到我的開源項目中,可以隨時查看https://github.com/liuxinyea/IWeex

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章