【HTML】简单制作一个分形动画

  目录

前言

开始       

HTML部分

效果图

​编辑​编辑​编辑​编辑总结


前言

        无需多言,本文将详细介绍一段代码,具体内容如下:

开始       

        首先新建文件夹,创建一个文本文档,其中HTML的文件名改为[index.html],创建好后右键用文本文档打开,再把下面相对应代码填入后保存即可。

HTML部分

       这段HTML代码创建了一个动画线分形艺术作品,其核心特点和功能可以总结如下:

  1. 视觉风格:页面背景设置为黑色,提供了一个适合展示分形图形的暗色背景。分形的线条颜色从蓝色渐变到紫色,增加了视觉效果的丰富性。

  2. Canvas 绘图:使用<canvas>元素作为绘图区域,通过JavaScript中的2D上下文来绘制分形图形。

  3. 分形逻辑:定义了一个Shape构造函数来创建分形形状,每个形状由一系列的线段组成,并且每个形状可以递归地生成更小的子形状,以达到分形效果。

  4. 动画效果:通过animate函数实现动画效果,该函数会在每一帧更新分形图形的位置和大小,并递归生成新的形状。动画的持续时间和速度都是可配置的。

  5. 颜色变化:随着动画的进行,分形线条的颜色会逐渐变化,从一种颜色过渡到另一种颜色,增加了动态视觉效果。

  6. 响应式设计:代码中包含了事件监听器,使得当浏览器窗口大小改变时,canvas元素的尺寸也会相应地调整,确保分形图形能够适应不同的屏幕尺寸。

  7. 性能优化:为了避免在每一帧都清除整个画布,代码使用了globalCompositeOperation属性设置为"lighter",这样新绘制的形状会与画布上已有的内容进行叠加,从而提高了动画的性能。

整体而言,这段代码展示了如何在网页上使用HTML5的canvas元素和JavaScript来创建一个动态、响应式的分形艺术作品。

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>动画线分形</title>

<style>
body {
	background-color:black; /* 设置背景颜色为黑色 */
	margin:0; /* 移除默认边距 */
	overflow:hidden; /* 隐藏滚动条 */
}
</style>
</head>
<body>

<canvas id="canvas"></canvas> <!-- 定义一个canvas元素用于绘制内容 -->

<script>
// 定义黄金比例的常量
const PHI = (1 + Math.sqrt(5)) / 2; // 1.618033988749895
// 根据浏览器调整生成的分形深度
const maxGeneration = (navigator.userAgent.toLowerCase().indexOf('firefox') > -1) ? 5 : 6,
// 每帧的持续时间
frameDuration = 1000 / 60,
// 动画总时长
duration = 3000,
// 旋转速度
rotationSpeed = 0.3,
// 动画总帧数
totalIterations = Math.floor(duration / frameDuration),
// 最大基础尺寸
maxBaseSize = 100,
// 基础尺寸变化速度
baseSizeSpeed = 0.02;

// 获取canvas元素及其上下文
var canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d"),
// 获取当前视口的宽度和高度
canvasWidth = document.documentElement.clientWidth,
canvasHeight = document.documentElement.clientHeight,
// 定义一个数组用于存储分形形状
shapes = [],
// 定义尺寸变化
sizeVariation,
// 当前迭代次数
iteration = 0,
// 动画方向
animationDirection = 1,
// 尺寸变化范围
sizeVariationRange = .15,
// 基础旋转角度
baseRotation = 0,
// 基础尺寸
baseSize = 50,
// 定义颜色变化的初始值
c1 = 43,
c1S = 1,
c2 = 205,
c2S = 1,
c3 = 255,
c3S = 1;

// 设置canvas元素的尺寸以匹配视口大小
canvas.setAttribute("width", canvasWidth);
canvas.setAttribute("height", canvasHeight);

// 定义Shape构造函数,用于创建分形形状
function Shape(gen, x, y, size, rotation) {
  this.generation = gen;
  this.size = size;
  this.rotation = -rotation;
  this.start = {
    x: x,
    y: y
  };
  // 计算形状的三个端点坐标
  this.end = {
    x_1: this.start.x + Math.cos(degToRad(this.rotation)) * this.size,
    y_1: this.start.y + Math.sin(degToRad(this.rotation)) * this.size,
    x_2: this.start.x + Math.cos(degToRad(this.rotation + 360 / 3)) * this.size,
    y_2: this.start.y + Math.sin(degToRad(this.rotation + 360 / 3)) * this.size,
    x_3:
      this.start.x +
      Math.cos(degToRad(this.rotation + 360 / 3 * 2)) * this.size,
    y_3:
      this.start.y + Math.sin(degToRad(this.rotation + 360 / 3 * 2)) * this.size
  };

  // 初始化形状,生成子形状
  this.init();
}

// Shape的初始化方法
Shape.prototype.init = function() {
  if (this.generation < maxGeneration) {
    var gen = this.generation + 1,
      newSize = this.size * sizeVariation,
      newRotation = this.rotation;

    // 递归创建子形状
    shapes.push(
      new Shape(gen, this.end.x_1, this.end.y_1, newSize, newRotation)
    );
    shapes.push(
      new Shape(gen, this.end.x_2, this.end.y_2, newSize, newRotation)
    );
    shapes.push(
      new Shape(gen, this.end.x_3, this.end.y_3, newSize, newRotation)
    );
  }
  // 绘制当前形状
  this.draw();
};

// 绘制形状的方法
Shape.prototype.draw = function() {
  ctx.beginPath();
  ctx.moveTo(this.start.x, this.start.y);
  // 绘制三条线段
  ctx.lineTo(this.end.x_1, this.end.y_1);
  ctx.moveTo(this.start.x, this.start.y);
  ctx.lineTo(this.end.x_2, this.end.y_2);
  ctx.moveTo(this.start.x, this.start.y);
  ctx.lineTo(this.end.x_3, this.end.y_3);
  // 设置线条颜色,透明度随迭代次数增加而降低
  ctx.strokeStyle =
    "rgba(" + c1 + "," + c2 + "," + c3 + "," + 1 / this.generation / 5 + ")";
  ctx.stroke();
  // 填充颜色(此处被注释掉)
  //ctx.fill();
};

// 动画函数,用于更新和绘制分形
function animate() {
  // 清除画布(此处被注释掉,因为我们使用其他方法实现透明效果)
  //ctx.clearRect(0, 0, canvasWidth, canvasHeight);
  // 设置合成操作为源覆盖,以实现透明效果
  ctx.globalCompositeOperation = "source-over";
  // 用半透明的黑色填充背景,创建透明效果
  ctx.fillStyle = "rgba(0,0,0,.1)";
  ctx.fillRect(0, 0, canvasWidth, canvasHeight);
  // 恢复合成操作为lighter,用于绘制新形状
  ctx.globalCompositeOperation = "lighter";
  // 清空形状数组
  shapes = [];
  // 创建一个新的分形形状
  shapes.push(
    new Shape(0, canvasWidth / 2, canvasHeight / 2, baseSize, baseRotation)
  );

  // 改变颜色
  changeColor();
  // 增加迭代次数
  iteration++;
  // 调整基础尺寸
  if (baseSize < maxBaseSize) baseSize += baseSizeSpeed;
  // 更新基础旋转角度
  baseRotation += rotationSpeed;
  // 调整尺寸变化
  sizeVariation = easeInOutSine(
    iteration,
    1 - sizeVariationRange * animationDirection,
    sizeVariationRange * 2 * animationDirection,
    totalIterations
  );
  // 如果迭代次数达到总帧数,则重置迭代次数并反转动画方向
  if (iteration >= totalIterations) {
    iteration = 0;
    animationDirection *= -1;
  }
  // 请求下一帧动画
  requestAnimationFrame(animate);
}

// 度转弧度函数
function degToRad(deg) {
  return Math.PI / 180 * deg;
}

// 缓动函数,用于在动画中平滑变化尺寸
function easeInOutSine(
  currentIteration,
  startValue,
  changeInValue,
  totalIterations
) {
  return (
    changeInValue /
      2 *
      (1 - Math.cos(Math.PI * currentIteration / totalIterations)) +
    startValue
  );
}

// 改变颜色的函数
function changeColor() {
  if (c1 == 0 || c1 == 255) c1S *= -1;
  if (c2 == 0 || c2 == 255) c2S *= -1;
  if (c3 == 0 || c3 == 255) c3S *= -1;
  c1 += 1 * c1S;
  c2 += 1 * c2S;
  c3 += 1 * c3S;
}

// 初始化canvas的合成操作和线条颜色
ctx.globalCompositeOperation = "lighter";
animate();

// 监听窗口大小变化事件,调整canvas尺寸
window.addEventListener("resize", function() {
  canvasWidth = document.documentElement.clientWidth;
  canvasHeight = document.documentElement.clientHeight;
  // 重新设置canvas元素的尺寸
  canvas.setAttribute("width", canvasWidth);
  canvas.setAttribute("height", canvasHeight);
  // 设置线条颜色
  ctx.strokeStyle = "rgba(66,134,240,.3)";
  // 保持合成操作为lighter
  ctx.globalCompositeOperation = "lighter";
});
</script>

</body>
</html>

效果图

总结

        这段HTML代码实现了一个动态的分形艺术动画,它在网页上展示了一个基于数学分形原理的视觉图案。页面背景设置为黑色,以突出显示绘制在<canvas>元素上的分形图形。这些图形通过递归的方式生成,每个基本形状会根据预设的参数产生更小的副本,从而形成复杂的分形结构。

        动画的核心是通过JavaScript编写的,其中定义了一个Shape类,负责创建和绘制单个分形形状。每个Shape对象包含生成的代数、大小、旋转角度和端点坐标。在初始化过程中,如果当前形状的代数小于最大代数限制,它将生成三个新的子形状,这些子形状的大小会根据一个变化范围进行调整,从而产生分形的递归效果。

        动画的绘制是通过animate函数实现的,该函数会在每一帧更新所有形状的位置和大小,并根据需要递归生成新的形状。动画使用了requestAnimationFrame来平滑地进行,确保了流畅的视觉效果。为了增加视觉效果,动画中的形状颜色会随时间变化,从蓝色过渡到紫色,并在每次迭代中调整透明度,以产生深度感。

        此外,代码还考虑了不同设备的屏幕尺寸,通过监听窗口大小变化事件来动态调整<canvas>元素的尺寸,确保动画在不同设备上都能正确显示。为了提高性能,动画在绘制新形状时不会清除整个画布,而是使用"lighter"合成操作模式,让新绘制的形状与画布上已有的内容叠加,从而减少了不必要的重绘操作。

        简单来说就是通过结合HTML5的<canvas>元素和JavaScript编程,创造了一个视觉上吸引人、响应式且性能优化的分形动画作品。

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

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

相关文章

【原创教程】Smart200通过Modbus RTU实现V90位置控制的方法

1 绪论 1.1 本文的目的 S7-200Smart 可通过标准的 Modbus 功能块发送伺服驱动器的控制指令及读写驱动器的参数。本文详细叙述了 S7-200 SMART PLC 通过 Modbus RTU 通信连接 SINAMICS V90 实现内部位置的 MDI 功能。(MDI(Manual Data Input)称为设定值直接给定运行方式。…

岛屿个数c++

参考文章 岛屿个数1岛屿个数2 题目 输入样例&#xff1a; 2 5 5 01111 11001 10101 10001 11111 5 6 111111 100001 010101 100001 111111输出样例&#xff1a; 1 3样例解释 对于第一组数据&#xff0c;包含两个岛屿&#xff0c;下面用不同的数字进行了区分&#xff1a; 0…

计算机网络-TCP基础、三次挥手、四次握手过程

TCP基础 定义&#xff1a;TCP是面向连接的、可靠的、基于字节流的传输层通信协议。这意味着在发送数据之前&#xff0c;TCP需要建立连接&#xff0c;并且它能确保数据的可靠传输。此外&#xff0c;TCP将数据视为无结构的连续字节流。面向连接&#xff1a;TCP只能一对一进行连接…

Harmony与Android项目结构对比

主要文件对应 Android文件HarmonyOS文件清单文件AndroidManifest.xmlmodule.json5Activity/Fragmententryability下的ts文件XML布局pages下的ets文件resresourcesModule下的build.gradleModule下的build-profile.json5gradlehvigor根目录下的build.gradle根目录下的build-profi…

动态内存管理详解

一.为什么要存在动态内存分配&#xff1a; 下图是不同类型数据在内存中的分配&#xff1a; 上述的开辟空间的⽅式有两个特点&#xff1a; • 空间开辟⼤⼩是固定的。 • 数组在申明的时候&#xff0c;必须指定数组的⻓度&#xff0c;数组空间⼀旦确定了⼤⼩不能调整 但是对…

DeepStream做对象模糊的几种方法

有时候&#xff0c;我们需要对视频的敏感信息做模糊处理&#xff0c;比如模糊人脸&#xff0c;车牌。 有时候&#xff0c;也需要对整帧做模糊&#xff0c;或者遮挡。比如这个例子。 下面介绍几种模糊的办法。 1. 通过nvosd deepstream-test1是DeepStream最简单的一个例子&…

基于SpringBoot的“垃圾分类网站”的设计与实现(源码+数据库+文档+PPT)

基于SpringBoot的“垃圾分类网站”的设计与实现&#xff08;源码数据库文档PPT) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 系统功能结构图 系统功能界面图 用户登录、用户注…

基于java+springboot+vue实现的人事管理系统(文末源码+Lw)23-242

摘 要 使用旧方法对人事管理系统的信息进行系统化管理已经不再让人们信赖了&#xff0c;把现在的网络信息技术运用在人事管理系统的管理上面可以解决许多信息管理上面的难题&#xff0c;比如处理数据时间很长&#xff0c;数据存在错误不能及时纠正等问题。这次开发的人事管理…

时序预测 | Matlab实现SSA-ESN基于麻雀搜索算法(SSA)优化回声状态网络(ESN)的时间序列预测

时序预测 | Matlab实现SSA-ESN基于麻雀搜索算法(SSA)优化回声状态网络(ESN)的时间序列预测 目录 时序预测 | Matlab实现SSA-ESN基于麻雀搜索算法(SSA)优化回声状态网络(ESN)的时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.Matlab实现SSA-ESN基于麻雀搜索…

SQL 注入之 Windows/Docker 环境 SQLi-labs 靶场搭建!

在安全测试领域&#xff0c;SQL注入是一种常见的攻击方式&#xff0c;通过应用程序的输入执行恶意SQL查询&#xff0c;从而绕过认证和授权&#xff0c;可以窃取、篡改或破坏数据库中的数据。作为安全测试学习者&#xff0c;如果你要练习SQL注入&#xff0c;在未授权情况下直接去…

(2022级)成都工业学院数据库原理及应用实验一:CASE工具概念数据模型建模

写在前面 1、基于2022级软件工程/计算机科学与技术实验指导书 2、代码仅提供参考 3、如果代码不满足你的要求&#xff0c;请寻求其他的途径 运行环境 window11家庭版 PowerDesigner 16.1 实验要求 某医院一个门诊部排班管理子系统涉及如下信息&#xff1a; 若干科室&a…

传输大咖22|如何利用ProtoBuf实现高效的数据传输?

在今日信息技术日新月异的时代&#xff0c;数据传输的速度与安全性无疑成为了软件开发中的重中之重。无论是微服务架构下的服务间交流&#xff0c;还是客户端与服务器间的数据互动&#xff0c;寻求一种既高效又稳妥的数据传输方式已成为共识。尽管传统的数据格式&#xff0c;如…

论文复现 混淆矩阵

概念 参考视频&#xff1a; 使用pytorch和tensorflow计算分类模型的混淆矩阵_哔哩哔哩_bilibili 混淆矩阵是评判模型结果的一种指标&#xff0c;属于模型评估的一部分&#xff0c;常用于评判分类器模型的优劣。 准确率&#xff1a;所有预测正确的验证集样本个数/所有的验证集…

什么是SSL重签(reissue)?具体怎么做?

SSL重签&#xff08;reissue&#xff09;是指在SSL/TLS证书到期或需要更新时&#xff0c;证书持有者向证书颁发机构&#xff08;CA&#xff09;申请新的证书的过程。这通常是因为原有证书的有效期即将结束&#xff0c;或者证书因为某些原因&#xff08;如密钥泄露、证书损坏等&…

2024,嵌入式还适合入吗?为什么好多人劝退?

昨几天有个老铁找我&#xff0c;说买了我们的教程。 我有点奇怪&#xff0c;c语言教程我们都是送的。 聊了一会才知道&#xff0c;有人拿我送给粉丝的教程工具资料&#xff0c;到某宝上卖。 他就是买了资料&#xff0c;看我们的教程和经历&#xff0c;找到我的。 他说&#xff…

深入理解LRU缓存算法:原理、应用与优化

LRU算法&#xff08;Least Recently Used&#xff0c;最近最少使用算法&#xff09;的思想是基于"时间局部性"原理&#xff0c;即在一段时间内&#xff0c;被访问过的数据在未来仍然会被频繁访问的概率较高。 LRU 原理 LRU算法的主要思想是将最近被使用的数据保留在…

redis的三大模式的演化及集群模式思考和总结

redis的三大模式&#xff0c;也是循序渐进。 1、主从复制 比如一开始的读写分离的&#xff0c;主从复制。 一个master&#xff0c;多个slave。 master进行写和 增量同步&#xff0c;slave负责读&#xff0c;和接收增量同步的信息。 这样压力减轻。 2、哨兵模式 这个推出…

如何通过VPN访问内网?

VPN&#xff08;Virtual Private Network&#xff09;是一种通过公共网络建立私有网络连接的技术&#xff0c;可以在不同地点的网络中建立安全通道&#xff0c;实现远程访问内网资源的目的。本文将介绍如何通过VPN访问内网&#xff0c;并介绍一款名为“天联”的VPN服务。 什么是…

ASP.NET Core 标识(Identity)框架系列(一):如何使用 ASP.NET Core 标识(Identity)框架创建用户和角色?

前言 ASP.NET Core 内置的标识&#xff08;identity&#xff09;框架&#xff0c;采用的是 RBAC&#xff08;role-based access control&#xff0c;基于角色的访问控制&#xff09;策略&#xff0c;是一个用于管理用户身份验证、授权和安全性的框架。 它提供了一套工具和库&…

软件设计—接口安全设计规范

1.token授权机制 2.https传输加密 3.接口调用防滥用 4.日志审计里监控 5.开发测试环境隔离&#xff0c;脱敏处理 6.数据库运维监控审计 软件项目相关全套精华资料包获取方式①&#xff1a;点我获取 获取方式②&#xff1a;本文末个人名片直接获取。