效果如下



代码如下:

//index.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>触摸事件</title>
<link href="style.css" rel="stylesheet" type="text/css" />
<script src="main.js" defer></script>
</head>
<body>
<canvas id="canvas">
当前浏览器不支持 canvas 元素
</canvas>
<br>记录:
<pre id="log"></pre>
</body>
</html>
//main.js
const ongoingTouches = [];
const el = document.getElementById("canvas");
const ctx = el.getContext("2d"); window.onload = () => {
el.width = 600;
el.height = 600;
el.addEventListener("touchstart", handleStart, false);
el.addEventListener("touchend", handleEnd, false);
el.addEventListener("touchcancel", handleCancel, false);
el.addEventListener("touchmove", handleMove, false);
log("初始化成功。");
}; function handleStart(evt) {
evt.preventDefault();
log("触摸开始。");
const touches = evt.changedTouches; for (let i = 0; i < touches.length; i++) {
log("开始第 " + i + " 个触摸 ...");
ongoingTouches.push(copyTouch(touches[i]));
ctx.beginPath();
ctx.fillStyle = colorForTouch(touches[i]);
ctx.arc(touches[i].pageX, touches[i].pageY, 4, 0, 2 * Math.PI, false);
// 在起点画一个圆
ctx.fill();
log("第 " + i + " 个触摸已开始。");
}
} function handleMove(evt) {
evt.preventDefault();
const touches = evt.changedTouches;
for (let i = 0; i < touches.length; i++) {
const color = colorForTouch(touches[i]);
const idx = ongoingTouchIndexById(touches[i].identifier);
if (idx >= 0) {
log("继续第 " + idx + " 个触摸。");
ctx.beginPath();
log("ctx.moveTo(" + ongoingTouches[idx].pageX + ", " +
ongoingTouches[idx].pageY + ");");
ctx.moveTo(ongoingTouches[idx].pageX, ongoingTouches[idx].pageY);
ctx.lineWidth = 4;
ctx.fillStyle = color;
log("ctx.lineTo(" + touches[i].pageX + ", " + touches[i].pageY + ");");
ctx.lineTo(touches[i].pageX, touches[i].pageY);
ctx.strokeStyle = color;
ctx.stroke();
ongoingTouches.splice(idx, 1, copyTouch(touches[i])); // 切换到新触摸
log(".");
} else {
log("无法确定下一个触摸点。");
}
}
} function handleEnd(evt) {
evt.preventDefault();
log("触摸结束。");
const touches = evt.changedTouches;
for (let i = 0; i < touches.length; i++) {
const color = colorForTouch(touches[i]);
const idx = ongoingTouchIndexById(touches[i].identifier);
if (idx >= 0) {
ctx.lineWidth = 4;
ctx.fillStyle = color;
ctx.beginPath();
ctx.moveTo(ongoingTouches[idx].pageX, ongoingTouches[idx].pageY);
ctx.lineTo(touches[i].pageX, touches[i].pageY);
ctx.fillRect(touches[i].pageX - 4, touches[i].pageY - 4, 8, 8);
// 在终点画一个正方形
ongoingTouches.splice(idx, 1); // 用完后移除
} else {
log("无法确定下一个触摸点。");
}
}
} function handleCancel(evt) {
evt.preventDefault();
log("触摸取消。");
const touches = evt.changedTouches; for (let i = 0; i < touches.length; i++) {
const idx = ongoingTouchIndexById(touches[i].identifier);
ongoingTouches.splice(idx, 1); // 用完后删除
}
} // 以下是便捷函数 function colorForTouch(touch) {
const r = (touch.identifier % 16).toString(16);
const g = (Math.floor(touch.identifier / 3) % 16).toString(16);
const b = (Math.floor(touch.identifier / 7) % 16).toString(16);
const color = "#" + r + g + b;
log("identifier " + touch.identifier + " 的颜色为:" + color);
return color;
} function copyTouch(touch) {
return {
identifier: touch.identifier,
pageX: touch.pageX,
pageY: touch.pageY
};
} function ongoingTouchIndexById(idToFind) {
for (let i = 0; i < ongoingTouches.length; i++) {
const id = ongoingTouches[i].identifier; if (id == idToFind) {
return i;
}
}
return -1; // 未找到
} function log(msg) {
const p = document.getElementById('log');
p.innerHTML =
new Date().toString().substring(16, 24) + ' ' + msg + "\n" + p.innerHTML;
}
//style.css
body {
padding: 0;
margin: 10px
} svg:not(:root) {
display: block
} .playable-code {
background-color: #f4f7f8;
border: none;
border-left: 6px solid #558abb;
border-width: medium medium medium 6px;
color: #4d4e53;
height: 100px;
width: 90%;
padding: 10px 10px 0
} .playable-canvas {
border: 1px solid #4d4e53;
border-radius: 2px
} .playable-buttons {
text-align: right;
width: 90%;
padding: 5px 10px 5px 26px
} #canvas {
border: 1px solid #000;
} #log {
border: 1px solid #ccc;
}

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. Swagger2常用注解及其说明 (转)

    Api 用在Controller中,标记一个Controller作为swagger的文档资源 属性名称 说明 value Controller的注解 description 对api资源的描述 hid ...

  2. 如何使用apache自带的ab压力测试工具

    ab是apache自带的一个很好用的压力测试工具,当安装完apache的时候,就可以在bin下面找到ab 1 我们可以模拟100个并发用户,对一个页面发送1000个请求 ./ab -n1000 -c1 ...

  3. Centos6.8 安装git

    1.下载安装包 wget https://mirrors.edge.kernel.org/pub/software/scm/git/git-2.8.0.tar.gz 2.安装依赖 sudo yum - ...

  4. awk骚操作

    一.awk自加 [root@168web3 ~]# head /data/logs/cloud_monitor_rds_cpu.log |awk '{sum+=$NF}END{print sum}' ...

  5. Java对象clone()的测试

    Object中自带native clone()方法. 研究了一下用法. public class DeepCopyTest { public static void main(String[] arg ...

  6. 导出数据到EXL表格中

    项目使用的是SSI框架,通过struts访问到action xml文件: <action name="fabAttributedaochu" class="com. ...

  7. C# 23种设计模式汇总

    创建型模式工厂方法(Factory Method)在工厂方法模式中,工厂方法用来创建客户所需要的产品,同时还向客户隐藏了哪种具体产品类将被实例化这一细节.工厂方法模式的核心是一个抽象工厂类,各种具体工 ...

  8. 【CPU】理解CPU

    CPU,全称Central Processing Unit,即中央处理器. 何为CPU? 计算机必须能够自动地从主存中取出一条条指令执行,专门来执行指令的就是CPU. 一.指令的执行过程 为了理解CP ...

  9. MySQL中表复制:create table like 与 create table as select

    CREATE TABLE A LIKE B 此种方式在将表B复制到A时候会将表B完整的字段结构和索引复制到表A中来. CREATE TABLE A AS SELECT x,x,x,xx FROM B ...

  10. day5 笔记

    笔记 字符格式化输出: 占位符%s s=string 字符型%d d=dight 整数型%f f=float 浮点数 约等于小数 通过格式:%(str1,str2,str3)一一对应 数据运算 数据类 ...