实现电子签名(vue)

代码如下:

<template>
    <div class="canvas-content">
        <div :class="{'canvas-container': type == 90 || type == -90, 'canvas-container-vertical': type == 0 || type == 180}">
            <canvas id="signCanvas"></canvas>
        </div>
        <div class="vertical-text" v-if="type == 0 || type == 180">
            <p>横屏体验更佳哦!</p>
        </div>
        <div class="canvas-operation">
            <button @click="handelClearEl">清除</button>
            <button @click="saveImage">保存</button>
        </div>
    </div>
</template>
<script>
export default {
    data() {
        return {
            imgsrc: '',
            type: 0,
        }
    },
    mounted() {
        let vm = this;
        this.$nextTick(() => {
            setTimeout(() => {
                vm.greenType()
            }, 100)
        })
    },
    methods: {
    	// 横屏和竖屏下的展示不一样的样式
        greenType() {
            let that = this;
            // 竖屏时
            if (window.orientation == 0 || window.orientation == 180) {
                // 竖屏时通过type来设置不同样式
                this.type = window.orientation;
                // 初始化画布
                this.initCanvas(window.orientation);
                // 横屏时
            } else if (window.orientation == 90 || window.orientation == -90) {
                // 横屏时通过type来设置不同样式
                this.type = window.orientation;
                // 初始化画布
                this.initCanvas(window.orientation);
                
            }
            window.addEventListener("orientationchange", function() {
                if (window.orientation == 0 || window.orientation == 180) {
                    // 在横竖更换后要清除之前的画布
                    let oCanvas = document.getElementById("signCanvas");
                    let cxt = oCanvas.getContext("2d");
                    // 在一个画布的一个矩形区域中清除掉像素,这时的矩形框也清除了
                    cxt.clearRect(0, 0, oCanvas.width, oCanvas.height);
                    that.type = window.orientation;
                    // 加入计时器防止画布还没有渲染就被初始化了,导致找不到canvas
                    setTimeout(() => {
                        that.initCanvas(window.orientation);
                    }, 100)
                    
                } else if (window.orientation == 90 || window.orientation == -90){
                    // 在横竖更换后要清除之前的画布
                    let oCanvas = document.getElementById("signCanvas");
                    let cxt = oCanvas.getContext("2d");
                    // 在一个画布的一个矩形区域中清除掉像素,这时的矩形宽也清除了
                    cxt.clearRect(0, 0, oCanvas.width, oCanvas.height);
                    that.type = window.orientation;
                    setTimeout(() => {
                        that.initCanvas(window.orientation);
                    }, 100)
                    
                }
            }, false);
        },
        // 初始化画布
        initCanvas(type) {
            let oCanvas = document.getElementById('signCanvas');
            if (type == 0 || type == 180) {
                oCanvas.width = oCanvas.offsetWidth;
                oCanvas.height = 300;
            } else if (type == 90 || type == -90) {
                oCanvas.width = oCanvas.offsetWidth;
                oCanvas.height = oCanvas.offsetHeight;
            }

            // 获取画布绘图环境
            let cxt = oCanvas.getContext('2d');
            // 设置画布绘图背景色
            cxt.fillStyle = "#fff";
            // 使用fillStyle属性所指的颜色.渐变或模式来填充指定的矩形
            cxt.fillRect(0, 0, oCanvas.width, oCanvas.height);
            // 指定用于画笔(绘制)路径的颜色
            cxt.strokeStyle = "#101010";
            // 画笔的大小设置
            cxt.lineWidth = 2 * (oCanvas.width/oCanvas.height);
            let posX = 0;
            let posY = 0;
            // 获取canvas的DOMrect对象
            let parentPosintin = oCanvas.getBoundingClientRect();
            
            oCanvas.ontouchstart = function(event) {
                // 获取手指开始触摸的位移
                posX = event.changedTouches[0].clientX ;
                // y轴要减去没有画布的部分,并留出.5的距离;
                // posY = event.changedTouches[0].clientY - parentPosintin.top + 0.5;
                posY = event.changedTouches[0].clientY ;
                // 开始画布中的一条新路径(或者子路径的集合)
                cxt.beginPath();
                // 设置当前位置并开始一条新的子路径。
                cxt.moveTo(posX, posY);
            }

            // // 手指滑动画线
            oCanvas.ontouchmove = function (event) {
                optimizedMove(event);
            }
            // 执行一个动画,在下一次重绘之前调用指定回调函数
            let requestAnimationFrame = window.requestAnimationFrame;
            let optimizedMove = requestAnimationFrame ? function(e) {
                requestAnimationFrame(function() {
                    // 再下一个动画前执行的回调
                    move(e);
                });
            } : move;
            
            function move(event) {
                // 手指移动后重新获取坐标
                posX = event.changedTouches[0].clientX;
                posY = event.changedTouches[0].clientY;
                // posY = event.changedTouches[0].clientY - parentPosintin.top + 0.5;
                // 为当前的子路径添加一条直线,参数为终点坐标
                cxt.lineTo(posX, posY);
                // 绘制当前路径
                cxt.stroke();
            }

        },
        // 清除画布
        handelClearEl() {
            let oCanvas = document.getElementById("signCanvas");
            let cxt = oCanvas.getContext("2d");
            // 在一个画布的一个矩形区域中清除掉像素,这时的矩形宽也清除了
            cxt.clearRect(0, 0, oCanvas.width, oCanvas.height);
            // 所以要重新创建矩形画布
            this.initCanvas();
        },
        // 保存图片
        saveImage() {
            let oCanvas = document.getElementById("signCanvas");
            let cxt = oCanvas.getContext("2d");
            // HTMLCanvasElement.toDataURL() 方法返回一个包含图片展示的 data URI 。可以使用 type 参数其类型,默认为 PNG 格式。图片的分辨率为96dpi。
            let imgBase64 = oCanvas.toDataURL();
            this.imgsrc = imgBase64;
            // 向父组件传值
            this.$emit('returnImageUrl', this.imgsrc);
            // 最后清空矩形画布
            cxt.clearRect(0, 0, oCanvas.width, oCanvas.height)
        },
    }
}
</script>
<style lang="less" scoped>
    .canvas-content {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        z-index: 1111111;
        background: #bbb;
        .vertical-text {
            p {
                color: #ddd;
                font-size: 20px;
                margin: 40px 0;
                text-align: center;

            }
        }
        .canvas-operation {
            width: 100%;
            height: 40px;
            position: fixed;
            bottom: 0;
            left: 0;
            z-index: 111111111;
            background: #ccc;
            button {
                width: 70px;
                height: 40px;
                background: #aaa;
                margin: 0 10px;
                outline: none;
                &:active {
                    background: #888;
                }
            }
        }
        .canvas-container {
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            bottom: 40px;
            background: green;
            #signCanvas {
                width: 100%;
                height: calc(100% - 40px);
                background: #fff;
                border: none;
                box-sizing: border-box;
                overflow: hidden;
                position: fixed;
                top: 0;
                left: 0;
                z-index: 1111111112;
            }
        }
        .canvas-container-vertical {
            width: 100%;
            height: 300px;
            position: relative;
            top: 0;
            left: 0;
            background: green;
            #signCanvas {
                width: 100%;
                height: 100%;
                background: #fff;
                border: none;
                box-sizing: border-box;
                overflow: hidden;
                position: relative;
                top: 0;
                left: 0;
                bottom: 40px;
                z-index: 1111111112;
            }
        }
    }

</style>

效果如下:

竖屏

java 文档电子章_java 文档电子章


横屏

java 文档电子章_竖屏_02