componente de firma vue

Trabajo temporal a un amigo Escribir un extremo móvil del proyecto, el proyecto ha encontrado su característica de la firma de un documento PDF, sino también lanzar una pequeña componente de firma

Firma principio de componente: el uso de tela nativa con el movimiento final del evento, touchstart, touchend, touchmove, fueron trazando una línea sobre la tela de lona, ​​por último, para generar una firma, () Parada de toDataURL imagen método de base 64, consiguió la firma, y ​​lograr resultados son los siguientes:

lienzo en blanco, seleccionar el tipo de letra color de la firma, la función de ahorro, relativamente simple

en github  componente de firma

En el código ah 

Nota: Este proyecto usos Vant-ui, ver la presentación que se está dado un socio pequeño, recuerde que debe eliminar el componente Vant-ui, sin embargo, no puede ver algunos de los efectos, como el color de fuente, vacío, la confirmación

1. plantilla de la plantilla

<template>
  <div class="signHandle">
    <canvas ref="signHandle" class="canvas" />
    <div class="btn_container van-hairline--top" :style="{height:height + 'px'}">
      <van-radio-group v-model="radio" class="radio_container" @change="radioHandle">
        <van-radio v-for="item in liColors" :key="item" :checked-color="item" :name="item" />
      </van-radio-group>
      <div>
        <van-button size="mini" @touchstart="clearHandle">清空</van-button>
        <van-button type="info" size="mini" @touchstart="saveImg">确认</van-button>
      </div>
    </div>
  </div>
</template>

Algunos api 2. JS, es el lienzo, no se explica

<script>
// 解构设备的宽度, 和 高度
const { clientWidth, clientHeight } = document.documentElement
export default {
  data() {
    return {
      radio: '#000',
      height: 50,
      direction: false, // true 代表横屏, false 代表'竖屏'
      el: '', // canvas dom
      ctx: '', // canvas context
      background: '#fff', // canvas background-color
      color: '#000', // 绘制时线条的颜色
      linewidth: 3, // 线条的宽度
      liColors: ['#ee0a24', '#000', '#1890ff']
    }
  },
  created() {
    this.color = this.radio
    window.addEventListener(
      'onorientationchange' in window ? 'orientationchange' : 'resize',
      () => {
        if (window.orientation === 180 || window.orientation === 0) {
          this.direction = false
          this.draw()
        }
        if (window.orientation === 90 || window.orientation === -90) {
          this.direction = true
          this.draw()
        }
      },
      false
    )
  },
  mounted() {
    this.draw()
  },
  methods: {
    radioHandle(value) {
      this.color = value
      this.setCanvas()
    },
    // 添加绘制 line
    draw() {
      document.addEventListener('touchmove', e => e.preventDefault(), {
        passive: false
      })
      this.el = this.$refs.signHandle
      this.initCanvas()
    },
    // 初始化canvas配置
    initCanvas() {
      const { height, direction, el } = this
      if (direction) {
        el.width = clientHeight
        el.height = clientWidth - height
      } else {
        el.width = clientWidth
        el.height = clientHeight - height
      }
      this.ctx = el.getContext('2d')
      this.setCanvas()
      this.drawStart()
      this.drawing()
      this.drawEnd()
    },
    // 配置 canvas
    setCanvas() {
      const { ctx, height, direction } = this
      console.log(direction)
      // 设置背景色
      ctx.fillStyle = this.background
      // 绘制矩形
      if (direction) {
        ctx.fillRect(0, 0, clientHeight, clientWidth - height)
      } else {
        ctx.fillRect(0, 0, clientWidth, clientHeight - height)
      }

      // 设置线条颜色
      ctx.strokeStyle = this.color
      // 设置线宽
      ctx.lineWidth = this.linewidth
      // 设置线条两头的结束点和开始点是圆形的
      ctx.lineCap = 'round'
    },
    // 开始绘制
    drawStart() {
      const { el, ctx } = this
      el.addEventListener(
        'touchstart',
        e => {
          ctx.beginPath()
          ctx.moveTo(e.changedTouches[0].pageX, e.changedTouches[0].pageY)
        },
        false
      )
    },
    // 绘制中
    drawing() {
      const { el, ctx } = this
      el.addEventListener(
        'touchmove',
        e => {
          ctx.lineTo(e.changedTouches[0].pageX, e.changedTouches[0].pageY)
          ctx.stroke()
        },
        false
      )
    },
    // 绘制结束
    drawEnd() {
      const { el, ctx } = this
      el.addEventListener('touchend', () => ctx.closePath(), false)
    },
    // 清空
    clearHandle() {
      this.initCanvas()
    },
    // 保存信息
    saveImg() {
      const imgBase64 = this.el.toDataURL()
      console.log('保存签名成功' + imgBase64)
    }
  }
}
</script>

3. css

.signHandle {
  position: relative;
  background-color: #666;
  .canvas {
    position: absolute;
    top: 0;
    left: 0;
  }
  .btn_container {
    width: 100%;
    position: fixed;
    bottom: 0;
    left: 0;
    background-color: #fff;
    display: flex;
    align-items: center;
    padding: 0 15px;
    box-sizing: border-box;
    justify-content: space-between;
    .radio_container {
      display: flex;
      /deep/ .van-radio {
        margin-right: 10px;
        &:nth-child(1) {
          /deep/ .van-icon {
            background-color: #ee0a24;
          }
        }
        &:nth-child(2) {
          /deep/ .van-icon {
            background-color: #000;
          }
        }
        &:nth-child(3) {
          /deep/ .van-icon {
            background-color: #1890ff;
          }
        }
      }
    }
  }
}
</style>

 

Publicado 63 artículos originales · ganado elogios 100 · vistas 310 000 +

Supongo que te gusta

Origin blog.csdn.net/qq_36407748/article/details/102816145
Recomendado
Clasificación