canvas签名

<!DOCTYPE html>
<html lang="zh-Hans">
  <link rel="stylesheet" href="./style.css">
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
  <title>我的画板</title>
  <canvas id="xxx" width=300 height=300></canvas>
  <div id=actions class="actions">
    <svg id=pen class="active icon">
      <use xlink:href="#icon-pen"></use>
    </svg>
    <svg id=eraser class="icon">
      <use xlink:href="#icon-erase"></use>
    </svg>
    <svg id=clear class="icon">
      <use xlink:href="#icon-clear"></use>
    </svg>
    <svg id=download class="icon">
      <use xlink:href="#icon-save"></use>
    </svg>
  </div>
  <ol class="colors">
    <li id="red" class="red active"></li>
    <li id="green" class="green"></li>
    <li id="blue" class="blue"></li>
  </ol>
  <ol class="sizes">
    <li id="thin" class="thin"></li>
    <li id="thick" class="thick"></li>
  </ol>
 
  <script src="./main.js"></script>
  <script src="other.js"></script>
 

</html>

style.css代码

ul,ol{list-style: none;}
*{margin:0;padding:0;}
.icon {
  width: 1em; height: 1em;
  vertical-align: -0.15em;
  fill: currentColor;
  overflow: hidden;
}
#xxx{
  display: block;
  background: white;
  position: fixed;
  top: 0;
  left: 0;
}

body{
  overflow: hidden;
}

.actions{
  position: fixed;
  top: 0;
  left: 0;
  padding: 20px;
}
.actions svg{
  width: 1.5em;
  height: 1.5em;
  transition: all 0.3s;
  margin: 0 10px;
}
.actions svg.active{
  fill: red;
  transform: scale(1.2);
}
.colors{
  position: fixed;
  top: 60px;
  left: 28px;
}
.colors> li{
  width: 20px;
  height: 20px;
  border-radius: 50%;
  box-shadow: 0 0 3px rgba(0,0,0,0.25);
  margin: 10px 0;
  transition: all 0.3s;
}
.colors> li.red{
  background: red;
}
.colors> li.green{
  background: green;
}
.colors> li.blue{
  background: blue;
}
.colors> li.active{
  box-shadow: 0 0 3px rgba(0,0,0,0.95);
  transform: scale(1.2);
}
.sizes {
  position: fixed;
  right: 20px;
  top: 10px;
}
.sizes > li {
  margin: 20px 0;
}
.sizes > .thin{
  height: 0;
  width: 20px;
  border-top: 3px solid black;
}
.sizes > .thick{
  height: 0;
  width: 20px;
  border-top: 6px solid black;
}

other.js代码

(function(window){var svgSprite='<svg><symbol id="icon-clear" viewBox="0 0 1024 1024"><path d="M902.095238 141.409524 633.904762 141.409524 633.904762 90.209524C633.904762 53.638095 609.52381 24.380952 577.828571 24.380952l-129.219048 0C414.47619 24.380952 390.095238 53.638095 390.095238 90.209524l0 51.2L121.904762 141.409524c-14.628571 0-24.380952 9.752381-24.380952 24.380952s9.752381 24.380952 24.380952 24.380952l24.380952 0L146.285714 877.714286c0 68.266667 53.638095 121.904762 121.904762 121.904762l487.619048 0c68.266667 0 121.904762-53.638095 121.904762-121.904762L877.714286 190.171429l24.380952 0c14.628571 0 24.380952-9.752381 24.380952-24.380952S916.72381 141.409524 902.095238 141.409524zM438.857143 90.209524C438.857143 80.457143 443.733333 73.142857 446.171429 73.142857l129.219048 0C580.266667 73.142857 585.142857 80.457143 585.142857 90.209524l0 51.2-146.285714 0L438.857143 90.209524zM828.952381 877.714286c0 41.447619-31.695238 73.142857-73.142857 73.142857L268.190476 950.857143c-41.447619 0-73.142857-31.695238-73.142857-73.142857L195.047619 190.171429l633.904762 0L828.952381 877.714286z"  ></path><path d="M512 853.333333c14.628571 0 24.380952-9.752381 24.380952-24.380952L536.380952 431.542857c0-14.628571-9.752381-24.380952-24.380952-24.380952s-24.380952 9.752381-24.380952 24.380952L487.619048 828.952381C487.619048 841.142857 497.371429 853.333333 512 853.333333z"  ></path><path d="M668.038095 853.333333c14.628571 0 24.380952-9.752381 24.380952-24.380952L692.419048 497.371429c0-14.628571-9.752381-24.380952-24.380952-24.380952s-24.380952 9.752381-24.380952 24.380952L643.657143 828.952381C643.657143 841.142857 653.409524 853.333333 668.038095 853.333333z"  ></path><path d="M355.961905 853.333333c14.628571 0 24.380952-9.752381 24.380952-24.380952L380.342857 497.371429c0-14.628571-9.752381-24.380952-24.380952-24.380952s-24.380952 9.752381-24.380952 24.380952L331.580952 828.952381C331.580952 841.142857 343.771429 853.333333 355.961905 853.333333z"  ></path></symbol><symbol id="icon-pen" viewBox="0 0 1024 1024"><path d="M241.53404 893.694472l-111.148643-111.097445 36.45225-132.753768 18.738094-18.686897 207.398964 207.398963-18.686898 18.738095-132.753767 36.401052z m-153.23256 42.03272l27.748763-101.114034L189.466712 907.978429l-101.114035 27.748763zM737.274391 79.406515l207.398964 207.45016L426.150347 805.328486 218.751384 597.980719 737.274391 79.355318zM444.837245 890.417865l33.175642-33.175642L1006.980078 328.326229a58.671738 58.671738 0 0 0 0-82.939107L778.743944 17.150988a58.671738 58.671738 0 0 0-82.939106 0L166.888844 546.066982l-33.175643 33.22684-24.420959 24.369762a58.46695 58.46695 0 0 0-15.922261 29.643051L1.317812 977.043154c-3.583789 13.311215 0.614364 26.827217 9.829821 35.786689 8.959471 9.215456 22.526671 13.413609 35.786688 9.82982l344.606868-92.052169a59.849269 59.849269 0 0 0 11.109745-3.583788c6.450819-2.867031 12.492063-6.911592 17.816549-12.236078l24.369762-24.369763z"  ></path></symbol><symbol id="icon-save" viewBox="0 0 1024 1024"><path d="M896 661.333333v128c0 58.88-53.973333 106.666667-120.106667 106.666667H248.106667C181.973333 896 128 848.213333 128 789.333333v-128H85.333333v128c0 82.346667 72.96 149.333333 162.773334 149.333334h527.786666c89.813333 0 162.773333-66.986667 162.773334-149.333334v-128h-42.666667z" fill="" ></path><path d="M740.48 463.146667l-30.293333-30.293334-176.853334 177.066667V85.333333h-42.666666v524.586667l-176.853334-177.066667-30.293333 30.293334L512 691.413333l228.48-228.266666z" fill="" ></path></symbol><symbol id="icon-erase" viewBox="0 0 1024 1024"><path d="M542 832.1l457.034-457.2c33.234-33.316 33.234-87.244 0-120.558L769.65 24.966c-33.288-33.288-87.262-33.288-120.55 0L192.074 482.158l-0.018 0.01-167.09 166.932c-33.234 33.316-33.234 87.244 0 120.558l229.384 229.374a84.43 84.43 0 0 0 46.148 23.588 17.012 17.012 0 0 0 6.702 1.38h549.718c9.426 0 17.066-7.64 17.066-17.066s-7.64-17.066-17.066-17.066H384.086l34.168-34.134H768c9.426 0 17.066-7.64 17.066-17.066s-7.64-17.066-17.066-17.066H452.418l34.168-34.134H768c9.426 0 17.066-7.64 17.066-17.066s-7.64-17.066-17.066-17.066H520.754l21.23-21.208 0.016-0.028z m-191.232 142.8c-20.23 19.3-52.054 19.3-72.284 0L49.1 745.526c-19.926-19.976-19.926-52.308 0-72.284l155.016-154.858 301.65 301.658-154.998 154.858z m-122.518-480.65L673.234 49.1c20.23-19.3 52.054-19.3 72.284 0L974.9 278.476c19.924 19.978 19.924 52.314 0 72.292l-444.984 445.14-301.666-301.658z"  ></path><path d="M728.866 90.334a17.064 17.064 0 0 0-24.132 24.132l204.8 204.8a17.064 17.064 0 0 0 24.132-24.132l-204.8-204.8z"  ></path></symbol></svg>';var script=function(){var scripts=document.getElementsByTagName("script");return scripts[scripts.length-1]}();var shouldInjectCss=script.getAttribute("data-injectcss");var ready=function(fn){if(document.addEventListener){if(~["complete","loaded","interactive"].indexOf(document.readyState)){setTimeout(fn,0)}else{var loadFn=function(){document.removeEventListener("DOMContentLoaded",loadFn,false);fn()};document.addEventListener("DOMContentLoaded",loadFn,false)}}else if(document.attachEvent){IEContentLoaded(window,fn)}function IEContentLoaded(w,fn){var d=w.document,done=false,init=function(){if(!done){done=true;fn()}};var polling=function(){try{d.documentElement.doScroll("left")}catch(e){setTimeout(polling,50);return}init()};polling();d.onreadystatechange=function(){if(d.readyState=="complete"){d.onreadystatechange=null;init()}}}};var before=function(el,target){target.parentNode.insertBefore(el,target)};var prepend=function(el,target){if(target.firstChild){before(el,target.firstChild)}else{target.appendChild(el)}};function appendSvg(){var div,svg;div=document.createElement("div");div.innerHTML=svgSprite;svgSprite=null;svg=div.getElementsByTagName("svg")[0];if(svg){svg.setAttribute("aria-hidden","true");svg.style.position="absolute";svg.style.width=0;svg.style.height=0;svg.style.overflow="hidden";prepend(svg,document.body)}}if(shouldInjectCss&&!window.__iconfont__svg__cssinject__){window.__iconfont__svg__cssinject__=true;try{document.write("<style>.svgfont {display: inline-block;width: 1em;height: 1em;fill: currentColor;vertical-align: -0.1em;font-size:16px;}</style>")}catch(e){console&&console.log(e)}}ready(appendSvg)})(window)


main.js代码

var yyy = document.getElementById('xxx');
var context = yyy.getContext('2d');
var lineWidth = 5

autoSetCanvasSize(yyy)

listenToUser(yyy)


var eraserEnabled = false
pen.onclick = function(){
  eraserEnabled = false
  pen.classList.add('active')
  eraser.classList.remove('active')
}
eraser.onclick = function(){
  eraserEnabled = true
  eraser.classList.add('active')
  pen.classList.remove('active')
}
clear.onclick = function(){
  context.clearRect(0, 0, yyy.width, yyy.height);
}
download.onclick = function(){
  var url = yyy.toDataURL("image/png")
  var a = document.createElement('a')
  document.body.appendChild(a)
  a.href = url
  a.download = '我的画儿'
  a.target = '_blank'
  a.click()
}


red.onclick = function(){
  context.fillStyle = 'red'
  context.strokeStyle = 'red'
  red.classList.add('active')
  green.classList.remove('active')
  blue.classList.remove('active')
}
green.onclick = function(){
  context.fillStyle = 'green'
  context.strokeStyle = 'green'
  red.classList.remove('active')
  green.classList.add('active')
  blue.classList.remove('active')
}
blue.onclick = function(){
  context.fillStyle = 'blue'
  context.strokeStyle = 'blue'
  red.classList.remove('active')
  green.classList.remove('active')
  blue.classList.add('active')
}

thin.onclick = function(){
  lineWidth = 5
}
thick.onclick = function(){
  lineWidth = 10
}

/******/

function autoSetCanvasSize(canvas) {
  setCanvasSize()

  window.onresize = function() {
    setCanvasSize()
  }

  function setCanvasSize() {
    var pageWidth = document.documentElement.clientWidth
    var pageHeight = document.documentElement.clientHeight

    canvas.width = pageWidth
    canvas.height = pageHeight
  }
}

function drawCircle(x, y, radius) {
  context.beginPath()
  context.arc(x, y, radius, 0, Math.PI * 2);
  context.fill()
}

function drawLine(x1, y1, x2, y2) {
  context.beginPath();
  context.moveTo(x1, y1) // 起点
  context.lineWidth = lineWidth
  context.lineTo(x2, y2) // 终点
  context.stroke()
  context.closePath()
}

function listenToUser(canvas) {


  var using = false
  var lastPoint = {
    x: undefined,
    y: undefined
  }
  // 特性检测
  if(document.body.ontouchstart !== undefined){
    // 触屏设备 苏菲就是个触屏设备啊哥
    canvas.ontouchstart = function(aaa){
      var x = aaa.touches[0].clientX
      var y = aaa.touches[0].clientY
      console.log(x,y)
      using = true
      if (eraserEnabled) {
        context.clearRect(x - 5, y - 5, 10, 10)
      } else {
        lastPoint = {
          "x": x,
          "y": y
        }
      }
    }
    canvas.ontouchmove = function(aaa){
      console.log('边摸边动')
      var x = aaa.touches[0].clientX
      var y = aaa.touches[0].clientY

      if (!using) {return}

      if (eraserEnabled) {
        context.clearRect(x - 5, y - 5, 10, 10)
      } else {
        var newPoint = {
          "x": x,
          "y": y
        }
        drawLine(lastPoint.x, lastPoint.y, newPoint.x, newPoint.y)
        lastPoint = newPoint
      }
    }
    canvas.ontouchend = function(){
      console.log('摸完了')
      using = false
    }
  }else{
    // 非触屏设备
    canvas.onmousedown = function(aaa) {
      var x = aaa.clientX
      var y = aaa.clientY
      using = true
      if (eraserEnabled) {
        context.clearRect(x - 5, y - 5, 10, 10)
      } else {
        lastPoint = {
          "x": x,
          "y": y
        }
      }
    }
    canvas.onmousemove = function(aaa) {
      var x = aaa.clientX
      var y = aaa.clientY

      if (!using) {return}

      if (eraserEnabled) {
        context.clearRect(x - 5, y - 5, 10, 10)
      } else {
        var newPoint = {
          "x": x,
          "y": y
        }
        drawLine(lastPoint.x, lastPoint.y, newPoint.x, newPoint.y)
        lastPoint = newPoint
      }

    }
    canvas.onmouseup = function(aaa) {
      using = false
    }
  }

}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值