当前位置: 首页 > 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 官方文档…...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)

引言&#xff1a;为什么 Eureka 依然是存量系统的核心&#xff1f; 尽管 Nacos 等新注册中心崛起&#xff0c;但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制&#xff0c;是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

Python爬虫(一):爬虫伪装

一、网站防爬机制概述 在当今互联网环境中&#xff0c;具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类&#xff1a; 身份验证机制&#xff1a;直接将未经授权的爬虫阻挡在外反爬技术体系&#xff1a;通过各种技术手段增加爬虫获取数据的难度…...

多种风格导航菜单 HTML 实现(附源码)

下面我将为您展示 6 种不同风格的导航菜单实现&#xff0c;每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

关于uniapp展示PDF的解决方案

在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项&#xff1a; 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库&#xff1a; npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...

vue3 daterange正则踩坑

<el-form-item label"空置时间" prop"vacantTime"> <el-date-picker v-model"form.vacantTime" type"daterange" start-placeholder"开始日期" end-placeholder"结束日期" clearable :editable"fal…...

微服务通信安全:深入解析mTLS的原理与实践

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、引言&#xff1a;微服务时代的通信安全挑战 随着云原生和微服务架构的普及&#xff0c;服务间的通信安全成为系统设计的核心议题。传统的单体架构中&…...

【UE5 C++】通过文件对话框获取选择文件的路径

目录 效果 步骤 源码 效果 步骤 1. 在“xxx.Build.cs”中添加需要使用的模块 &#xff0c;这里主要使用“DesktopPlatform”模块 2. 添加后闭UE编辑器&#xff0c;右键点击 .uproject 文件&#xff0c;选择 "Generate Visual Studio project files"&#xff0c;重…...

第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10+pip3.10)

第一篇&#xff1a;Liunx环境下搭建PaddlePaddle 3.0基础环境&#xff08;Liunx Centos8.5安装Python3.10pip3.10&#xff09; 一&#xff1a;前言二&#xff1a;安装编译依赖二&#xff1a;安装Python3.10三&#xff1a;安装PIP3.10四&#xff1a;安装Paddlepaddle基础框架4.1…...