文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Vue怎么实现多点涂鸦效果

2023-07-05 17:41

关注

这篇文章主要介绍“Vue怎么实现多点涂鸦效果”,在日常操作中,相信很多人在Vue怎么实现多点涂鸦效果问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Vue怎么实现多点涂鸦效果”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

创建画布

创建画布并设置事件处理器

 <canvas    ref="board"        width="1000"    height="1000"    @touchstart="handleStart"    @touchmove="handleMove"    @touchend="handleEnd"  />

获取画布并初始化画笔信息

onMounted(() => {  initPointer();});const board = ref();const cxt = ref();const lineWidth = 4;const initPointer = () => {  cxt.value = board.value.getContext('2d');  window.MeApi?.mainWindowLoaded();  cxt.value.strokeStyle = 'red';  cxt.value.fillStyle = 'red';  cxt.value.lineWidth = lineWidth;};

触摸事件处理

基础知识

Touch.identifier

唯一地识别和触摸平面接触的点的值。

这个值在这根手指(或触摸笔等)所引发的所有事件中保持一致,直到它离开触摸平面。

TouchEvent.changedTouches

该属性返回一个TouchList:

拷贝触摸点

浏览器会复用触摸点,通过拷贝只记录差异点和唯一标识符替换引用整个对象的方式进行优化

type Point = {  identifier: number,//触摸点什么标识  //触摸点坐标  x: number,  y: number};const copyTouch = (touch: Touch) => {  return {    identifier: touch.identifier,    x: touch.pageX,    y: touch.pageY  };};

查找触摸点

通过遍历 activityTouches 数组来寻找与给定标记相匹配的触摸点,返回该触摸点在数组中的下标。

const activityTouchIndexById = (idToFind: number) => {  for (let i = 0; i < activityTouches.length; i++) {    const id = activityTouches[i].identifier;    if (id === idToFind) {      return i;    }  }  return -1;};

跟踪所有触摸点以实现多点触控

//跟踪当前存在的所有触摸点const activityTouches: Point[] = [];

新增触摸事件

当屏幕上出现新的触摸点touchstart事件被触发,handleStart 函数被触发。此时,要收集记录触摸点并在触摸点处画圆:

const handleStart = (evt: TouchEvent) => {  //获取所有新增的点  const touches = evt.changedTouches;  for (let i = 0; i < touches.length; i++) {    //收集触摸点    activityTouches.push(copyTouch(touches[i]));    //画圆    cxt.value.beginPath();    drawCircle(touches[i].clientX, touches[i].clientY)  }};

触摸移动时

touchmove 事件被触发时,从而将调用handleMove() 函数,此时按照路径绘制线:

const handleMove = (evt: TouchEvent) => {  evt.preventDefault();  const touches = evt.changedTouches;  for (let i = 0; i < touches.length; i++) {    const indexById = activityTouchIndexById(touches[i].identifier);    if (indexById >= 0) {      cxt.value.beginPath();      cxt.value.moveTo(activityTouches[indexById].x, activityTouches[indexById].y);      cxt.value.lineTo(touches[i].clientX, touches[i].pageY);      cxt.value.stroke();      //更新缓存信息      activityTouches.splice(indexById, 1, copyTouch(touches[i]));    }  }};

首先遍历所有发生移动的触摸点。通过读取每个触摸点的 Touch.identifier 属性,从缓存中读取每个触摸点在变化前的起点。这样取得每个触摸点之前位置的坐标,进而进行绘制。

触摸结束处理

通过调用 handleEnd() 函数来处理触摸结束事件:

const handleEnd = (evt: TouchEvent) => {  evt.preventDefault();  const touches = evt.changedTouches;  for (let i = 0; i < touches.length; i++) {    const indexById = activityTouchIndexById(touches[i].identifier);    if (indexById >= 0) {      cxt.value.beginPath();      cxt.value.moveTo(activityTouches[indexById].x, activityTouches[indexById].y);      cxt.value.lineTo(touches[i].clientX, touches[i].clientY);      drawCircle(touches[i].clientX, touches[i].clientY)      //移除缓存      activityTouches.splice(indexById, 1);    }  }};

类似handleMove ,首先遍历所有事件,并读取缓存。在事件触发点画个圆,然后将对应的触摸对象从缓存中移除。

其他

移动端和PC端所对应的时间不同。详情可见鼠标事件和触摸事件文档。

移动端的触摸点信息被封装在Touch中,通过Touch.clientXTouch.clientX 读取当前坐标

移动端的触摸点信息被封装在MouseEvent中

完整代码

<template>  <canvas    ref="board"        width="1000"    height="1000"    @touchstart="handleStart"    @touchmove="handleMove"    @touchend="handleEnd"  ></canvas></template><script setup lang="ts">import { onMounted, ref } from 'vue';const board = ref();const cxt = ref();const lineWidth = 4;onMounted(() => {  initPointer();});const initPointer = () => {  cxt.value = board.value.getContext('2d');  window.MeApi?.mainWindowLoaded();  cxt.value.strokeStyle = 'red';  cxt.value.fillStyle = 'red';  cxt.value.lineWidth = lineWidth;};type Point = {  identifier: number,  x: number,  y: number};const activityTouches: Point[] = [];const copyTouch = (touch: Touch) => {  return {    identifier: touch.identifier,    x: touch.pageX,    y: touch.pageY  };};const activityTouchIndexById = (idToFind: number) => {  for (let i = 0; i < activityTouches.length; i++) {    const id = activityTouches[i].identifier;    if (id === idToFind) {      return i;    }  }  return -1;};const handleStart = (evt: TouchEvent) => {  const touches = evt.changedTouches;  for (let i = 0; i < touches.length; i++) {    activityTouches.push(copyTouch(touches[i]));    cxt.value.beginPath();    drawCircle(touches[i].clientX, touches[i].clientY)  }};const handleMove = (evt: TouchEvent) => {  evt.preventDefault();  const touches = evt.changedTouches;  for (let i = 0; i < touches.length; i++) {    const indexById = activityTouchIndexById(touches[i].identifier);    if (indexById >= 0) {      cxt.value.beginPath();      cxt.value.moveTo(activityTouches[indexById].x, activityTouches[indexById].y);      cxt.value.lineTo(touches[i].clientX, touches[i].pageY);      cxt.value.stroke();      activityTouches.splice(indexById, 1, copyTouch(touches[i]));    }  }};const handleEnd = (evt: TouchEvent) => {  evt.preventDefault();  const touches = evt.changedTouches;  for (let i = 0; i < touches.length; i++) {    const indexById = activityTouchIndexById(touches[i].identifier);    if (indexById >= 0) {      cxt.value.beginPath();      cxt.value.moveTo(activityTouches[indexById].x, activityTouches[indexById].y);      cxt.value.lineTo(touches[i].clientX, touches[i].clientY);      drawCircle(touches[i].clientX, touches[i].clientY)      activityTouches.splice(indexById, 1);    }  }};const drawCircle = (x:number,y:number) => {  cxt.value.arc(x, y, lineWidth / 2, 0, 2 * Math.PI, false);  cxt.value.fill();}</script>

到此,关于“Vue怎么实现多点涂鸦效果”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯