canvas基础3 -- 交互

news2024/11/15 8:26:17

点击交互

使用 isPointInPath(x, y) 判断鼠标点击位置在不在图形内

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <canvas id="canvas" style="border:1px solid #ccc;display:block;margin:10px auto;"></canvas>
  </div>

  <script>
    const canvas = document.getElementById('canvas')
    canvas.width = 800
    canvas.height = 800
    const context = canvas.getContext('2d')

    const balls = []
    for(let i = 0; i < 10; i++) {
      const ball = {
        x: Math.random() * canvas.width,
        y: Math.random() * canvas.height,
        r: Math.random() * 50 + 20
      }

      balls[i] = ball
    }

    draw()
    canvas.addEventListener('mouseup', detect)

    function draw() {
      for(let i = 0; i < balls.length; i++) {
        context.beginPath()
        context.arc(balls[i].x, balls[i].y, balls[i].r, 0, Math.PI*2)
        context.fillStyle = '#058'
        context.fill()
      }
    }

    function detect(event) {
      const x = event.clientX - canvas.getBoundingClientRect().left
      const y = event.clientY - canvas.getBoundingClientRect().top

      for (let i = 0; i < balls.length; i++) {
        context.beginPath()
        context.arc(balls[i].x, balls[i].y, balls[i].r, 0, Math.PI * 2)

        if (context.isPointInPath(x, y)) {
          context.fillStyle = 'red'
          context.fill()
        }
      }
    }

    
  </script>
</body>

</html>

图示:

鼠标移动事件

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <canvas id="canvas" style="border:1px solid #ccc;display:block;margin:10px auto;"></canvas>
  </div>

  <script>
    const canvas = document.getElementById('canvas')
    canvas.width = 800
    canvas.height = 800
    const context = canvas.getContext('2d')

    const balls = []
    for(let i = 0; i < 10; i++) {
      const ball = {
        x: Math.random() * canvas.width,
        y: Math.random() * canvas.height,
        r: Math.random() * 50 + 20
      }

      balls[i] = ball
    }

    draw()
    canvas.addEventListener('mousemove', detect)

    function draw(x, y) {
      context.clearRect(0, 0, canvas.width, canvas.height)
      for(let i = 0; i < balls.length; i++) {
        context.beginPath()
        context.arc(balls[i].x, balls[i].y, balls[i].r, 0, Math.PI*2)

        if(context.isPointInPath(x, y)) {
          context.fillStyle = 'red'
        } else {
          context.fillStyle = '#058'
        }
        
        context.fill()
      }
    }

    function detect(event) {
      const x = event.clientX - canvas.getBoundingClientRect().left
      const y = event.clientY - canvas.getBoundingClientRect().top

      draw(x, y)
    }

    
  </script>
</body>

</html>

图示:

在Canvas上使用HTML元素进行交互

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    #canvas-wrapper {
      width: 1200px;
      height: 800px;
      position: relative;
      margin: 20px auto;
    }

    #canvas {
      border: 1px solid #aaa;
    }

    #controller {
      position: absolute;
      top: 30px;
      left: 30px;
      background-color: rgba(0, 85, 116, 0.7);
      padding: 5px 20px 25px 20px;
      border-radius: 10px 10px;
    }

    #controller h1 {
      color: white;
      font-weight: bold;
      font-family: Microsoft Yahei;
    }

    #controller #canvas-btn {
      display: inline-block;
      background-color: #8b0;
      color: white;
      font-size: 14px;
      padding: 5px 15px;
      border-radius: 6px;
      text-decoration: none;
      margin-top: 10px;
      margin-right: 20px;
    }

    #controller #canvas-btn:hover {
      background-color: #7a0;
    }

    #controller .color-btn {
      display: inline-block;
      font-size: 14px;
      padding: 5px 15px;
      border-radius: 6px;
      text-decoration: none;
      margin-top: 10px;
      margin-right: 5px;
    }

    #white-color-btn {
      background: white;
    }

    #black-color-btn {
      background: black;
    }
  </style>
</head>

<body>
  <div id="canvas-wrapper">
    <canvas id="canvas"></canvas>
    <div id="controller">
      <h1>Canvas 绘图之旅</h1>
      <a href="#" id="canvas-btn">停止运动</a>
      <a href="#" class="color-btn" id="white-color-btn">&nbsp;</a>
      <a href="#" class="color-btn" id="black-color-btn">&nbsp;</a>
    </div>
  </div>
  
  <script>
    const canvas = document.getElementById('canvas')
    canvas.width = 1200
    canvas.height = 800
    const context = canvas.getContext('2d')

    const balls = []
    let isMoving = true
    let themeColor = 'white'
    for(let i = 0; i < 100; i++) {
      const R = Math.floor(Math.random() * 255)
      const G = Math.floor(Math.random() * 255)
      const B = Math.floor(Math.random() * 255)
      const radius = Math.random() * 50 + 20

      const ball = {
        color: `rgb(${R}, ${G}, ${B})`,
        radius,
        x: Math.random() * (canvas.width - 2*radius) + radius,
        y: Math.random() * (canvas.height - 2*radius) + radius,
        vx: (Math.random() * 5 + 5) * Math.pow(-1, Math.floor(Math.random()*100)),
        vy: (Math.random() * 5 + 5) * Math.pow(-1, Math.floor(Math.random() * 100)),
      }

      balls[i] = ball
    }

    setInterval(function() {
      draw(context)
      if(isMoving) {
        update(canvas.width, canvas.height)
      }
    }, 50)

    document.getElementById('canvas-btn').onclick = function() {
      if (isMoving) {
        isMoving = false
        this.text = '开始运动'
      } else {
        isMoving = true
        this.text = '停止运动'
      }
    }

    document.getElementById('white-color-btn').onclick = function() {
      themeColor = 'white'
      return false
    }

    document.getElementById('black-color-btn').onclick = function () {
      themeColor = 'black'
      return false
    }

    function draw(cxt) {
      cxt.clearRect(0, 0, cxt.canvas.width, cxt.canvas.height)

      if (themeColor === 'black') {
        cxt.fillStyle = 'black'
        cxt.fillRect(0, 0, cxt.canvas.width, cxt.canvas.height)
      }
      for(let i = 0; i < balls.length; i++) {
        cxt.fillStyle = balls[i].color
        cxt.beginPath()
        cxt.arc(balls[i].x, balls[i].y, balls[i].radius, 0, Math.PI*2)
        cxt.closePath()
        cxt.fill()
      }
    }

    function update(canvasWidth, canvasHeight) {
      for (let i = 0; i < balls.length; i++) {
        balls[i].x += balls[i].vx
        balls[i].y += balls[i].vy

        if (balls[i].x - balls[i].radius <= 0) {
          balls[i].vx = -balls[i].vx
          balls[i].x = balls[i].radius
        }

        if (balls[i].x + balls[i].radius >= canvasWidth) {
          balls[i].vx = -balls[i].vx
          balls[i].x = canvasWidth - balls[i].radius
        }

        if (balls[i].y - balls[i].radius <= 0) {
          balls[i].vy = -balls[i].vy
          balls[i].y = balls[i].radius
        }

        if (balls[i].y - balls[i].radius >= canvasHeight) {
          balls[i].vy = -balls[i].vy
          balls[i].y = canvasHeight - balls[i].radius
        }
      }
    }

    
  </script>
</body>

</html>

图示:

1

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1131695.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

「北大社送书」学习Flutter编程 — 《从零基础到精通Flutter开发》

目录 1.书籍推荐理由 2.本书特色 3.内容简介 4.书籍概览 1.书籍推荐理由 一套代码&#xff0c;构建多平台精美的应用&#xff1a;本书从真实的开发场景出发&#xff0c;完整地讲解了Flutter框架&#xff0c;帮助你快速掌握Flutter的基础知识和开发技巧&#xff0c;助你在移…

服务器百万并发的原理与实现

什么是百万并发&#xff1f; 指的是服务器接收百万个连接或数据会在同一时刻接收到&#xff0c;也就是同时能看到 百万个连接或数据。 在了解服务器百万并发的同时&#xff0c;我们先来看看我们的百万并发服务器的结构图。 主体是以reactor为核心&#xff0c;链表方式存储事…

「北大社送书」学习MATLAB—从算法到实战

MATLAB科学计算从入门到精通 一句话推荐书籍特色内容简介书籍概览 从代码到函数&#xff0c;从算法到实战&#xff0c;从问题到应用&#xff0c;由浅入深掌握科学计算方法&#xff0c;高效解决实际问题。 一句话推荐 科学计算基础入门&#xff0c;高效解决实际问题。 书籍特色…

vue3中的provide 与 inject

一、概述 作用&#xff1a;实现祖先与后代组件的通信。一般为祖孙通信&#xff0c;因为子组件可以用props来通信。 语法&#xff1a;父组件中&#xff1a;provide(car, car) 子组件中&#xff1a;let car inject(car) 二、举例说明&#xff08;代码如下&#xff09; &…

逐鹿千亿市场:一碗中国面的魅力

【潮汐商业评论/原创】 根据世界方便面协会&#xff08;WINA&#xff09;发布的数据&#xff0c;2022年全球方便面总需求量同比增长4.0%至1212亿份&#xff0c;再创历史新高。从小门头商铺到大型商超&#xff0c;从线下到线上&#xff0c;方便面早就走进了千家万户&#xff0c…

C++ 左值、右值、左值引用以及右值引用

一、左值和右值 将亡值 1.左值 左值是一个表示数据的表达式&#xff0c;比如&#xff1a;变量名、解引用的指针变量。一般地&#xff0c;我们可以获取它的地址和对它赋值&#xff0c;但被 const 修饰后的左值&#xff08;常性&#xff09;&#xff0c;不能给它赋值&#xff0…

系统架构设计师之软件概要设计

系统架构设计师之软件概要设计

设计模式(15)组合模式

一、介绍&#xff1a; 1、定义&#xff1a;组合多个对象形成树形结构以表示“整体-部分”的关系的层次结构。组合模式对叶子节点和容器节点的处理具有一致性&#xff0c;又称为整体-部分模式。 2、优缺点&#xff1a; 优点&#xff1a; &#xff08;1&#xff09;高层模块调…

国外问卷调查赚钱靠谱吗?

大家好&#xff0c;我是橙河网络&#xff0c;这几年的国外问卷调查项目可真是火得一塌糊涂&#xff0c;不少人靠这个项目赚得是盆满钵满&#xff0c;让人直流口水。今天&#xff0c;我就来给大家详细扒一扒这个国外问卷调查赚钱靠谱吗&#xff1f; 首先&#xff0c;我得跟大家…

家长扫码查成绩

亲爱的老师&#xff0c;你是否曾为了如何让家长更方便地查询学生的成绩而烦恼&#xff1f;现在&#xff0c;我们为你介绍一款简单易用的成绩查询系统&#xff0c;让家长只需轻轻一扫&#xff0c;即可查看孩子的成绩。 一、什么是成绩查询系统&#xff1f; 成绩查询系统是一款专…

TTS | 一文总览语音合成系列基础知识及简要介绍

Text-to-Speech&#xff08;通常缩写为TTS&#xff09;是指一种将文本读成音频的技术。换句话说&#xff0c;它指的是一种模型&#xff0c;在该模型中&#xff0c;当文本或类似于字符的东西作为输入时&#xff0c;会生成波形音频作为输出。 但实际上&#xff0c;这个 TTS 的音…

iOS调试技巧——使用Python 自定义LLDB

一、类介绍 在使用Python 自定义LLDB之前,先了解一下LLDB的一些类型 SBTarget 正在被调试的程序SBProcess 和程序关联的具体的进程SBThread 执行的线程SBFrame 和线程关联的一个栈帧SBVariable 变量,寄存器或是一个表达式一般情况下,我们取到SBFrame就可以进行方法调用来打…

Spring Boot整合swagger2

在上一篇中我们围绕了Spring Boot 集成了RESTful API项目&#xff0c;但是我们在实际开发中&#xff0c;我们的一个RESTful API有可能就要服务多个不同的开发人员或者开发团队&#xff0c;包括不限于PC,安卓&#xff0c;IOS&#xff0c;甚至现在的鸿蒙OS&#xff0c;web开发等等…

buuctf_练[网鼎杯 2018]Fakebook

[网鼎杯 2018]Fakebook 文章目录 [网鼎杯 2018]Fakebook掌握知识解题思路关键paylaod 掌握知识 ​ SQL注入的联合注入&#xff1b;闭合类型的探查&#xff0c;本次是数字型闭合&#xff1b;SQL注入的读取文件的利用 解题思路 打开题目链接&#xff0c;发现主界面给了一些信息…

大数据-Storm流式框架(一)

一、storm介绍 Storm是个实时的、分布式以及具备高容错的计算系统 Storm进程常驻内存&#xff08;worker&#xff0c;supervisor&#xff0c;nimbus&#xff0c;ui&#xff0c;logviewer。。。&#xff09;Storm数据不经过磁盘&#xff0c;在内存中处理Twitter开源的分布式实时…

CSS基础框盒模型:打造炙手可热的网页布局!

&#x1f3ac; 江城开朗的豌豆&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 &#x1f4dd; 个人网站 :《 江城开朗的豌豆&#x1fadb; 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! 目录 ⭐ 专栏简介 &#x1f4d8; 文章引言 一、是…

老师们都在用的办公好物

现在还有老师不知道班级查询系统吗?各位老师们&#xff0c;向大家推荐一款超级实用的班级查询系统&#xff0c;帮你轻松管理学生信息&#xff0c;省去繁琐的手动操作&#xff0c;还能让学生们自主查询&#xff0c;简直是老师的福音&#xff01; 如果你在编程方面感到有些吃力&…

vscode推送gitee方法

有一套uni-app代码需要修改&#xff0c;版本控制使用vscode的git功能&#xff0c;远程库在gitee上。 1、设置vscode中git.exe路径 由于git使用了绿色便携版&#xff08;PortableGit-2.42.0.2-64-bit.7z.exe&#xff09;&#xff0c;vscode未识别到git安装路径&#xff0c;需要…

RTE2023大会来袭,声网宣布首创广播级4K超高清实时互动体验

10月24日&#xff0c;由声网和RTE开发者社区联合主办的RTE2023第九届实时互联网大会在北京举办&#xff0c;声网与众多RTE领域技术专家、产品精英、创业者、开发者一起&#xff0c;共同开启了以“智能高清”为主题的全新探讨。本届RTE大会将持续2天&#xff0c;开展1场主论坛及…

【路径规划】A*算法 Java实现

A*&#xff08;A-Star&#xff09;算法是一种广泛使用的寻路算法&#xff0c;尤其在计算机科学和人工智能领域。 算法思想 通过评估函数来引导搜索过程&#xff0c;从而找到从起始点到目标点的最短路径。评估函数通常包括两部分&#xff1a;一部分是已经走过的实际距离&#x…