用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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/384746.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

opencv 图像色彩空间转化

今天看了b站贾志刚的课&#xff0c;觉得不错&#xff0c;特地做学习笔记来和小伙伴分享 贾志刚的这个好像是2.0版本,30小时的,语言更加精炼,适合初级入门学习 第一节是常规安装 看他的步骤装就行了,记得配置完点应用再点确定,我第一次就是 没点然后就失败了,又得重配置一次…

服务网格(Service Mesh)流行工具

在这篇博客中&#xff0c;我们将介绍微服务的最佳服务网格工具列表&#xff0c;这些工具提供安全性、金丝雀部署、遥测、负载均衡等。 用于部署和操作微服务的服务网格工具的数量不断增加。在这篇文章中&#xff0c;我们将探讨您应该用来构建自己的服务网格架构的顶级服务网格…

视觉开发板—K210自学笔记(五)

本期我们来遵循其他单片机的学习路线开始去用板子上的按键控制点亮LED。那么第一步还是先知道K210里面的硬件电路是怎么连接的&#xff0c;需要查看第二节的文档&#xff0c;看看开发板原理图到底是按键是跟哪个IO连在一起。然后再建立输入按键和GPIO的映射就可以开始变成了。 …

PHP特性知识点总结

description: 专门出的关于php的特性比较,后面好像也有java的特性。 大家直接去我的gitbook或者github看就能看到图片,这里就懒得把他弄到csdn上了。 这里放github和gitbook的链接,大家跳转就可以。gitbook链接用国内的网就能访问。 gitbook: http://22kaka.fun github:htt…

STM32 + ESP8266,连接阿里云 上报/订阅数据

&#xff08;文章正在编辑中&#xff0c;一点点地截图操作过程&#xff0c;估计要拖拉两三天&#xff09; 一、烧录MQTT固件 ESP8266出厂时&#xff0c;默认是AT固件。连接阿里云&#xff0c;需要使用MQTT固件。 1、独立EPS8266模块的烧录方法 2、魔女开发板&#xff0c;板载…

HTTP协议-请求Request

前言&#xff1a; 序列&#xff1a;HTTP - 002 1.请求格式 1.1标椎格式 HTTP请求是字符串的格式传输&#xff0c;具体包含以下四部分&#xff1a; 首行&#xff1a;[方法][url][版本号]&#xff0c;分别使用空格分隔&#xff1b;请求头&#xff08;Header&#xff09;&#…

apk反编译修改教程系列---简单修改apk默认横竖屏显示 手机端与电脑端同步演示【十一】

往期教程&#xff1a; apk反编译修改教程系列-----修改apk应用名称 任意修改名称 签名【一】 apk反编译修改教程系列-----任意修改apk版本号 版本名 防止自动更新【二】 apk反编译修改教程系列-----修改apk中的图片 任意更换apk桌面图片【三】 apk反编译修改教程系列---简单…

《UE5_C++多人TPS完整教程》学习笔记8 ——《P9 访问 Steam(Acessing Steam)》

本文为B站系列教学视频 《UE5_C多人TPS完整教程》 —— 《P9 访问 Steam&#xff08;Acessing Steam&#xff09;》 的学习笔记&#xff0c;该系列教学视频为 Udemy 课程 《Unreal Engine 5 C Multiplayer Shooter》 的中文字幕翻译版&#xff0c;UP主&#xff08;也是译者&…

[JavaWeb玩耍日记]Maven的安装与使用

目录 一.作用 二.安装 三.使用 2.对项目使用compile命令进行编译,看看新的文件会在哪里产生&#xff1f; 3.需要认识的命令 4.Maven对项目执行不同命令的生命周期特点&#xff1f; 5.如何导入工程外的Maven&#xff1f; 6.如何直观地查看Maven导入了哪些工程或哪些jar包…

Stream流学习笔记

Stream流 创建流中间操作1、filter2、map3、distinct4、sorted5、limit6、skip7、flatMap 终结操作1、forEach2、count3、max&min4、collect5、查找与匹配 创建流 单例集合&#xff1a;集合对象.stream() List<Integer> list new ArrayList<>(); Stream<…

前端JavaScript篇之Promise解决了什么问题、Promise.all和Promise.race的区别的使用场景

目录 Promise解决了什么问题Promise.all和Promise.race的区别的使用场景 Promise解决了什么问题 Promise 解决了 JavaScript 中回调地狱的问题。在传统的回调函数中&#xff0c;如果需要依次执行多个异步操作&#xff0c;就需要使用嵌套的回调函数&#xff0c;这样会导致代码难…

如何学习VBA_3.2.14:VBA中字符串的处理和判断函数

我给VBA的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高自己的劳动效率&#xff0c;而且可以提高数据处理的准确度。我推出的VBA系列教程共九套和一部VBA汉英手册&#xff0c;现在已经全部完成&#xff0c;希望大家利用、学习。 如果…

EasyCaptcha,开源图形验证码新标杆!

引言&#xff1a; 随着互联网的普及&#xff0c;验证码已成为网站和应用程序中不可或缺的安全组件。它能够有效地防止自动化攻击、垃圾邮件和机器人活动。在众多验证码解决方案中&#xff0c;Easy-captcha以其简单易用和高度可定制的特点受到了开发者的青睐。本文将指导读者如…

leetcode:买卖股票最佳时机二

思路&#xff1a; 使用贪心算法&#xff1a;局部最优是将买卖过程中产生的正数进行相加&#xff0c;进而使得最后结果最大&#xff08;全局最优&#xff09;。 price [7,1,5,10,3,6,4] -6,4,5,-7,3,-2 正数相加就得到了最大 代码实现&#xff1a; 1.循环中下标从1开始 …

unity2017 遇到visual studio 2017(社区版) 30日试用期到了

安装unity2017 遇到visual studio 2017 30日试用期到了&#xff0c;网上百度搜了好多方法都没有成功。 最后用了这个方法&#xff1a; 1)启动vs2017&#xff0c;在弹出要登录的窗口之前&#xff0c;迅速的点击工具-》选项-》账户&#xff0c;勾选在添加账户或对账户重新进行身…

【技巧】Allegro实用技巧之模块复用

需求分析&#xff1a;使用Allegro软件进行PCB Layout设计时&#xff0c;当电路图中有很多路相同的模块&#xff0c;使用模块复用的的操作方法&#xff0c;可以显著提高工作效率&#xff0c;同时也可以使PCB布局在整体上显得美观。下面来讲述这个方法。 具体方法及说明&#xf…

计算机组成原理 1 概论

主要内容 介绍运算器、控制器、存储器结构、工作原理、设计方法及互连构成整机的技术。 主要内容&#xff1a; ◼ 数值表示与运算方法 ◼ 运算器的功能、组成和基本运行原理 ◼ 存储器及层次存储系统 ◼ 指令系统 ◼ CPU功能、组成和运行原理 ◼ 流水线 ◼ 系统总线 ◼ 输入输出…

【蓝桥杯选拔赛真题34】C++最大值 第十三届蓝桥杯青少年创意编程大赛C++编程选拔赛真题解析

目录 C/C最大值 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 七、推荐资料 C/C最大值 第十三届蓝桥杯青少年创意编程大赛C选拔赛真题 一、题目要求 1、编程实现&#xff08;C&#xff09; 给定一个…

C# WinFrom+AspNetCore WebApi实现大文件下载与上传

客户端UI: 服务端WebApi: 客户端代码&#xff1a; App.config&#xff1a; <?xml version"1.0" encoding"utf-8" ?> <configuration><appSettings><add key"WebApi" value"https://localhost:7285"/><…