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

用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> 标签/元素只是图形容器&#xff0c;必须使用脚本来绘制图形。 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 数据结构篇-实现红黑树的核心方法

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 红黑树的说明 2.0 红黑树的特性 3.0 红黑树的成员变量及其构造方法 4.0 实现红黑树的核心方法 4.1 红黑树内部类的核心方法 &#xff08;1&#xff09;判断当前…...

【实战】一、Jest 前端自动化测试框架基础入门(中) —— 前端要学的测试课 从Jest入门到TDD BDD双实战(二)

文章目录 一、Jest 前端自动化测试框架基础入门5.Jest 中的匹配器toBe 匹配器toEqual匹配器toBeNull匹配器toBeUndefined匹配器和toBeDefined匹配器toBeTruthy匹配器toBeFalsy匹配器数字相关的匹配器字符串相关的匹配器数组相关的匹配器异常情况的匹配器 6.Jest 命令行工具的使…...

【C语言 - 力扣 - 反转链表】

反转链表题目描述 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 题解1-迭代 假设链表为 1→2→3→∅&#xff0c;我们想要把它改成 ∅←1←2←3。 在遍历链表时&#xff0c;将当前节点的 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只做拓展&#xff0c;可跳过。 PartOne introduction 首先要对于python这门语言有一个宏观的认识&#xff0c;包括特点和应用场景。 特点分析&#xff1a; 优势 提供了完善的基础代码库&#xff0c;许多功能不必从零编写简单优雅 劣势 运…...

Idea里自定义封装数据警告解决 Spring Boot Configuration Annotation Processor not configured

我们自定对象封装指定数据&#xff0c;封装类上面一个红色警告&#xff0c;虽然不影响我们的执行&#xff0c;但是有强迫症看着不舒服&#xff0c; 去除方式&#xff1a; 在pom文件加上坐标刷新 <dependency><groupId>org.springframework.boot</groupId><…...

【流程图——讲解】

流程图介绍 流程图介绍 流程图介绍 流程图是一种图表&#xff0c;它展示了工作流程或过程中的步骤顺序&#xff0c;它通常由不同的符号表示&#xff0c;每个符号都代表一个步骤或过程中的一个元素&#xff0c;流程图非常有用&#xff0c;因为它们可以提供清晰、视觉化的过程表…...

「计算机网络」物理层

物理层的基本概念 物理层的作用&#xff1a;尽可能屏蔽掉不同传输媒体和通信手段的差异物理层规程&#xff1a;用于物理层的协议主要任务&#xff1a;确定与传输媒体的接口有关的一些特性 机械特性电器特性功能特性过程特性 数据通信的基础知识 数据通信系统的模型 划分为…...

ARM与X86架构的区别与联系

文章目录 1.什么是CPU2.复杂指令集和精简指令集3.ARM架构与X86架构的比较3.1.制造工艺3.2 64位计算3.3 异构计算3.4 功耗 4.ARM和X86的发展现状Reference 1.什么是CPU 中央处理单元&#xff08;CPU&#xff09;主要由运算器、控制器、寄存器三部分组成&#xff0c;从字面意思看…...

蓝桥杯每日一题------背包问题(二)

前言 本次讲解背包问题的一些延申问题&#xff0c;新的知识点主要涉及到二进制优化&#xff0c;单调队列优化DP&#xff0c;树形DP等。 多重背包 原始做法 多重背包的题意处在01背包和完全背包之间&#xff0c;因为对于每一个物品它规定了可选的个数&#xff0c;那么可以考虑…...

牛客错题整理——C语言(实时更新)

1.以下程序的运行结果是&#xff08;&#xff09; #include <stdio.h> int main() { int sum, pad,pAd; sum pad 5; pAd sum, pAd, pad; printf("%d\n",pAd); }答案为7 由于赋值运算符的优先级高于逗号表达式&#xff0c;因此pAd sum, pAd, pad;等价于(…...

CIFAR-10数据集详析:使用卷积神经网络训练图像分类模型

1.数据集介绍 CIFAR-10 数据集由 10 个类的 60000 张 32x32 彩色图像组成&#xff0c;每类 6000 张图像。有 50000 张训练图像和 10000 张测试图像。 数据集分为5个训练批次和1个测试批次&#xff0c;每个批次有10000张图像。测试批次正好包含从每个类中随机选择的 1000 张图像…...

《傲剑狂刀》中的人物性格——龙吟风

在《傲剑狂刀》这款经典武侠题材的格斗游戏中,龙吟风作为一位具有传奇色彩的角色,其性格特征复杂且引人入胜。以下是对龙吟风这一角色的性格特点进行深度剖析: 一、孤高独立的剑客气质 龙吟风的名字本身就流露出一种独特的江湖气息,"吟风"象征着他的飘逸与淡泊名…...

KVM和JVM的虚拟化技术有何区别?

随着虚拟化技术的不断发展&#xff0c;KVM和JVM已成为两种主流的虚拟化技术。尽管它们都提供了虚拟化的解决方案&#xff0c;但它们在实现方式、功能和性能方面存在一些重要的差异。本文将深入探讨KVM和JVM的虚拟化技术之间的区别。 KVM&#xff08;Kernel-based Virtual Mac…...

LeetCode力扣 面试经典150题 详细题解 (1~5) 持续更新中

目录 1.合并两个有序数组 2.移动元素 3.删除有序数组中的重复项 4.删除排序数组中的重复项 II 5.多数元素 暂时更新到这里&#xff0c;博主会持续更新的 1.合并两个有序数组 题目&#xff08;难度&#xff1a;简单&#xff09;&#xff1a; 给你两个按 非递减顺序 排列的…...

如何解决利用cron定时任务自动更新SSL证书后Nginx重启问题

利用cron定时任务自动更新SSL证书后&#xff0c;用浏览器访问网站&#xff0c;获取到的证书仍然是之前的。原因在于没有对Nginx进行重启。 据说certbot更新完成证书后会自动重启Nginx,但显然经我检测不是这回事儿。 所以我们需要创建一bash脚本&#xff0c;然后定时调用这个脚…...

第一个 Angular 项目 - 静态页面

第一个 Angular 项目 - 静态页面 之前的笔记&#xff1a; [Angular 基础] - Angular 渲染过程 & 组件的创建 [Angular 基础] - 数据绑定(databinding) [Angular 基础] - 指令(directives) 这是在学完了上面这三个内容后能够完成的项目&#xff0c;目前因为还没有学到数…...

网络协议与攻击模拟_17HTTPS 协议

HTTPShttpssl/tls 1、加密算法 2、PKI&#xff08;公钥基础设施&#xff09; 3、证书 4、部署HTTPS服务器 部署CA证书服务器 5、分析HTTPS流量 分析TLS的交互过程 一、HTTPS协议 在http的通道上增加了安全性&#xff0c;传输过程通过加密和身份认证来确保传输安全性 1、TLS …...

SNOMED CT入门指南:从概念、关系到数据文件,手把手带你理解这个医学术语标准

SNOMED CT技术解析&#xff1a;从数据结构到医疗信息系统的实战指南 在医疗信息化领域&#xff0c;数据标准化是打破信息孤岛的关键。当不同医院的电子病历系统使用各自独立的术语体系时&#xff0c;跨机构的数据交换就像一场没有翻译的多国会议——充满误解和低效。这正是SNOM…...

拓扑排序不止于理论:用邻接矩阵实现时,我踩过的3个坑和性能优化

拓扑排序实战&#xff1a;邻接矩阵实现中的性能陷阱与优化策略 邻接矩阵作为图论中最直观的存储结构&#xff0c;常被初学者用来实现拓扑排序算法。但当我们真正将其投入实际项目时&#xff0c;往往会遭遇意想不到的性能瓶颈和逻辑陷阱。本文将分享三个真实项目中踩过的坑&…...

高效解决Magpie插件更新难题:完全掌握图像增强功能升级指南

高效解决Magpie插件更新难题&#xff1a;完全掌握图像增强功能升级指南 【免费下载链接】Magpie An all-purpose window upscaler for Windows 10/11. 项目地址: https://gitcode.com/gh_mirrors/mag/Magpie 识别插件更新需求&#xff1a;为何及时升级至关重要 在使用M…...

技术小白AI入门避坑指南:避开4大雷区,高效进阶不走弯路

技术小白AI入门避坑指南&#xff1a;避开4大雷区&#xff0c;高效进阶不走弯路 前言&#xff1a;作为技术小白&#xff0c;入门AI的路上&#xff0c;最可怕的不是“基础薄弱”&#xff0c;而是“走偏方向”——明明付出了时间和精力&#xff0c;却因为踩中误区&#xff0c;要么…...

单片机I/O口阻抗特性及其在电路设计中的关键作用

1. 阻抗基础&#xff1a;从水管到电路的理解 第一次接触阻抗概念时&#xff0c;我盯着教科书上的公式发呆了半小时。直到有天修水管时突然开窍——这不就是水管的粗细对水流的影响吗&#xff1f;在电路中&#xff0c;阻抗就是电子流动遇到的"阻力"。但和水管不同&…...

LLVM指令调度实战:如何用llvm-mca优化AArch64代码性能(附TSV110配置示例)

LLVM指令调度实战&#xff1a;如何用llvm-mca优化AArch64代码性能&#xff08;附TSV110配置示例&#xff09; 在ARM架构的性能优化领域&#xff0c;指令调度质量直接影响着关键计算任务的吞吐量。本文将带您深入llvm-mca工具链的实际应用&#xff0c;通过TSV110处理器的具体案例…...

终极OBS Studio直播软件指南:5步打造专业级智能直播系统

终极OBS Studio直播软件指南&#xff1a;5步打造专业级智能直播系统 【免费下载链接】obs-studio OBS Studio - 用于直播和屏幕录制的免费开源软件。 项目地址: https://gitcode.com/GitHub_Trending/ob/obs-studio 想象一下这样的场景&#xff1a;你正在直播一场重要的…...

从“机器会思考”的执念说起,聊聊神经网络到底是个啥(下篇)

一、神经网络的类型&#xff1a;别被名字搞晕&#xff0c;核心就几种 现在叫“神经网络”的东西五花八门&#xff0c;但绝大多数都是从下面这几类衍生出去的。 1. 前馈神经网络&#xff08;FNN&#xff09;—— 最朴素的直筒子 数据从输入层进&#xff0c;经过若干隐藏层&am…...

企业级AD域控+FreeRADIUS认证实战:从零配置PAP/MSCHAPv2完整流程

企业级AD域控与FreeRADIUS深度集成&#xff1a;PAP与MSCHAPv2认证全流程解析 在企业混合IT环境中&#xff0c;如何实现Windows Active Directory&#xff08;AD&#xff09;域账户与Linux系统的无缝认证一直是运维团队的痛点。本文将手把手带你完成AD域控与FreeRADIUS的深度集成…...

从图片预览需求看H5监听浏览器返回事件的3种实现方案(含history API避坑指南)

从图片预览需求看H5监听浏览器返回事件的3种实现方案&#xff08;含history API避坑指南&#xff09; 在移动端H5开发中&#xff0c;图片预览功能几乎是标配需求。随着全面屏手势操作的普及&#xff0c;用户越来越习惯通过滑动返回退出预览&#xff0c;而非点击关闭按钮。这种交…...