canvas基础3 -- 交互

点击交互

使用 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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

mac电脑怎么永久性彻底删除文件?

Mac老用户都知道在我们查看Mac内存时都会发现有一条“其他文件”占比非常高&#xff0c;它是Mac储存空间中的“其他”数据包含不可移除的移动资源&#xff0c;如&#xff0c;Siri 语音、字体、词典、钥匙串和 CloudKit 数据库、系统无法删除缓存的文件等。这些“其他文件”无用…

腾讯云优惠券、代金券、云服务器折扣券领取方法及使用教程

腾讯云优惠券是腾讯云为用户提供的一种优惠活动&#xff0c;通常包括代金券和折扣券两种类型&#xff0c;代金券可以在购买腾讯云相关产品时直接抵扣订单金额&#xff0c;而折扣券则可以在购买腾讯云相关产品时享受一定的折扣。 腾讯云作为国内领先的云计算服务提供商&#xff…

时间、空间复杂度的例题详解

文章前言 上篇文章带大家认识了数据结构和算法的含义&#xff0c;以及理解了时间、空间复杂度&#xff0c;那么接下来来深入理解一下时间、空间复杂度。 时间复杂度实例 实例1 // 计算Func2的时间复杂度&#xff1f; void Func2(int N) {int count 0;for (int k 0; k <…

eslint提示 xxx should be listed in the project's dependencies

有时候手动安装了一个npm包A&#xff0c;npm包A里面包含了npm包B&#xff0c;这时候如果 import xxx from npm包B;eslint会报错&#xff0c;提示 npm包B 不在 package.json 里面 解决方法&#xff1a;在 eslintrc.js 增加配置 module.exports {rules: {import/no-extraneous-d…

docker和K8S环境xxl-job定时任务不执行问题总结

文章目录 xxl-job 任务调度原理1 问题1 时区导致的任务没有执行的问题解决方案 2 执行器注册和下线导致的问题&#xff08;IP问题&#xff09;解决方案 3 问题3 调度成功&#xff0c;但是执行器的定时任务未执行4 问题4 数据库性能问题&#xff0c;导致查询任务和操作日志数据卡…

Ocelot简易教程目录

Ocelot简易教程目录 这里写目录标题 Ocelot简易教程目录 Ocelot简易教程&#xff08;一&#xff09;之Ocelot是什么Ocelot简易教程&#xff08;二&#xff09;之快速开始1Ocelot简易教程&#xff08;二&#xff09;之快速开始2Ocelot简易教程&#xff08;三&#xff09;之主要特…

Linux MMC子系统 - 2.eMMC 5.1总线协议浅析

By: Ailson Jack Date: 2023.10.27 个人博客&#xff1a;http://www.only2fire.com/ 本文在我博客的地址是&#xff1a;http://www.only2fire.com/archives/161.html&#xff0c;排版更好&#xff0c;便于学习&#xff0c;也可以去我博客逛逛&#xff0c;兴许有你想要的内容呢。…

Qt界面实现中英文切换

要实现的效果&#xff0c;是下拉列表切换中文和English实现按钮文本中英文内容切换。 实现步骤&#xff1a; 1.在VS中鼠标对Translation Files文件右击&#xff0c;选择“添加”--->“模块”. 在弹窗的窗口中选择“Qt”--->“Qt Translation File”。 添加Translation_e…

50个常用的Java代码示例

50个常用的Java代码示例 1.输出语句&#xff1a; System.out.println(Hello World!);2.定义变量&#xff1a; int x 5; String name John;3.循环语句&#xff1a; for(int i 0; i < 10; i) {System.out.println(i);}4.条件语句&#xff1a; if(x > 0) {System.ou…

MQTT(详解)

什么是MQTT MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;是一种轻量级的通信协议&#xff0c;用于在设备之间传输消息。它通常用于物联网&#xff08;IoT&#xff09;和传感器网络中&#xff0c;可以在不同设备之间进行可靠的通信&#xff0c;而且资源消耗…

YOLOv5配置文件之 - yaml

在YOLOv5的目录中&#xff0c;models文件夹里存储了YOLO的模型配置。 ./models/yolov5.yaml 定义了YOLOv5s网络结构的定义文件 yaml的主要内容 参数配置 nc: 80 类别数量 depth_multiple: 0.33 模型深度缩放因子 width_multiple: 0.50 控制卷积特征图的通道个数 anchors配…

【Docker】Docker-Compose内置DNS负载均衡失效问题

Docker Compose实现负载均衡 还是对前面的例子docker-compose.yml稍微修改&#xff1a; version: "3.8"services:flask-demo:build:context: .dockerfile: Dockerfileimage: flask-demo:latestenvironment:- REDIS_HOSTredis-server- REDIS_PASS${REDIS_PASS}healt…

N-129基于springboot,vue学生宿舍管理系统

开发工具&#xff1a;IDEA 服务器&#xff1a;Tomcat9.0&#xff0c; jdk1.8 项目构建&#xff1a;maven 数据库&#xff1a;mysql5.7 系统分前后台&#xff0c;项目采用前后端分离 前端技术&#xff1a;vuevue-element-admin 服务端技术&#xff1a;springboot,mybatis…

UML中类之间的六种主要关系

UML中类之间的六种主要关系: 继承&#xff08;泛化&#xff09;&#xff08;Inheritance、Generalization&#xff09;, 实现&#xff08;Realization&#xff09;&#xff0c;关联&#xff08;Association)&#xff0c;聚合&#xff08;Aggregation&#xff09;&#xff0c;组…

JDK API Diff Report Generator-Java版本对比工具

今天查资料找到了除了EMT4J之外&#xff0c;其他可以用于Java版本迁移的工具。 这里简单的记录一下。 非Java er&#xff0c;有不同意见欢迎评论区交流。 JDK API Diff Report Generator JDK API Diff是一个用于比较不同Java版本API区别的工具。github地址在这里。 例如&am…

Android---StartActivity启动过程

在手机桌面应用中点击某一个 icon 之后&#xff0c;最终是通过 startActivity 去打开某一个 Activity 页面。我们知道&#xff0c;Android 中的一个 APP 就相当于一个进程。所以&#xff0c;startActivity 操作中还需要判断&#xff0c;目标 Activity 的进程是否已经创建。如果…

竞赛选题 深度学习人体跌倒检测 -yolo 机器视觉 opencv python

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; **基于深度学习的人体跌倒检测算法研究与实现 ** 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f947;学长这里给一个题目综合评分(每项满…

STM32-ADC实验

目录 实验1&#xff1a;单ADC单通道中断 硬件原理图 USART配置 ADC1配置 初始化结构体的参数 ScanConvMode&#xff1a;扫描转换模式 ContinuousConvMode&#xff1a;连续转换模式 ExternalTrigConv&#xff1a;外部触发方式 测试环节 实验现象 实验2&#xff1a;单…

【疑问解决】在自动装箱中Integer赋予一个常量1,为什么会出现==判断true和flase的情况(JDK源码、内部缓冲)

问题来源自讲课时的Integer练习中 当时第一反应是false true true 因为第一段的输出为flase毋庸置疑了&#xff0c;因为已经new了两个新的堆空间&#xff0c;当然指向不同的空间了 但是第二段第三段就没有头绪了&#xff0c;自动装箱了难道不是执行同一个空间吗…

服务网络基础

服务网络基础 目录 前言 从今天开始我们将进入服务网格的学习&#xff0c;服务网格是微服务架构中的一种重要的技术&#xff0c;它可以解决微服务架构中的一些问题&#xff0c;比如服务发现、服务治理、服务监控等等&#xff0c;我们将从服务网格的基础开始&#xff0c;逐步深…