用HTML5 + JavaScript绘制花、树

用HTML5 + JavaScript绘制花、树

<canvas>是一个可以使用脚本 (通常为JavaScript) 来绘制图形的 HTML 元素。

<canvas> 标签/元素只是图形容器,必须使用脚本来绘制图形。

HTML5 canvas 图形标签基础https://blog.csdn.net/cnds123/article/details/112916903

下面展示了如何使用 HTML5 的 <canvas> 标签/元素以及 JavaScript 来绘制花、树等效果。

一、画花

花1、先给出运行效果图:

源码如下:

html 复制代码
<!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、先给出运行效果图:

源码如下:

html 复制代码
<!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 **、**先给出运行效果图:

源码如下:

html 复制代码
<!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,添加花朵。先给出运行效果图:

源码如下:

html 复制代码
<!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

相关推荐
真的很上进4 小时前
如何借助 Babel+TS+ESLint 构建现代 JS 工程环境?
java·前端·javascript·css·react.js·vue·html
噢,我明白了8 小时前
同源策略:为什么XMLHttpRequest不能跨域请求资源?
javascript·跨域
sanguine__8 小时前
APIs-day2
javascript·css·css3
关你西红柿子8 小时前
小程序app封装公用顶部筛选区uv-drop-down
前端·javascript·vue.js·小程序·uv
济南小草根9 小时前
把一个Vue项目的页面打包后再另一个项目中使用
前端·javascript·vue.js
小木_.9 小时前
【python 逆向分析某有道翻译】分析有道翻译公开的密文内容,webpack类型,全程扣代码,最后实现接口调用翻译,仅供学习参考
javascript·python·学习·webpack·分享·逆向分析
Aphasia3119 小时前
一次搞懂 JS 对象转换,从此告别类型错误!
javascript·面试
m0_748256569 小时前
Vue - axios的使用
前端·javascript·vue.js
m0_7482563410 小时前
QWebChannel实现与JS的交互
java·javascript·交互
胡西风_foxww10 小时前
【es6复习笔记】函数参数的默认值(6)
javascript·笔记·es6·参数·函数·默认值