效果如下



代码如下:

  1. //index.html
  2. <!DOCTYPE html>
  3. <html lang="zh-CN">
  4. <head>
  5. <meta charset="utf-8">
  6. <title>触摸事件</title>
  7. <link href="style.css" rel="stylesheet" type="text/css" />
  8. <script src="main.js" defer></script>
  9. </head>
  10. <body>
  11. <canvas id="canvas">
  12. 当前浏览器不支持 canvas 元素
  13. </canvas>
  14. <br>记录:
  15. <pre id="log"></pre>
  16. </body>
  17. </html>
  1. //main.js
  2. const ongoingTouches = [];
  3. const el = document.getElementById("canvas");
  4. const ctx = el.getContext("2d");
  5. window.onload = () => {
  6. el.width = 600;
  7. el.height = 600;
  8. el.addEventListener("touchstart", handleStart, false);
  9. el.addEventListener("touchend", handleEnd, false);
  10. el.addEventListener("touchcancel", handleCancel, false);
  11. el.addEventListener("touchmove", handleMove, false);
  12. log("初始化成功。");
  13. };
  14. function handleStart(evt) {
  15. evt.preventDefault();
  16. log("触摸开始。");
  17. const touches = evt.changedTouches;
  18. for (let i = 0; i < touches.length; i++) {
  19. log("开始第 " + i + " 个触摸 ...");
  20. ongoingTouches.push(copyTouch(touches[i]));
  21. ctx.beginPath();
  22. ctx.fillStyle = colorForTouch(touches[i]);
  23. ctx.arc(touches[i].pageX, touches[i].pageY, 4, 0, 2 * Math.PI, false);
  24. // 在起点画一个圆
  25. ctx.fill();
  26. log("第 " + i + " 个触摸已开始。");
  27. }
  28. }
  29. function handleMove(evt) {
  30. evt.preventDefault();
  31. const touches = evt.changedTouches;
  32. for (let i = 0; i < touches.length; i++) {
  33. const color = colorForTouch(touches[i]);
  34. const idx = ongoingTouchIndexById(touches[i].identifier);
  35. if (idx >= 0) {
  36. log("继续第 " + idx + " 个触摸。");
  37. ctx.beginPath();
  38. log("ctx.moveTo(" + ongoingTouches[idx].pageX + ", " +
  39. ongoingTouches[idx].pageY + ");");
  40. ctx.moveTo(ongoingTouches[idx].pageX, ongoingTouches[idx].pageY);
  41. ctx.lineWidth = 4;
  42. ctx.fillStyle = color;
  43. log("ctx.lineTo(" + touches[i].pageX + ", " + touches[i].pageY + ");");
  44. ctx.lineTo(touches[i].pageX, touches[i].pageY);
  45. ctx.strokeStyle = color;
  46. ctx.stroke();
  47. ongoingTouches.splice(idx, 1, copyTouch(touches[i])); // 切换到新触摸
  48. log(".");
  49. } else {
  50. log("无法确定下一个触摸点。");
  51. }
  52. }
  53. }
  54. function handleEnd(evt) {
  55. evt.preventDefault();
  56. log("触摸结束。");
  57. const touches = evt.changedTouches;
  58. for (let i = 0; i < touches.length; i++) {
  59. const color = colorForTouch(touches[i]);
  60. const idx = ongoingTouchIndexById(touches[i].identifier);
  61. if (idx >= 0) {
  62. ctx.lineWidth = 4;
  63. ctx.fillStyle = color;
  64. ctx.beginPath();
  65. ctx.moveTo(ongoingTouches[idx].pageX, ongoingTouches[idx].pageY);
  66. ctx.lineTo(touches[i].pageX, touches[i].pageY);
  67. ctx.fillRect(touches[i].pageX - 4, touches[i].pageY - 4, 8, 8);
  68. // 在终点画一个正方形
  69. ongoingTouches.splice(idx, 1); // 用完后移除
  70. } else {
  71. log("无法确定下一个触摸点。");
  72. }
  73. }
  74. }
  75. function handleCancel(evt) {
  76. evt.preventDefault();
  77. log("触摸取消。");
  78. const touches = evt.changedTouches;
  79. for (let i = 0; i < touches.length; i++) {
  80. const idx = ongoingTouchIndexById(touches[i].identifier);
  81. ongoingTouches.splice(idx, 1); // 用完后删除
  82. }
  83. }
  84. // 以下是便捷函数
  85. function colorForTouch(touch) {
  86. const r = (touch.identifier % 16).toString(16);
  87. const g = (Math.floor(touch.identifier / 3) % 16).toString(16);
  88. const b = (Math.floor(touch.identifier / 7) % 16).toString(16);
  89. const color = "#" + r + g + b;
  90. log("identifier " + touch.identifier + " 的颜色为:" + color);
  91. return color;
  92. }
  93. function copyTouch(touch) {
  94. return {
  95. identifier: touch.identifier,
  96. pageX: touch.pageX,
  97. pageY: touch.pageY
  98. };
  99. }
  100. function ongoingTouchIndexById(idToFind) {
  101. for (let i = 0; i < ongoingTouches.length; i++) {
  102. const id = ongoingTouches[i].identifier;
  103. if (id == idToFind) {
  104. return i;
  105. }
  106. }
  107. return -1; // 未找到
  108. }
  109. function log(msg) {
  110. const p = document.getElementById('log');
  111. p.innerHTML =
  112. new Date().toString().substring(16, 24) + ' ' + msg + "\n" + p.innerHTML;
  113. }
  1. //style.css
  2. body {
  3. padding: 0;
  4. margin: 10px
  5. }
  6. svg:not(:root) {
  7. display: block
  8. }
  9. .playable-code {
  10. background-color: #f4f7f8;
  11. border: none;
  12. border-left: 6px solid #558abb;
  13. border-width: medium medium medium 6px;
  14. color: #4d4e53;
  15. height: 100px;
  16. width: 90%;
  17. padding: 10px 10px 0
  18. }
  19. .playable-canvas {
  20. border: 1px solid #4d4e53;
  21. border-radius: 2px
  22. }
  23. .playable-buttons {
  24. text-align: right;
  25. width: 90%;
  26. padding: 5px 10px 5px 26px
  27. }
  28. #canvas {
  29. border: 1px solid #000;
  30. }
  31. #log {
  32. border: 1px solid #ccc;
  33. }

touch-paint的更多相关文章

  1. 【appium】根据accessibility_id定位元素

    如何获得AccessibilityId 可以通过UIAutomatorViewer或者Appium Inspector获得.Accessibility ID在Android上面就等同于contentD ...

  2. android中自定义view---实现竖直方向的文字功能,文字方向朝上,同时提供接口,判断当前touch的是哪个字符,并改变颜色

    android自定义view,实现竖直方向的文字功能,文字方向朝上,同时提供接口,判断当前touch的是哪个字符,并改变颜色. 由于时间比较仓促,因此没有对代码进行过多的优化,功能远远不如androi ...

  3. Android事件处理第一节(View对Touch事件的处理)

    http://ipjmc.iteye.com/blog/1694146 在Android里Touch是很常用的事件,尤其实在自定义控件中,要实现一些动态的效果,往往要对Touch进行处理.Androi ...

  4. Android Touch事件之一:Touch事件在父ViewGroup和子View之间的传递篇

    2015-11-26 17:00:22 前言:Android的Touch事件传递和View的实现紧密相连,因此理解Touch事件的传递,有助于我们更好的理解View的工作原理. 1. 几个重要的方法: ...

  5. Xamarin.Forms实现touch事件

    Xamarin.Forms的View没有touch事件,只能自己实现 首先,在共享项目里面,放入这几个类,结构大概是这样的: using System; using Xamarin.Forms; na ...

  6. 详解Paint的setXfermode(Xfermode xfermode)

    一.setXfermode(Xfermode xfermode) Xfermode国外有大神称之为过渡模式,这种翻译比较贴切但恐怕不易理解,大家也可以直接称之为图像混合模式,因为所谓的“过渡”其实就是 ...

  7. android Canvas 和 Paint用法

    自定义view里面的onDraw方法,在这里我们可以绘制各种图形,onDraw里面有两个API我们需要了解清楚他们的用法:Canvas 和 Paint. Canvas翻译成中文就是画布的意思,Canv ...

  8. mkdir,rmdir,cp,rm,mv,cat,touch用法

    一.mkdir新建目录 1.进入tmp目录,查看该目录下面的子目录 [root@localhost ~]# cd /tmp[root@localhost tmp]# lshsperfdata_root ...

  9. UC浏览器中touch事件的异常记录

    以前也在UC上面栽过几个坑,不过都是页面显示方面的.上个周的时候,商品详情页重做,要添加个上拉显示详情的效果. 有两个条件需要判断: 1.是否到达底部: 2.到达底部之后拖动的y轴距离. 效果写完后, ...

  10. 移动端web开发,click touch tap区别

    转自: http://blog.csdn.net/sly94/article/details/51701188 移动端用tap时会有穿透问题 一:click与tap比较 click与tap都会触发点击 ...

随机推荐

  1. hive表链接

    等值连接 不等职链接 外部链接 没有包含在聚合函数(这里是count)中的列,都需要包含在group by函数中: 正确的外链接的写法,用的是右外链接: 自链接表 把同一张表 看成了2张表

  2. HTML5 & tel & make a phone call

    HTML5 & tel & make a phone call 咋呼叫呀,网页怎么打电话? { key: "exploreCorpPhone", title: &q ...

  3. edge

    https://www.cnblogs.com/st-leslie/p/6784990.html

  4. Java多线程之单例模式(线程安全)

    package org.study2.javabase.ThreadsDemo.sync; /** * @Auther:GongXingRui * @Date:2018/9/20 * @Descrip ...

  5. 创建一个UWP 打包签名

    Create a certificate for package signing 2017/2/8 3 min to read [ Updated for UWP apps on Windows 10 ...

  6. mybatis,主键返回指的是返回到传入的对象中

  7. Neutron 网络基本概念

    Neutron 网络基本概念 上次我们讨论了 Neutron 提供的功能,今天我们学习 Neutron 模块几个重要的概念. Neutron 管理的网络资源包括 Network,subnet 和 po ...

  8. linux系统命令大全

    文件管理 cat chattr chgrp chmod chown cksum cmp cp cut diff diffstat file find git gitview in indent les ...

  9. 【XSY1515】【GDKOI2016】小学生数学题 组合数学

    题目描述 给你\(n,k,p\)(\(p\)为质数),求 \[ \sum_{i=1}^n\frac{1}{i}\mod p^k \] 保证有解. \(p\leq {10}^5,np^k\leq {10 ...

  10. IDEA如何查看maven的依赖结构

    打开方式: 方法一:该工具有个Maven Projects窗口,一般在右侧能够找到,如果没有可以从菜单栏打开:View>Tool Windows>Maven Projects:选择要分析的 ...