效果如下



代码如下:

//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. 对于修改jsp页面后页面不发生变化的解决方法

    1.清除 Tomcat 6.0\work\Catalina\localhost 里面这个工程的内容:2.清除 Tomcat 6.0 webapps 里面的这个工程内容,然后重新部署,重启服务器:3.清 ...

  2. SQL Server2012中时间字段为DateTime和VarChar的区别

    在设计数据库的时候varchar类型是一个非常常见的类型,很多字段都可以使用这个类型,所以有时候在设计数据库的时候就很容易习惯性设计该类型,比如说时间类型,我们既可以DateTime类型,又可以使用v ...

  3. com.alibaba的fastjson简介

    fastjson简介 Fastjson是一个Java语言编写的高性能功能完善的JSON库.它采用一种“假定有序快速匹配”的算法,把JSON Parse的性能提升到极致,是目前Java语言中最快的JSO ...

  4. 检索 COM 类工厂中 CLSID 为 {91493441-5A91-11CF-8700-00AA0060263B} 的组件失败

    Symptoms When no user is interactively logged on to the server console, if you try to start a COM+ a ...

  5. codeforces158C

    Cd and pwd commands CodeForces - 158C Vasya is writing an operating system shell, and it should have ...

  6. Nginx 简单的cpu配置

    配置指定CPU Nginx建议进程数和CPU数量一致,这样每个CPU都有自己独立的缓存 worker_processes 4; worker_cpu_affinity 1000 0100 0010 0 ...

  7. Civil 3D CustomDraw .NET混合项目设置

    样例文件中的CustomDraw项目使用的是COM API,但COM API不完整,某些时候需要使用.NET API,此时需要将C++项目设置成"公共语言运行时支持(/clr)"但 ...

  8. Nginx+Tomcat 负载均衡集群

    案例分析 通常情况下,一台Tomcat站点由于可能出现单点故障及无法应对多客户复杂多样性的请求等问题,不能单独应用于生产环境下,所以我们需要一套更可靠的解决方案来完善Web站点架构. Nginx是一款 ...

  9. Codeforces Round #475 Div. 1

    B:当n是偶数时无解,因为此时树中有奇数条边,而我们每次都只能删除偶数条.当n是奇数时一定有解,因为此时不可能所有点度数都为奇数,只要找到一个度数为偶数的点,满足将它删掉后,各连通块大小都为奇数就可以 ...

  10. 基准对象object中的基础类型----数字 (二)

    object有如下子类: CLASSES object basestring str unicode buffer bytearray classmethod complex dict enumera ...