liuhj 9 miesięcy temu
rodzic
commit
de9e804745
2 zmienionych plików z 205 dodań i 13 usunięć
  1. 202 13
      src/components/EvaluationForm.vue
  2. 3 0
      src/main.js

+ 202 - 13
src/components/EvaluationForm.vue

@@ -1,15 +1,204 @@
 <template>
-    <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>
-</template>
-<script>
-export default {
-    
-}
-</script>
-<style>
-    
-</style>
-
-
+  </template>
+  
+  <script>
+  export default {
+    name: 'Signatrue',
+    data () {
+      return {
+        canvas: null, // 存储canvas节点
+        ctx: null, // 存储canvas的context上下文
+        config: {
+          width: 400, // 宽度
+          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')
+  
+        // 设置相应配置
+        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 { offsetX, offsetY, pageX, pageY } = this.mobileStatus ? event.changedTouches[0] : event
+  
+        // 修改上次的偏移量及坐标
+        this.client.offsetX = offsetX
+        this.client.offsetY = offsetY
+        this.client.endX = pageX
+        this.client.endY = pageY
+  
+        // 清除以上一次 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
+        // 修改最后一次绘制的坐标点
+        this.client.endX = pageX
+        this.client.endY = pageY
+        const obj = {
+          x: pageX,
+          y: pageY
+        }
+  
+        // 根据坐标点位移动添加线条
+        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>

+ 3 - 0
src/main.js

@@ -8,6 +8,7 @@ import 'element-ui/lib/theme-chalk/index.css';
 import './assets/icon/iconfont.css'
 import store from './store/index.js';
 import VueTypedJs from 'vue-typed-js'
+
 //富文本
 import VueQuillEditor from 'vue-quill-editor'
 import 'quill/dist/quill.core.css'
@@ -25,6 +26,8 @@ import cookie from 'vue-cookie'
 Vue.prototype.$cookie = cookie;  //配置时候prototype.$这里的名字自己定义不是固定是cookie
 
 Vue.use(VueTypedJs)
+
+
 import axios from 'axios';
 axios.defaults.baseURL = 'http://132.232.92.186:8888';
 //axios.defaults.baseURL = 'http://localhost:5256/';