用HTML5 + JavaScript绘制花、树
用HTML5 + JavaScript绘制花、树
<canvas>是一个可以使用脚本 (通常为JavaScript) 来绘制图形的 HTML 元素。
<canvas> 标签/元素只是图形容器,必须使用脚本来绘制图形。
HTML5 canvas 图形标签基础https://blog.csdn.net/cnds123/article/details/112916903
下面展示了如何使用 HTML5 的 <canvas> 标签/元素以及 JavaScript 来绘制花、树等效果。
一、画花
花1、先给出运行效果图:

源码如下:
<!DOCTYPE html>
<html>
<head><title>Canvas绘制花朵</title><style>canvas {border: 1px solid black;}</style>
</head>
<body><canvas id="myCanvas" width="400" height="400"></canvas><script>var canvas = document.getElementById("myCanvas");var context = canvas.getContext("2d");// 绘制花朵:花朵中心的x坐标;花朵中心的y坐标;radius花朵的半径;petalCount花瓣的数量;petalColor花瓣的颜色;centerColor花朵中心的颜色function drawFlower(x, y, petalCount, petalColor, centerColor) {// 绘制花朵的中心context.beginPath();context.arc(x, y, 10, 0, Math.PI * 2, true);context.fillStyle = centerColor;context.fill();var angle = (Math.PI * 2) / petalCount;for (var i = 0; i < petalCount; i++) {context.beginPath();var startX = x + Math.cos(angle * i) * 10;var startY = y + Math.sin(angle * i) * 10;var cp1X = x + Math.cos(angle * i - angle / 4) * 50;var cp1Y = y + Math.sin(angle * i - angle / 4) * 50;var cp2X = x + Math.cos(angle * i + angle / 4) * 50;var cp2Y = y + Math.sin(angle * i + angle / 4) * 50;context.moveTo(startX, startY);//绘制了花瓣context.bezierCurveTo(cp1X, cp1Y, cp2X, cp2Y, startX, startY);context.fillStyle = petalColor;context.fill();//花径context.moveTo(x, y + 10);context.lineTo(x, y + 60);context.stroke();context.strokeStyle = 'DarkCyan'; // 设置颜色}}// 调用函数进行绘制drawFlower(200, 200, 6, "green", "red");drawFlower(250, 300, 8, "green", "red");</script>
</body>
</html>
花2、先给出运行效果图:

源码如下:
<!DOCTYPE html>
<html>
<head><title>Canvas绘制花朵</title><style>canvas {border: 1px solid black;}</style>
</head>
<body><canvas id="myCanvas" width="800" height="600"></canvas><script>// 绘制花朵:x和y定义了花朵中心的位置,radius花朵的半径,petalCount花瓣的数量,petalColor花瓣的颜色,centerColor花朵中心的颜色。function drawFlower(x, y, radius,petalCount, petalColor, centerColor) {var canvas = document.getElementById("myCanvas");var context = canvas.getContext("2d");context.lineWidth = 2;context.strokeStyle = "pink";//花瓣context.fillStyle = petalColor;for (var i = 0; i < petalCount; i++) {context.beginPath();var angle = (2 * Math.PI / petalCount) * i;var petalX = x + Math.cos(angle) * radius;var petalY = y + Math.sin(angle) * radius;context.arc(petalX, petalY, radius, 0, 2 * Math.PI);context.stroke();context.fill();}//花蕊context.beginPath();context.fillStyle = centerColor;context.arc(x, y, radius, 0, 2 * Math.PI);context.stroke();context.fill();//叶子context.beginPath();context.fillStyle = "green";context.arc(x, y + 3 * radius, radius*1.5, 0, Math.PI, false);context.closePath();context.fill();context.beginPath();context.fillStyle = "white"; // 使用白色来覆盖原有的大半圆,形成月牙形context.arc(x, y + 2.7 * radius, radius*1.5, 0, Math.PI, false);context.closePath();context.fill();//花径context.beginPath();context.lineWidth = radius/10; // 设置线宽context.strokeStyle = 'DarkCyan'; // 设置颜色context.moveTo(x, y + radius);context.lineTo(x, y + 6 * radius);context.stroke();}// 调用函数进行绘制drawFlower(500, 250, 30, 4,"#ED6E91", "#f90");drawFlower(250, 300, 8, 6, "pink", "red");</script>
</body>
</html>
二、画树
树1、先给出运行效果图:

源码如下:
<!DOCTYPE html>
<html>
<head><title>Canvas绘制树</title><style>canvas {border: 1px solid black;}</style>
</head>
<body><canvas id="myCanvas" width="800" height="600"></canvas><script>var canvas = document.getElementById("myCanvas");var context = canvas.getContext("2d");// 绘制树function drawTree(x, y, len, angle, branchWidth) {context.beginPath();context.save();context.strokeStyle = "#8B4513";context.fillStyle = "brown";context.lineWidth = branchWidth;context.translate(x, y);context.rotate(angle * Math.PI / 180);context.moveTo(0, 0);context.lineTo(0, -len);context.stroke();if (len < 10) {context.beginPath();context.arc(0, -len, 5, 0, Math.PI * 2, false); // 树叶context.fillStyle = "green";context.fill();context.restore();return;}drawTree(0, -len, len * 0.8, angle - 15, branchWidth * 0.8);drawTree(0, -len, len * 0.8, angle + 15, branchWidth * 0.8);context.restore();}// 调用函数进行绘制drawTree(400, 600, 90, 0, 12);</script>
</body>
</html>
说明:绘制树的函数drawTree(x, y, len, angle, branchWidth),其中参数的含义
x 和 y 参数是树枝的起始点的坐标。在最开始的调用中,这个坐标通常是树的基部。在递归调用中,这个坐标是新的树枝的起点,也就是上一级树枝的终点。
len 参数是树枝的长度。在每次递归调用中,这个长度会减小一些,表示新的树枝比上一级的树枝短一些。
angle 参数是树枝的角度。在最开始的调用中,这个角度通常是 0,表示树直立。在递归调用中,这个角度会有所改变,表示新的树枝相对于上一级的树枝有一个角度。
branchWidth 参数是树枝的宽度。在每次递归调用中,这个宽度会减小一些,表示新的树枝比上一级的树枝细一些。
这个函数首先会在给定的起点和角度处绘制一段长度和宽度为给定值的树枝,然后在这个树枝的终点处递归地绘制两个新的树枝,这两个新的树枝的角度分别向左和向右偏移一定的角度。这个过程一直进行,直到树枝的长度小于一个给定的阈值(在这个例子中是 10)。当达到阈值时,绘制一个绿色的小圆形表示树叶。
树2、是对树1,添加花朵。先给出运行效果图:

源码如下:
<!DOCTYPE html>
<html>
<head><title>Canvas绘制树</title><style>canvas {border: 1px solid black;}</style>
</head>
<body><canvas id="myCanvas" width="800" height="600"></canvas><script>var canvas = document.getElementById("myCanvas");var context = canvas.getContext("2d");// 绘制树function drawTree(x, y, len, angle, branchWidth) {context.beginPath();context.save();context.strokeStyle = "#8B4513";context.fillStyle = "brown";context.lineWidth = branchWidth;context.translate(x, y);context.rotate(angle * Math.PI / 180);context.moveTo(0, 0);context.lineTo(0, -len);context.stroke();if (len < 10) {context.beginPath();context.arc(0, -len, 5, 0, Math.PI * 2, false); // 树叶context.fillStyle = "green";context.fill();context.restore();return;}drawTree(0, -len, len * 0.8, angle - 15, branchWidth * 0.8);drawTree(0, -len, len * 0.8, angle + 15, branchWidth * 0.8);context.restore();}// 绘制花朵function drawFlower(x, y, petalCount, petalColor, centerColor) {// 绘制花朵的中心context.beginPath();context.arc(x, y, 8, 0, Math.PI * 2, true);context.fillStyle = centerColor;context.fill();var angle = (Math.PI * 2) / petalCount;for (var i = 0; i < petalCount; i++) {context.beginPath();var startX = x + Math.cos(angle * i) * 10;var startY = y + Math.sin(angle * i) * 10;var cp1X = x + Math.cos(angle * i - angle / 4) * 30;var cp1Y = y + Math.sin(angle * i - angle / 4) * 30;var cp2X = x + Math.cos(angle * i + angle / 4) * 30;var cp2Y = y + Math.sin(angle * i + angle / 4) * 30;context.moveTo(startX, startY);context.bezierCurveTo(cp1X, cp1Y, cp2X, cp2Y, startX, startY);context.fillStyle = petalColor;context.fill();}}// 调用函数进行绘制drawTree(400, 600, 90, 0, 12);drawFlower(400, 250, 6, "DeepPink", "red");drawFlower(250, 400, 6, "DeepPink", "red");drawFlower(550, 400, 6, "DeepPink", "red");</script>
</body>
</html>
附录
更多例子可见:https://blog.csdn.net/cnds123/article/details/112392014
关于 HTML的元素、标签和属性 是什么,可见https://blog.csdn.net/cnds123/article/details/125745562
相关文章:
用HTML5 + JavaScript绘制花、树
用HTML5 JavaScript绘制花、树 <canvas>是一个可以使用脚本 (通常为JavaScript) 来绘制图形的 HTML 元素。 <canvas> 标签/元素只是图形容器,必须使用脚本来绘制图形。 HTML5 canvas 图形标签基础https://blog.csdn.net/cnds123/article/details/112…...
Science重磅_让大模型像婴儿一样学习语言
英文名称: Grounded language acquisition through the eyes and ears of a single child 中文名称: 通过一个孩子的眼睛和耳朵基于实践学习语言 文章: https://www.science.org/doi/10.1126/science.adi1374 代码: https://github.com/wkvong/multimodalbaby 作者: Wai Keen V…...
Java 数据结构篇-实现红黑树的核心方法
🔥博客主页: 【小扳_-CSDN博客】 ❤感谢大家点赞👍收藏⭐评论✍ 文章目录 1.0 红黑树的说明 2.0 红黑树的特性 3.0 红黑树的成员变量及其构造方法 4.0 实现红黑树的核心方法 4.1 红黑树内部类的核心方法 (1)判断当前…...
【实战】一、Jest 前端自动化测试框架基础入门(中) —— 前端要学的测试课 从Jest入门到TDD BDD双实战(二)
文章目录 一、Jest 前端自动化测试框架基础入门5.Jest 中的匹配器toBe 匹配器toEqual匹配器toBeNull匹配器toBeUndefined匹配器和toBeDefined匹配器toBeTruthy匹配器toBeFalsy匹配器数字相关的匹配器字符串相关的匹配器数组相关的匹配器异常情况的匹配器 6.Jest 命令行工具的使…...
【C语言 - 力扣 - 反转链表】
反转链表题目描述 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 题解1-迭代 假设链表为 1→2→3→∅,我们想要把它改成 ∅←1←2←3。 在遍历链表时,将当前节点的 next 指针改为指向前一个节点。由于节点没…...
ctfshow-php特性(web102-web115)
目录 web102 web103 web104 web105 web106 web107 web108 web109 web110 web111 web112 web113 web114 web115 实践是检验真理的 要多多尝试 web102 <?php highlight_file(__FILE__); $v1$_POST[V1]; $v2$_GET[v2]; $v3$_GET[v3]; $v4is_numeric($v2)and is…...
python系统学习Day1
section1 python introduction 文中tips只做拓展,可跳过。 PartOne introduction 首先要对于python这门语言有一个宏观的认识,包括特点和应用场景。 特点分析: 优势 提供了完善的基础代码库,许多功能不必从零编写简单优雅 劣势 运…...
Idea里自定义封装数据警告解决 Spring Boot Configuration Annotation Processor not configured
我们自定对象封装指定数据,封装类上面一个红色警告,虽然不影响我们的执行,但是有强迫症看着不舒服, 去除方式: 在pom文件加上坐标刷新 <dependency><groupId>org.springframework.boot</groupId><…...
【流程图——讲解】
流程图介绍 流程图介绍 流程图介绍 流程图是一种图表,它展示了工作流程或过程中的步骤顺序,它通常由不同的符号表示,每个符号都代表一个步骤或过程中的一个元素,流程图非常有用,因为它们可以提供清晰、视觉化的过程表…...
「计算机网络」物理层
物理层的基本概念 物理层的作用:尽可能屏蔽掉不同传输媒体和通信手段的差异物理层规程:用于物理层的协议主要任务:确定与传输媒体的接口有关的一些特性 机械特性电器特性功能特性过程特性 数据通信的基础知识 数据通信系统的模型 划分为…...
ARM与X86架构的区别与联系
文章目录 1.什么是CPU2.复杂指令集和精简指令集3.ARM架构与X86架构的比较3.1.制造工艺3.2 64位计算3.3 异构计算3.4 功耗 4.ARM和X86的发展现状Reference 1.什么是CPU 中央处理单元(CPU)主要由运算器、控制器、寄存器三部分组成,从字面意思看…...
蓝桥杯每日一题------背包问题(二)
前言 本次讲解背包问题的一些延申问题,新的知识点主要涉及到二进制优化,单调队列优化DP,树形DP等。 多重背包 原始做法 多重背包的题意处在01背包和完全背包之间,因为对于每一个物品它规定了可选的个数,那么可以考虑…...
牛客错题整理——C语言(实时更新)
1.以下程序的运行结果是() #include <stdio.h> int main() { int sum, pad,pAd; sum pad 5; pAd sum, pAd, pad; printf("%d\n",pAd); }答案为7 由于赋值运算符的优先级高于逗号表达式,因此pAd sum, pAd, pad;等价于(…...
CIFAR-10数据集详析:使用卷积神经网络训练图像分类模型
1.数据集介绍 CIFAR-10 数据集由 10 个类的 60000 张 32x32 彩色图像组成,每类 6000 张图像。有 50000 张训练图像和 10000 张测试图像。 数据集分为5个训练批次和1个测试批次,每个批次有10000张图像。测试批次正好包含从每个类中随机选择的 1000 张图像…...
《傲剑狂刀》中的人物性格——龙吟风
在《傲剑狂刀》这款经典武侠题材的格斗游戏中,龙吟风作为一位具有传奇色彩的角色,其性格特征复杂且引人入胜。以下是对龙吟风这一角色的性格特点进行深度剖析: 一、孤高独立的剑客气质 龙吟风的名字本身就流露出一种独特的江湖气息,"吟风"象征着他的飘逸与淡泊名…...
KVM和JVM的虚拟化技术有何区别?
随着虚拟化技术的不断发展,KVM和JVM已成为两种主流的虚拟化技术。尽管它们都提供了虚拟化的解决方案,但它们在实现方式、功能和性能方面存在一些重要的差异。本文将深入探讨KVM和JVM的虚拟化技术之间的区别。 KVM(Kernel-based Virtual Mac…...
LeetCode力扣 面试经典150题 详细题解 (1~5) 持续更新中
目录 1.合并两个有序数组 2.移动元素 3.删除有序数组中的重复项 4.删除排序数组中的重复项 II 5.多数元素 暂时更新到这里,博主会持续更新的 1.合并两个有序数组 题目(难度:简单): 给你两个按 非递减顺序 排列的…...
如何解决利用cron定时任务自动更新SSL证书后Nginx重启问题
利用cron定时任务自动更新SSL证书后,用浏览器访问网站,获取到的证书仍然是之前的。原因在于没有对Nginx进行重启。 据说certbot更新完成证书后会自动重启Nginx,但显然经我检测不是这回事儿。 所以我们需要创建一bash脚本,然后定时调用这个脚…...
第一个 Angular 项目 - 静态页面
第一个 Angular 项目 - 静态页面 之前的笔记: [Angular 基础] - Angular 渲染过程 & 组件的创建 [Angular 基础] - 数据绑定(databinding) [Angular 基础] - 指令(directives) 这是在学完了上面这三个内容后能够完成的项目,目前因为还没有学到数…...
网络协议与攻击模拟_17HTTPS 协议
HTTPShttpssl/tls 1、加密算法 2、PKI(公钥基础设施) 3、证书 4、部署HTTPS服务器 部署CA证书服务器 5、分析HTTPS流量 分析TLS的交互过程 一、HTTPS协议 在http的通道上增加了安全性,传输过程通过加密和身份认证来确保传输安全性 1、TLS …...
练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...
【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...
【JVM】- 内存结构
引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...
多模态大语言模型arxiv论文略读(108)
CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...
Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...
R语言速释制剂QBD解决方案之三
本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...
搭建DNS域名解析服务器(正向解析资源文件)
正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...
Qt 事件处理中 return 的深入解析
Qt 事件处理中 return 的深入解析 在 Qt 事件处理中,return 语句的使用是另一个关键概念,它与 event->accept()/event->ignore() 密切相关但作用不同。让我们详细分析一下它们之间的关系和工作原理。 核心区别:不同层级的事件处理 方…...
uniapp 实现腾讯云IM群文件上传下载功能
UniApp 集成腾讯云IM实现群文件上传下载功能全攻略 一、功能背景与技术选型 在团队协作场景中,群文件共享是核心需求之一。本文将介绍如何基于腾讯云IMCOS,在uniapp中实现: 群内文件上传/下载文件元数据管理下载进度追踪跨平台文件预览 二…...
用鸿蒙HarmonyOS5实现中国象棋小游戏的过程
下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...
