canvas应用----刮刮乐

野性酷女 2022-01-26 11:17 467阅读 0赞

最近在学习html5,为了更好地学习和帮助其他人我决定把我写过的案例写下来~~

先说一下刮刮乐这个程序实现的注意点

  • 材料:一张图片和canvas画布
  • 在html页面只要放图片元素,canvas由js生成。 这是为了保证canvas生成在img上面而且保证刚打开页面的时候不会看见图片
  • 生成的canvas涂层要保证大小和位置和图片的相同

CSS

  1. *{padding:0;margin:0;}
  2. body{
  3. background-color: skyblue;
  4. text-align: center;
  5. }
  6. #img{
  7. margin-top: 100px;
  8. user-select: none;
  9. }
  10. canvas{
  11. user-select: none;
  12. }

html

  1. <img src = "img/1.jpg" alt="" id = "img">
  2. <input type = "text" id = "txt">

js

  1. let img = document.querySelector("#img")
  2. let txt = document.querySelector("#txt")
  3. // 保证图片和canvas生成顺序不会出错
  4. if( img.readyState === "complete" ){
  5. draw()
  6. } else{
  7. img.onload = draw
  8. }
  9. function draw() {
  10. // 生成canvas涂层
  11. let can = document.createElement("canvas")
  12. // 保证涂层宽高与画布宽高一致
  13. can.width = img.width
  14. can.height = img.height
  15. // 保证涂层位置与画布位置一致
  16. can.style.position = "absolute"
  17. can.style.left = img.offsetLeft + "px"
  18. can.style.top = img.offsetTop + "px"
  19. // 插入生成的canvas
  20. img.parentNode.insertBefore( can, img )
  21. // canvas样式
  22. let ctx = can.getContext("2d")
  23. ctx.fillStyle = "#bbb" // 涂层的颜色
  24. ctx.fillRect( 0, 0, img.width, img.height ) // 填充canvas涂层
  25. // 以上的样式可以先写在一个字符串中,然后只要用ctx.cssText就好了 但是这里为了更直观我就一步步写了
  26. // 合成 处理合成图片的透明样式
  27. // 拖拽的时候使canvas涂层透明
  28. ctx.globalCompositeOperation = "destination-out"
  29. // 画笔样式
  30. ctx.lineWidth = 30
  31. ctx.lineCap = "round"
  32. // 拖拽事件
  33. can.onmousedown = function (e) {
  34. let x = e.pageX - can.offsetLeft
  35. let y = e.pageY - can.offsetTop
  36. // 在涂层点一下的时候要有一个圆点
  37. ctx.beginPath()
  38. ctx.arc( x, y, 15, 0, 2*Math.PI, false )
  39. ctx.fill()
  40. can.onmousemove = function (e) {
  41. ctx.beginPath()
  42. ctx.moveTo( x, y )
  43. ctx.lineTo( e.pageX - can.offsetLeft, e.pageY - can.offsetTop )
  44. // 滚动过程中实时更新坐标
  45. x = e.pageX - can.offsetLeft
  46. y = e.pageY - can.offsetTop
  47. // 描线
  48. ctx.stroke() // 这里是描线,用fill会没有效果
  49. }
  50. document.onmouseup = function (e) {
  51. // 这里对document绑定事件是因为抬起鼠标的时候可能是在图片之外抬起
  52. can.onmousemove = null
  53. this.onmouseup = null
  54. check() // 这里增加一个功能,已涂面积超过30%的时候显示全部图片
  55. }
  56. }
  57. function check () {
  58. let data = ctx.getImageData( 0, 0, can.width, can.height ).data
  59. let n = 0 // 已经刮开的像素点
  60. for( let i = 0; i < data.length; i+=4 ){
  61. if( data[i] === 0 && data[i+1] === 0 && data[i+2] === 0 && data[i+3] === 0 ) {
  62. // 这里的data表示一个像素点的rgba 由于被刮过的像素点变透明,因此此时rgba都为0
  63. n++
  64. }
  65. }
  66. // 算出当前已刮面积占比
  67. let f = n * 100 / ( can.width * can.height )
  68. txt.value = `刮开面积:${f.toFixed(2)}%`
  69. // 如果超过30%则展示完整画面
  70. if( f > 30 ){
  71. ctx.beginPath()
  72. ctx.fillRect( 0, 0, can.width, can.height )
  73. txt.value = `给你看完整的图片吧~~`
  74. }
  75. }
  76. }

好了,要是有什么问题或者建议的话欢迎联系我~

Wish you godspeed!

发表评论

表情:
评论列表 (有 0 条评论,467人围观)

还没有评论,来说两句吧...

相关阅读

    相关 canvas应用----

    最近在学习html5,为了更好地学习和帮助其他人我决定把我写过的案例写下来~~ 先说一下刮刮乐这个程序实现的注意点 材料:一张图片和canvas画布 在html