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

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

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

生成xcframework

打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式&#xff0c;可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

k8s从入门到放弃之Ingress七层负载

k8s从入门到放弃之Ingress七层负载 在Kubernetes&#xff08;简称K8s&#xff09;中&#xff0c;Ingress是一个API对象&#xff0c;它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress&#xff0c;你可…...

【论文笔记】若干矿井粉尘检测算法概述

总的来说&#xff0c;传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度&#xff0c;通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...

C++ 基础特性深度解析

目录 引言 一、命名空间&#xff08;namespace&#xff09; C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用&#xff08;reference&#xff09;​ C 中的引用​ 与 C 语言的对比​ 四、inline&#xff08;内联函数…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序

一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)

UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中&#xff0c;UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化&#xf…...

20个超级好用的 CSS 动画库

分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码&#xff0c;而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库&#xff0c;可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画&#xff0c;可以包含在你的网页或应用项目中。 3.An…...

日常一水C

多态 言简意赅&#xff1a;就是一个对象面对同一事件时做出的不同反应 而之前的继承中说过&#xff0c;当子类和父类的函数名相同时&#xff0c;会隐藏父类的同名函数转而调用子类的同名函数&#xff0c;如果要调用父类的同名函数&#xff0c;那么就需要对父类进行引用&#…...

springboot 日志类切面,接口成功记录日志,失败不记录

springboot 日志类切面&#xff0c;接口成功记录日志&#xff0c;失败不记录 自定义一个注解方法 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;/***…...