Skip to content

签名画板案例


01. 绘制一个画板

js
// 1、获取canvas画布
var c1 = document.querySelector("#c1");
if (!c1.getContext) {
    console.log('当前浏览器不支持canvas,请下载最新的浏览器');
}
// 2. 获取画笔,上下文对象
var ctx = c1.getContext('2d')
// 连接点和末端为圆形
ctx.lineJoin = 'round';
ctx.lineCap = 'round'
// 3.获取输入框和按钮
var boldBtn = document.getElementById('boldBtn')
var thinBtn = document.getElementById('thinBtn')
var saveBtn = document.getElementById('saveBtn')
var color = document.getElementById('color')
var eraserBtn = document.getElementById('eraserBtn')
var clearBtn = document.getElementById('clearBtn')
// 是否在画
var isDraw = false

c1.onmousedown = (e) => {
    isDraw = true
    ctx.beginPath();
    var x = e.offsetX;
    var y = e.offsetY;
    ctx.moveTo(x, y);

}
function mouseEvent(e) {
    if (isDraw) {
        var x = e.offsetX;
        var y = e.offsetY;
        ctx.lineTo(x, y)
        ctx.stroke()
    }
}
c1.onmousemove = (e) => {
    mouseEvent(e)
}
c1.onmouseup = () => {
    isDraw = false
    ctx.closePath()
}
c1.onmouseleave = () => {
    isDraw = false
    ctx.closePath()
}
boldBtn.addEventListener('click', () => {
    ctx.globalCompositeOperation = 'source-over'
    ctx.lineWidth = 20
    boldBtn.classList.add('active')
    thinBtn.classList.remove('active')
    eraserBtn.classList.remove('active')
})
thinBtn.addEventListener('click', () => {
    ctx.globalCompositeOperation = 'source-over'
    ctx.lineWidth = 1
    boldBtn.classList.remove('active')
    eraserBtn.classList.remove('active')
    thinBtn.classList.add('active')
})
eraserBtn.addEventListener('click', () => {
    // 修改模式
    ctx.globalCompositeOperation = 'destination-out'
    ctx.lineWidth = 30
    boldBtn.classList.remove('active')
    thinBtn.classList.remove('active')
    eraserBtn.classList.add('active')
})
clearBtn.addEventListener('click', () => {
    ctx.clearRect(0, 0, c1.width, c1.height)
})
function setWhiteBackground() {
    // 获取图片数据
    var imgData = ctx.getImageData(
        0,
        0,
        c1.width,
        c1.height
    );
    for (var i = 0; i < imgData.data.length; i += 4) {
        // 当该像素是透明的,则设置成白色
        if (imgData.data[i + 3] == 0) {
            imgData.data[i] = 255;
            imgData.data[i + 1] = 255;
            imgData.data[i + 2] = 255;
            imgData.data[i + 3] = 255;
        }
    }
    ctx.putImageData(imgData, 0, 0);
}
saveBtn.addEventListener('click', () => {
    setWhiteBackground()
    var dataUrl = c1.toDataURL()
    const elem = window.document.createElement('a')
    elem.href = dataUrl
    elem.download = '签名.png'
    elem.click()
})
colorInput.addEventListener('change', () => {
    ctx.strokeStyle = colorInput.value
})
当前浏览器不支持canvas,请下载最新的浏览器 立即下载
<template>
  <div>
    <!-- id,标识元素的唯一性,width,height 画布的宽高 -->
    <canvas id="canvas" width="600" height="400">
      当前浏览器不支持canvas,请下载最新的浏览器
      <a href="https://www.google.cn/chrome/index.html">立即下载</a>
    </canvas>
    <hr />
    <n-space>
      <button id="boldBtn" type="button">粗线条</button>
      <button id="thinBtn" type="button">细线条</button>
      <button id="saveBtn" type="button">保存签名</button>
      <input type="color" name="" id="colorInput" />
      <button id="eraserBtn" type="button">橡皮擦</button>
      <button id="clearBtn" type="button">清除画布</button>
    </n-space>
  </div>
</template>

<script setup>
import { onMounted } from "vue";
onMounted(() => {
  // 1、获取canvas画布
  var c1 = document.querySelector("#canvas");
  if (!c1.getContext) {
    console.log("当前浏览器不支持canvas,请下载最新的浏览器");
  }
  // 2. 获取画笔,上下文对象
  var ctx = c1.getContext("2d");
  // 连接点和末端为圆形
  ctx.lineJoin = "round";
  ctx.lineCap = "round";
  // 3.获取输入框和按钮
  var boldBtn = document.getElementById("boldBtn");
  var thinBtn = document.getElementById("thinBtn");
  var saveBtn = document.getElementById("saveBtn");
  var color = document.getElementById("color");
  var eraserBtn = document.getElementById("eraserBtn");
  var clearBtn = document.getElementById("clearBtn");
  // 是否在画
  var isDraw = false;

  c1.onmousedown = (e) => {
    isDraw = true;
    ctx.beginPath();
    var x = e.offsetX;
    var y = e.offsetY;
    ctx.moveTo(x, y);
  };
  function mouseEvent(e) {
    if (isDraw) {
      var x = e.offsetX;
      var y = e.offsetY;
      ctx.lineTo(x, y);
      ctx.stroke();
    }
  }
  c1.onmousemove = (e) => {
    mouseEvent(e);
  };
  c1.onmouseup = () => {
    isDraw = false;
    ctx.closePath();
  };
  c1.onmouseleave = () => {
    isDraw = false;
    ctx.closePath();
  };
  boldBtn.addEventListener("click", () => {
    ctx.globalCompositeOperation = "source-over";
    ctx.lineWidth = 20;
    boldBtn.classList.add("active");
    thinBtn.classList.remove("active");
    eraserBtn.classList.remove("active");
  });
  thinBtn.addEventListener("click", () => {
    ctx.globalCompositeOperation = "source-over";
    ctx.lineWidth = 1;
    boldBtn.classList.remove("active");
    eraserBtn.classList.remove("active");
    thinBtn.classList.add("active");
  });
  eraserBtn.addEventListener("click", () => {
    // 修改模式
    ctx.globalCompositeOperation = "destination-out";
    ctx.lineWidth = 30;
    boldBtn.classList.remove("active");
    thinBtn.classList.remove("active");
    eraserBtn.classList.add("active");
  });
  clearBtn.addEventListener("click", () => {
    ctx.clearRect(0, 0, c1.width, c1.height);
  });
  function setWhiteBackground() {
    // 获取图片数据
    var imgData = ctx.getImageData(0, 0, c1.width, c1.height);
    for (var i = 0; i < imgData.data.length; i += 4) {
      // 当该像素是透明的,则设置成白色
      if (imgData.data[i + 3] == 0) {
        imgData.data[i] = 255;
        imgData.data[i + 1] = 255;
        imgData.data[i + 2] = 255;
        imgData.data[i + 3] = 255;
      }
    }
    ctx.putImageData(imgData, 0, 0);
  }
  saveBtn.addEventListener("click", () => {
    setWhiteBackground();
    var dataUrl = c1.toDataURL();
    const elem = window.document.createElement("a");
    elem.href = dataUrl;
    elem.download = "签名.png";
    elem.click();
  });
  colorInput.addEventListener("change", () => {
    ctx.strokeStyle = colorInput.value;
  });
});
</script>

<style scoped>
canvas,
input,
button {
  border: 1px solid #ccc;
}
button.active {
  color: #fff;
  background-color: orangered;
  border-color: orangered;
}
</style>