移动端横屏绘制签名

WechatIMG1.jpeg
<div id="canvasBox" :style="getHorizontalStyle">
  <canvas id="signcanvas" :width="getHorizontalStyle.width" :height="getHorizontalStyle.height" ></canvas>
  <div>
     <button class="canvas-btn default" @touchstart="clear" title="button" @mousedown="clear">重写</button>
     <button class="canvas-btn" @touchstart="upload" title="button" >提交</button>
  </div>
</div>
  • 设置旋转角度
data (){
  return {
    degree: 90,
  }
}
  • 计算画布大小
computed: {
    getHorizontalStyle() {
      let d = document;
      let w = window.innerWidth || d.documentElement.clientWidth || d.body.clientWidth;
      let h = window.innerHeight || d.documentElement.clientHeight || d.body.clientHeight;
      let length = (h - w) / 2;
      let width = w;
      let height = h;
      switch (this.degree) {
        case -90:
          length = -length;
        case 90:
          width = h;
          height = w;
          break;
        default:
          length = 0;
      }
      if (this.canvasBox) {
        this.canvasBox.removeChild(document.querySelector('canvas'));
        this.canvasBox.appendChild(document.createElement('canvas'));
        setTimeout(() => {
          this.initCanvas();
        }, 200);
      }
      return {
        transform: `rotate(${this.degree}deg) translate(${length}px,${length}px)`,
        width: `${width}px`,
        height: `${height}px`,
        transformOrigin: 'center center',
      };
    },
  },
  • 操作
// 初始化画布
initCanvas() {
  let canvas = document.querySelector('#signcanvas');
  this.draw = new Draw(canvas, -this.degree,this.penColor);
},
// 清楚画布
clear() {
  this.draw.clear();
},
// 下载图片
download() {
   this.draw.downloadPNGImage(this.draw.getPNGImage());
},
// 上传图片
upload() {
  let image = this.draw.getPNGImage();
  let blob = this.draw.dataURLtoBlob(image);
  var url = '';
  let successCallback = (response) => {
    console.log(response);
  };
  let failureCallback = (error) => {
    console.log(error);
  };
  this.draw.upload(blob, url, successCallback, failureCallback);
},
// 检测canvas 非空
isCanvasBlank(canvas) {
  let emcan = document.querySelector('canvas');
  var blank = document.createElement('canvas');//系统获取一个空canvas对象
  blank.width = emcan.width;
  blank.height = emcan.height;
  return emcan.toDataURL() == blank.toDataURL();//比较值相等则为空
},
  • draw.js
/**
 * Created by louizhai on 17/6/30.
 * description: Use canvas to draw.
 */
function Draw(canvas, degree, color = 'black' ,config = {}) {
  if (!(this instanceof Draw)) {
    return new Draw(canvas, config);
  }
  if (!canvas) {
    return;
  }
  let { width, height } = window.getComputedStyle(canvas, null);
  width = width.replace('px', '');
  height = height.replace('px', '');

  this.canvas = canvas;
  this.context = canvas.getContext('2d');
  this.width = width;
  this.height = height;
  const context = this.context;

  // 根据设备像素比优化canvas绘图
  const devicePixelRatio = window.devicePixelRatio;
  if (devicePixelRatio) {
    canvas.style.width = `${width}px`;
    canvas.style.height = `${height}px`;
    canvas.height = height * devicePixelRatio;
    canvas.width = width * devicePixelRatio;
    context.scale(devicePixelRatio, devicePixelRatio);
  } else {
    canvas.width = width;
    canvas.height = height;
  }

  context.lineWidth = 6;
  context.strokeStyle = color;
  context.lineCap = 'round';
  context.lineJoin = 'round';
  Object.assign(context, config);

  const { left, top } = canvas.getBoundingClientRect();
  const point = {};
  const isMobile = /phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone/i.test(navigator.userAgent);
  // 移动端性能太弱, 去掉模糊以提高手写渲染速度
  if (!isMobile) {
    context.shadowBlur = 1;
    context.shadowColor = 'black';
  }
  let pressed = false;

  const paint = (signal) => {
    switch (signal) {
      case 1:
        context.beginPath();
        context.moveTo(point.x, point.y);
      case 2:
        context.lineTo(point.x, point.y);
        context.stroke();
        break;
      default:
    }
  };
  const create = signal => (e) => {
    e.preventDefault();
    if (signal === 1) {
      pressed = true;
    }
    if (signal === 1 || pressed) {
      e = isMobile ? e.touches[0] : e;
      point.x = e.clientX - left;
      point.y = e.clientY - top;
      paint(signal);
    }
  };
  const start = create(1);
  const move = create(2);
  const requestAnimationFrame = window.requestAnimationFrame;
  const optimizedMove = requestAnimationFrame ? (e) => {
    requestAnimationFrame(() => {
      move(e);
    });
  } : move;

  if (isMobile) {
    canvas.addEventListener('touchstart', start);
    canvas.addEventListener('touchmove', optimizedMove);
  } else {
    canvas.addEventListener('mousedown', start);
    canvas.addEventListener('mousemove', optimizedMove);
    ['mouseup', 'mouseleave'].forEach((event) => {
      canvas.addEventListener(event, () => {
        pressed = false;
      });
    });
  }

  // 重置画布坐标系
  if (typeof degree === 'number') {
    this.degree = degree;
    context.rotate((degree * Math.PI) / 180);
    switch (degree) {
      case -90:
        context.translate(-height, 0);
        break;
      case 90:
        context.translate(0, -width);
        break;
      case -180:
      case 180:
        context.translate(-width, -height);
        break;
      default:
    }
  }
}
Draw.prototype = {
  scale(width, height, canvas = this.canvas) {
    const w = canvas.width;
    const h = canvas.height;
    width = width || w;
    height = height || h;
    if (width !== w || height !== h) {
      const tmpCanvas = document.createElement('canvas');
      const tmpContext = tmpCanvas.getContext('2d');
      tmpCanvas.width = width;
      tmpCanvas.height = height;
      tmpContext.drawImage(canvas, 0, 0, w, h, 0, 0, width, height);
      canvas = tmpCanvas;
    }
    return canvas;
  },
  rotate(degree, image = this.canvas) {
    degree = ~~degree;
    if (degree !== 0) {
      const maxDegree = 180;
      const minDegree = -90;
      if (degree > maxDegree) {
        degree = maxDegree;
      } else if (degree < minDegree) {
        degree = minDegree;
      }

      const canvas = document.createElement('canvas');
      const context = canvas.getContext('2d');
      const height = image.height;
      const width = image.width;
      const degreePI = (degree * Math.PI) / 180;

      switch (degree) {
        // 逆时针旋转90°
        case -90:
          canvas.width = height;
          canvas.height = width;
          context.rotate(degreePI);
          context.drawImage(image, -width, 0);
          break;
        // 顺时针旋转90°
        case 90:
          canvas.width = height;
          canvas.height = width;
          context.rotate(degreePI);
          context.drawImage(image, 0, -height);
          break;
        // 顺时针旋转180°
        case 180:
          canvas.width = width;
          canvas.height = height;
          context.rotate(degreePI);
          context.drawImage(image, -width, -height);
          break;
        default:
      }
      image = canvas;
    }
    return image;
  },
  getPNGImage(canvas = this.canvas) {
    return canvas.toDataURL('image/png');
  },
  getJPGImage(canvas = this.canvas) {
    return canvas.toDataURL('image/jpeg', 0.5);
  },
  downloadPNGImage(image) {
    const url = image.replace('image/png', 'image/octet-stream;Content-Disposition:attachment;filename=test.png');
    window.location.href = url;
  },
  dataURLtoBlob(dataURL) {
    const arr = dataURL.split(',');
    const mime = arr[0].match(/:(.*?);/)[1];
    const bStr = atob(arr[1]);
    let n = bStr.length;
    const u8arr = new Uint8Array(n);
    while (n--) {
      u8arr[n] = bStr.charCodeAt(n);
    }
    return new Blob([u8arr], { type: mime });
  },
  clear() {
    let width;
    let height;
    switch (this.degree) {
      case -90:
      case 90:
        width = this.height;
        height = this.width;
        break;
      default:
        width = this.width;
        height = this.height;
    }
    this.context.clearRect(0, 0, width, height);
  },
  upload(blob, url, success, failure) {
    const formData = new FormData();
    const xhr = new XMLHttpRequest();
    xhr.withCredentials = true;
    formData.append('image', blob, 'sign');

    xhr.open('POST', url, true);
    xhr.onload = () => {
      if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
        success(xhr.responseText);
      } else {
        failure();
      }
    };
    xhr.onerror = (e) => {
      if (typeof failure === 'function') {
        failure(e);
      } else {
        console.log(`upload img error: ${e}`);
      }
    };
    xhr.send(formData);
  },
};
export default Draw;

**此插件为引用他人。忘记原文地址,知道的请联系我 **

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,662评论 1 32
  • 在前面一篇文章中,我们分析了Android应用程序窗口的绘图表面的创建过程。Android应用程序窗口的绘图表面在...
    一个不掉头发的开发阅读 5,013评论 0 14
  • 此方人家 文/尘一粒 有些人,有些事,永远会在无法预期的时刻浮现在脑海,一遍又一遍地呼唤…… 1 元月三号、四号,...
    尘一粒W阅读 712评论 0 4
  • 1、我怎么如此幸运,今天和高娃姐了那么好的一个沟通,让我又悟了很多东西 2、我怎么如此幸运,今天完成了和房东的信息...
    陈悦希阅读 220评论 0 0
  • 楼亭细雨, 听蝉鸣。 月上梢头, 牍倚暗江流。 花开花谢又一年。 誰堪今夕是何年? 难啊难, 烦又烦。 料想明朝春...
    北槐向暖阅读 523评论 0 7

友情链接更多精彩内容