<template>
    <div class="ml_sign-all">
        <div class="ml_sign-form">
            <el-form :model="signinfo" :rules="signrules" ref="signinfo" label-width="80px" class="demo-ruleForm">
                <el-form-item label="团队:" prop="tname">
                    <el-input size="small" v-model="signinfo.tname"></el-input>
                </el-form-item>
                <el-form-item label="人数:" prop="tname">
                    <el-input size="small" v-model="signinfo.tname"></el-input>
                </el-form-item>
                <!-- <el-form-item label="领队:" prop="tname">
                    <el-input size="small" v-model="signinfo.tname"></el-input>
                </el-form-item>
                <el-form-item label="导游:" prop="tname">
                    <el-input size="small" v-model="signinfo.tname"></el-input>
                </el-form-item>
                <el-form-item label="行程:" prop="tname">
                    <el-input size="small" v-model="signinfo.tname"></el-input>
                </el-form-item>
                <el-form-item label="天数:" prop="tname">
                    <el-input size="small" v-model="signinfo.tname"></el-input>
                </el-form-item> -->
            </el-form>
        </div>
        <div class="ml_sign">
            <canvas ref="signature" id="signature"></canvas>
            <div class="btn-wrapper">
              <button @click="clear">取消</button>
              <button @click="save">保存</button>
            </div>
            <img :src="imgurl">
        </div>
    </div>
  </template>
  
<script>
export default {
    name: 'Signatrue',
    data() {
        return {
            signinfo:{
                tname:'',
            },
            signrules:{
                tname: [
                    { required: true, message: '请输入活动名称', trigger: 'blur' },
                    { min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' }
                ],
            },
            canvas: null, // 存储canvas节点
            ctx: null, // 存储canvas的context上下文
            config: {
                width: 350, // 宽度
                height: 200, // 高度
                strokeStyle: 'red', // 线条颜色
                lineWidth: 4, // 线条宽度
                lineCap: 'round', // 设置线条两端圆角
                lineJoin: 'round' // 线条交汇处圆角
            },
            points: [], // 记录坐标 用来判断是否有签名的
            client: {
                offsetX: 0, // 偏移量
                offsetY: 0,
                endX: 0, // 坐标
                endY: 0
            },
            imgurl: ''
        }
    },
    computed: {
        // 判断是否为移动端
        mobileStatus() {
            return (/Mobile|Android|iPhone/i.test(navigator.userAgent))
        }
    },
    mounted() {
        this.init()
    },
    methods: {
        // 初始化
        init() {
            const canvas = this.$refs.signature
            canvas.width = this.config.width // 设置canvas的宽
            canvas.height = this.config.height // 设置canvas的高
            // 设置一个边框
            canvas.style.border = '1px solid #000'

            // 存储canvas节点
            this.canvas = canvas
            // 创建context对象
            this.ctx = canvas.getContext('2d')
            console.log(this.ctx);
            
            // 设置相应配置
            this.ctx.fillStyle = 'transparent'
            this.ctx.lineWidth = this.config.lineWidth
            this.ctx.strokeStyle = this.config.strokeStyle
            this.ctx.lineCap = this.config.lineCap
            this.ctx.lineJoin = this.config.lineJoin

            // 绘制填充矩形
            this.ctx.fillRect(
                0, // x 轴起始绘制位置
                0, // y 轴起始绘制位置
                this.config.width, // 宽度
                this.config.height // 高度
            )

            
            // 创建鼠标/手势按下监听器
            canvas.addEventListener(this.mobileStatus ? 'touchstart' : 'mousedown', this.startDraw)
            // 创建鼠标/手势 弹起/离开 监听器
            canvas.addEventListener(this.mobileStatus ? 'touchend' : 'mouseup', this.cloaseDraw)
        },
        // 开始绘制
        startDraw(event) {
            // 获取偏移量及坐标
            const { clientX, clientY, pageX, pageY } = this.mobileStatus ? event.changedTouches[0] : event
            const rect = this.$refs.signature.getBoundingClientRect();
            console.log(event);
            
            // 修改上次的偏移量及坐标
            this.client.offsetX = clientX-rect.left
            this.client.offsetY = clientY-rect.top
            this.client.endX = pageX-rect.left
            this.client.endY = pageY-rect.top
            console.log(this.client.offsetX,this.client.offsetY,this.client.endX,this.client.endY);
            

            // 清除以上一次 beginPath 之后的所有路径，进行绘制
            this.ctx.beginPath()
            // 设置画线起始点位
            this.ctx.moveTo(this.client.endX, this.client.endY)
            // 监听 鼠标移动或手势移动
            this.canvas.addEventListener(this.mobileStatus ? 'touchmove' : 'mousemove', this.draw)
        },
        // 绘制
        draw(event) {
            // 获取当前坐标点位
            const { pageX, pageY } = this.mobileStatus ? event.changedTouches[0] : event
            const rect = this.$refs.signature.getBoundingClientRect();
            // 修改最后一次绘制的坐标点
            this.client.endX = pageX-rect.left
            this.client.endY = pageY-rect.top
            const obj = {
                x: pageX,
                y: pageY
            }

            console.log(obj);
            
            // 根据坐标点位移动添加线条
            this.ctx.lineTo(pageX, pageY)

            // 绘制
            this.ctx.stroke()

            // 记录坐标
            this.points.push(obj)
        },
        // 结束绘制
        cloaseDraw() {
            // 结束绘制
            this.ctx.closePath()
            // 移除鼠标移动或手势移动监听器
            this.canvas.removeEventListener('mousemove', this.draw)
        },
        // 取消/清空画布
        clear() {
            // 清空当前画布上的所有绘制内容
            this.ctx.clearRect(0, 0, this.config.width, this.config.height)
            // 清空坐标
            this.points = []
        },
        // 保存
        save() {
            // 判断至少有20个坐标 才算有签名
            if (this.points.length < 20) {
                alert('签名不能为空!')
                return
            }

            // 操作事件
            const baseFile = this.canvas.toDataURL() // 转成base64,默认转成png格式的图片编码
            const filename = `${Date.now()}.png` // 文件名字
            const file = this.dataURLToFile(baseFile, filename) // 图片文件形式 传给后端存储即可

            this.uploadSignatrue(file)

            // this.dataUrlToPng()

            // this.dataToImg()
        },
        // img显示签名
        dataToImg() {
            // 转成base64
            const baseFile = this.canvas.toDataURL() // 默认转成png格式的图片编码
            this.imgurl = baseFile
        },
        // 将签名生成png图片
        dataUrlToPng() {
            // 将canvas上的内容转成blob流
            this.canvas.toBlob(blob => {
                // 获取当前时间并转成字符串，用来当做文件名
                const date = Date.now().toString()
                // 创建一个 a 标签
                const a = document.createElement('a')
                // 设置 a 标签的下载文件名
                a.download = `${date}.png`
                // 设置 a 标签的跳转路径为 文件流地址
                a.href = URL.createObjectURL(blob)
                // 手动触发 a 标签的点击事件
                a.click()
                // 移除 a 标签
                a.remove()
            })
        },
        // 将base64转成File文件对象
        dataURLToFile(dataURL, filename) {
            const arr = dataURL.split(',')
            // 获取图片格式
            const imgType = arr[0].match(/:(.*?);/)[1]
            // atob() 方法用于解码使用 base-64 编码的字符串
            const dec = atob(arr[1])
            let n = dec.length
            const u8arr = new Uint8Array(n)
            while (n--) {
                // 转成ASCII码
                u8arr[n] = dec.charCodeAt(n)
            }
            return new File([u8arr], filename, { type: imgType })
        },
        // 上传签名
        uploadSignatrue(file) {
            const formData = new FormData()
            formData.append('file', file)
            // formData.append('paramsOne', paramsOne)
            // ...
            console.log(formData)

            // 上传接口 这里就不赘述了
            // uploadFile(params, ...)
        }
    }
}
</script>
<style>
*{
    padding: 0;
    margin: 0;
}
.ml_sign-all{
    padding: 10px;
}
.ml_sign-form .el-form-item{
    width: 350px;
    margin-bottom: 10px;
}
.ml_sign-form .el-form-item__error{
    top: 85%;
}
.ml_sign-form .el-form-item__label {
    position: relative; /* 设置相对定位作为星号的定位基准 */
    text-align: justify;
    text-align-last: justify; /* 确保最后一行也两端对齐 */
    padding-left: 10px; /* 为星号预留空间 */
}

.ml_sign-form .el-form-item__label:before {
    content: '*';
    color: red;
    position: absolute;
    left: 0; /* 星号定位到标签最左侧 */
    top: 0; /* 调整垂直位置以适应行高 */
}
.ml_sign-form .el-form{
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
}
</style>
