当前位置: 首页 > news >正文

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 = 800canvas.height = 800const 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().leftconst y = event.clientY - canvas.getBoundingClientRect().topfor (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 = 800canvas.height = 800const 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().leftconst y = event.clientY - canvas.getBoundingClientRect().topdraw(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 = 1200canvas.height = 800const context = canvas.getContext('2d')const balls = []let isMoving = truelet 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 + 20const 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 = falsethis.text = '开始运动'} else {isMoving = truethis.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].colorcxt.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].vxballs[i].y += balls[i].vyif (balls[i].x - balls[i].radius <= 0) {balls[i].vx = -balls[i].vxballs[i].x = balls[i].radius}if (balls[i].x + balls[i].radius >= canvasWidth) {balls[i].vx = -balls[i].vxballs[i].x = canvasWidth - balls[i].radius}if (balls[i].y - balls[i].radius <= 0) {balls[i].vy = -balls[i].vyballs[i].y = balls[i].radius}if (balls[i].y - balls[i].radius >= canvasHeight) {balls[i].vy = -balls[i].vyballs[i].y = canvasHeight - balls[i].radius}}}</script>
</body></html>

图示:

1

相关文章:

canvas基础3 -- 交互

点击交互 使用 isPointInPath(x, y) 判断鼠标点击位置在不在图形内 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"&…...

Flutter——最详细(Scaffold)使用教程

Scaffold简介 相当于界面的主体&#xff08;类似于安卓最外层PhoneWindow&#xff09;&#xff0c;组件的展示都必须依附于它。 使用场景&#xff1a; 每一个界面都是脚手架&#xff0c;通过它来进行架构实现&#xff0c;优美的布局效果。 属性作用appBar顶部的标题栏body显示整…...

C语言编写图形化界面-创建按钮-为其指定样式

文章目录 前置章节指定窗口样式给按钮加边框扁平化按钮复选框样式按钮自动复选框 单选按钮三态按钮自动三态按钮 默认按钮样式&#xff08;对话框Enter键&#xff09; 设置按钮位置和大小封装函数 前置章节 开始之前&#xff0c;需要学习以下章节&#xff1a; 创建窗口 窗口过…...

C++并发与多线程(7) | 创建多个线程时数据共享的问题

一、创建和等待多个线程 借助vector存放多个线程thread对象,借助vector和它的迭代器实现创建和运行多个线程,代码如下: #include <iostream> #include <thread> #include <vector> using namespace std;void myprint(int inum) {cout << "mypr…...

进程间通信(匿名管道、命名管道、消息队列、共享内存、信号量、信号、Socket)

文章目录 一、什么是进程间通信二、管道1.匿名管道(pipe)a).创建匿名管道b).管道的读写规则c).匿名管道的特点 2.有名管道(FIFO)a).创建命名管道b).命名管道的特点c).基于命名管道的进程间通信&#xff08;服务端/客户端&#xff09; 三、消息队列四、共享内存1.什么是共享内存…...

浅谈中国汽车充电桩行业市场状况及充电桩选型的介绍

安科瑞虞佳豪 车桩比降低是完善新能源汽车行业配套的一大重要趋势&#xff0c;目前各国政府都在努力推进政策&#xff0c;通过税收减免、建设补贴等措施提升充电桩建设速度&#xff0c;以满足新能源汽车需求。 近年来&#xff0c;在需求和技术的驱动下&#xff0c;充电桩的平…...

Postgresql在jdbc处理bit字段的解决方案

问题&#xff1a; bit如果长度为1&#xff0c;则会默认为布尔型&#xff08;1-true 0-false&#xff09;&#xff1b; bit如果长度大于1&#xff0c;则会默认为bit类型&#xff0c;但是代码中以前常用的两种set方式&#xff0c;会报错 第一种方式&#xff1a; ps.setObject(i1,…...

ESMapping字段

在 Elasticsearch 中&#xff0c;字段&#xff08;field&#xff09;是指用于表示数据的最小单元。每个文档&#xff08;document&#xff09;都由一个或多个字段组成&#xff0c;字段存储了文档的不同属性或数据。 字段可以包含不同的数据类型&#xff0c;如文本、数字、日期…...

基于LDA的隐式标签协同过滤推荐算法_文勇军

, 王全民等人[14]提出了一种交替奇异值分解算法 (ASVD),即结合协同过滤和隐语义分析的混合推荐 算法。唐泽坤等人[15]融合聚类算法和协同过滤推荐 算法,取得了一定效果。高娜等人[16⁃19]将标签因子 和协同过滤推荐算法结合研究缓解了数据稀疏问题,但这…...

在线设计数据库表用Itbuilder,极简易用真香!!!

“如果您想要一个具有快速搜索运行的高性能数据库&#xff0c;那么数据库设计是必不可少的&#xff0c;花时间设计数据库将帮助您避免效率低下和高冗余等问题”。 在线数据库设计软件itbuilder&#xff0c;界面清爽漂亮&#xff0c;功能简洁&#xff0c;没有多余设置很容易上手…...

onclick事件的用法

onclick 事件是一种在网页开发中用来处理用户点击操作的事件。它通常用于 HTML 元素&#xff08;如按钮、链接、图像等&#xff09;&#xff0c;以便在用户单击该元素时触发 JavaScript 函数或执行一些特定的操作。以下是 onclick 事件的用法&#xff1a; HTML 元素上的 onclic…...

二叉排序树

二叉排序树定义及性质 二叉排序树(Binary Sort Tre)或者是一棵空树&#xff0c;或者是具有如下性质的二叉树&#xff1a; (1) 若它的左子树不空&#xff0c;则左子树上所有结点的值均小于它的根结点的值&#xff1b; (2) 若它的右子树不空&#xff0c;则右子树上所有结点的值均…...

探秘Spring的设计精髓,深入解析架构原理

序员与平庸的程序员之间的区别&#xff0c;是在于认为自己的代码重要还是数据结构更加重要。平庸的程序员眼里只有代码&#xff0c;优秀的程序员则关注数据结构及之前的关系。” 1、spring的设计理念 spring提供了一个轻量级的开发框架&#xff0c;抽象了实际开发中的很多共…...

Python Wordcloud报错:Only supported for TrueType fonts,多种解决方案

Python Wordcloud报错&#xff1a;Only supported for TrueType fonts&#xff0c;多种解决方案。 报错内容如下&#xff1a; 2023-10-26T09:35:41.190459839Z Traceback (most recent call last): 2023-10-26T09:35:41.190502589Z File “lib/task/compute.py”, line 621, i…...

为虚拟网络提供敏捷负载均衡:Everoute LB 特性解读

为了保证应用系统的可用性&#xff0c;同时避免并发访问导致后端服务器出现性能瓶颈&#xff0c;不少用户都通过负载均衡技术优化流量分发。随着虚拟化平台下用户业务规模的持续扩大&#xff0c;虚拟化网络的数据访问量也不断增加&#xff0c;而传统负载均衡通常通过硬件负载均…...

Jmeter 接口测试,参数值为列表,如何参数化?

最近在我的教学过程中&#xff0c;我的一个学生问了我一个问题&#xff0c;他们公司的一个接口参数值是列表&#xff0c;列表中值的数量有多有少&#xff0c;问我在 jmeter 中如何让这个参数的值进行参数化&#xff1f; 看到这种问题&#xff0c;你的第一反应是什么&#xff1f…...

DeepinV20实现使用CapsLock键切换输入法

概览 起因参考资料解决问题1. 删除CapsLock键映射关系2. 新建CapsLock键映射关系3. 建立配置文件4. **注销用户或者重启电脑**5. 修改切换输入法快捷键6. 测试输入 起因 看同事的MacBook可以使用CapsLock键切换输入法&#xff0c;而我作为Shift党CapsLock键几乎不使用&#xf…...

基于springboot实现校友社交平台管理系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现校友社交平台管理系统演示 摘要 校友社交系统提供给用户一个校友社交信息管理的网站&#xff0c;最新的校友社交信息让用户及时了解校友社交动向,完成校友社交的同时,还能通过论坛中心进行互动更方便。本系统采用了B/S体系的结构&#xff0c;使用了java技…...

WordPress主题模板 大前端D8 5.1版本完整开源版源码简洁大气多功能配置

源码测评&#xff1a;该模板官方已更新至5.2&#xff0c;但是这个5.1也是非常好用的&#xff0c;经测试所有页面均完好&#xff0c;推荐下载使用。 模板简介&#xff1a; 大前端D8 主题是一款非常牛逼的WordPress博客主题,响应式,功能齐全,支持手机,电脑,平板,非常适合做博客站…...

如何在Postman中使用静态HTTP

首先&#xff0c;打开 Postman 软件。在 Postman 的菜单栏中&#xff0c;点击 “Preferences”&#xff08;偏好设置&#xff09;。 亲身经验&#xff1a;我自己尝试了这个方法&#xff0c;发现它非常适用于需要使用HTTP的场景。 数据和引证&#xff1a;根据 Postman 官方文档…...

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中&#xff0c;时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志&#xff0c;到供应链系统的物流节点时间戳&#xff0c;时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库&#xff0c;其日期时间类型的…...

工业安全零事故的智能守护者:一体化AI智能安防平台

前言&#xff1a; 通过AI视觉技术&#xff0c;为船厂提供全面的安全监控解决方案&#xff0c;涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面&#xff0c;能够实现对应负责人反馈机制&#xff0c;并最终实现数据的统计报表。提升船厂…...

聊聊 Pulsar:Producer 源码解析

一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台&#xff0c;以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中&#xff0c;Producer&#xff08;生产者&#xff09; 是连接客户端应用与消息队列的第一步。生产者…...

Java入门学习详细版(一)

大家好&#xff0c;Java 学习是一个系统学习的过程&#xff0c;核心原则就是“理论 实践 坚持”&#xff0c;并且需循序渐进&#xff0c;不可过于着急&#xff0c;本篇文章推出的这份详细入门学习资料将带大家从零基础开始&#xff0c;逐步掌握 Java 的核心概念和编程技能。 …...

SpringCloudGateway 自定义局部过滤器

场景&#xff1a; 将所有请求转化为同一路径请求&#xff08;方便穿网配置&#xff09;在请求头内标识原来路径&#xff0c;然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。

1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj&#xff0c;再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

【Oracle】分区表

个人主页&#xff1a;Guiat 归属专栏&#xff1a;Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...

使用 SymPy 进行向量和矩阵的高级操作

在科学计算和工程领域&#xff0c;向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能&#xff0c;能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作&#xff0c;并通过具体…...

初学 pytest 记录

安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...

代码随想录刷题day30

1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币&#xff0c;另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额&#xff0c;返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...