【HTML】制作一个简单的线性动画

 目录

前言

HTML部分

CSS部分

JS部分

效果图

总结


前言

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

开始

        首先新建文件夹,创建一个文本文档,两个文件夹,其中HTML的文件名改为[index.html];CSS的文件名改为[css],里面新建一个文本文档重命名为[normalize.min.css];JS的文件名改为[js],里面新建两个文本文档,分别重命名为 [script.js] [simplex-noise.min.js],创建好后右键用文本文档打开,再把下面相对应代码填入后保存即可。

HTML部分

        这段HTML代码定义了一个基本的网页结构,包括了必要的文档类型声明、网页头部(head)和主体(body)部分。具体来说:

  1. <!DOCTYPE html>: 这是HTML5文档的声明,用于告诉浏览器这是一个HTML5文档。

  2. <html lang="en">: 根元素,定义了整个HTML文档,并设置页面的语言为英语。

  3. <head>: 包含了文档的元数据,不影响页面的可见内容,但对搜索引擎优化(SEO)和页面表现很重要。

    • <meta charset="UTF-8">: 设置字符编码为UTF-8,这是一种广泛使用的国际字符编码,可以显示几乎所有语言的字符。
    • <title>雷神Leo</title>: 设置了浏览器标签页上显示的标题,这里是“雷神Leo”。
    • <link rel="stylesheet" href="css/normalize.min.css">: 引入了一个外部CSS文件,用于样式重置和标准化不同浏览器间的默认样式差异,以确保网页的一致性。
  4. <body>: 包含了网页的所有可见内容。

    • <script src='js/simplex-noise.min.js'></script>: 引入了一个JavaScript库,用于生成简单的噪声效果,常用于创建视觉效果。
    • <script src="js/script.js"></script>: 引入了网页的主要JavaScript文件,负责处理网页的行为和交互逻辑。

        这个网页模板是一个起点,开发者可以在此基础上添加更多的HTML元素、CSS样式和JavaScript代码,以创建具有丰富功能和吸引人设计的网页。需要注意的是,实际使用时,需要确保外部文件路径正确,并编写相应的CSS和JavaScript代码来实现所需的功能。

<!DOCTYPE html> <!-- 声明文档类型为HTML5 -->
<html lang="en" ><!-- 根元素,设置语言为英语 -->
<head><meta charset="UTF-8"> <!-- 设置字符编码为UTF-8,确保网页正确显示多语言字符 --><title>雷神Leo</title> <!-- 网页标题,将显示在浏览器标签页上 --><!-- 引入外部CSS样式表,用于网页的样式布局 --><link rel="stylesheet" href="css/normalize.min.css">
</head>
<body><!-- 页面的主体内容将会放在这里 --><!-- 引入外部JavaScript文件,用于网页的行为和动态效果 --><script src='js/simplex-noise.min.js'></script><script src="js/script.js"></script>
</body>
</html>

CSS部分

        这段代码是一个CSS样式表的一部分,主要使用了Normalize.css,它是一个用于网页的CSS库,旨在创建一个更平滑的用户体验,同时保持不同浏览器和设备之间的一致性。以下是对这段代码的总结和注释:

  1. button,hr,input{overflow:visible}: 设置按钮、水平规则线(hr)和输入框的溢出内容为可见,以确保这些元素的溢出内容不会影响布局。

  2. audio,canvas,progress,video{display:inline-block}: 将音频、画布、进度条和视频等元素设置为内联块状元素,使它们既能像内联元素一样参与文本流,又能设置宽高。

  3. progress,sub,sup{vertical-align:baseline}: 设置进度条、下标和上标元素的垂直对齐方式为基线对齐,以确保它们与文本的基线对齐。

  4. html{font-family:sans-serif;line-height:1.15;...}: 设置默认的字体系列为无衬线字体,并设置行高为1.15倍,同时禁用了一些浏览器的默认文本大小调整功能。

  5. body{margin:0}: 设置页面主体的默认外边距为0,以避免浏览器的默认边距影响布局。

  6. menu,article,aside,...{display:block}: 将一些HTML5新增的语义化元素设置为块状元素,确保它们占据一整行。

  7. h1{font-size:2em;margin:.67em 0}: 设置一级标题的字体大小为2em,并设置上下外边距。

  8. figcaption,figure,main{display:block}: 设置图题、图形和主要内容区域为块状元素。

  9. hr{box-sizing:content-box;height:0}: 设置水平规则线的盒模型为内容盒模型,并将其高度设置为0。

  10. code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}: 设置代码、键盘输入、预格式化文本和样本文本的字体为等宽字体,并设置字体大小为1em。

  11. a{background-color:transparent;...}: 设置超链接的背景颜色为透明,并禁用了一些浏览器的默认文本装饰。

  12. abbr[title]{...}: 设置有标题属性的缩写词的文本装饰为下划线点状,以提供解释性的文本。

  13. b,strong{font-weight:bolder}: 设置加粗文本的字体权重更强。

  14. small{font-size:80%}: 设置小号文字的字体大小为80%。

  15. sub,sup{...}: 设置下标和上标的字体大小为75%,并设置行高为0,以及它们的相对位置。

  16. audio:not([controls]){...}: 隐藏没有控件的音频元素。

  17. img{border-style:none}: 设置图片的边框样式为无。

  18. button,input,...{...}: 设置一系列表单元素的字体系列、大小、外边距等。

  19. fieldset{border:1px solid silver...}: 设置字段集的边框样式、间距和填充。

  20. legend{...}: 设置图例的盒模型、颜色、显示方式和白空间。

  21. progress{}textarea{overflow:auto}: 为进度条和文本区域设置样式。

  22. [type=checkbox],...{...}: 设置复选框、单选按钮等表单元素的盒模型和样式。

  23. summary{display:list-item}: 设置摘要元素的显示方式为列表项。

  24. [hidden],template{display:none}: 隐藏隐藏元素和模板元素。

        最后,/*# sourceMappingURL=normalize.min.css.map */ 是一个注释,用于指示这个CSS文件的源映射文件的位置,便于开发者调试。

        这段代码的目的是为网页提供一个统一的样式基础,减少浏览器之间的默认样式差异,使得开发者可以更轻松地创建一致且易于维护的网页。

button,hr,input{overflow:visible}audio,canvas,progress,video{display:inline-block}progress,sub,sup{vertical-align:baseline}html{font-family:sans-serif;line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0} menu,article,aside,details,footer,header,nav,section{display:block}h1{font-size:2em;margin:.67em 0}figcaption,figure,main{display:block}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}a{background-color:transparent;-webkit-text-decoration-skip:objects}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}dfn{font-style:italic}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}audio:not([controls]){display:none;height:0}img{border-style:none}svg:not(:root){overflow:hidden}button,input,optgroup,select,textarea{font-family:sans-serif;font-size:100%;line-height:1.15;margin:0}button,input{}button,select{text-transform:none}[type=submit], [type=reset],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:ButtonText dotted 1px}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}[hidden],template{display:none}/*# sourceMappingURL=normalize.min.css.map */

JS部分

[script.js]

        这段代码定义了几个类,用于生成随机数、颜色、处理向量运算、碰撞检测、计时、动画定时以及绘制分形图形。

  1. Utils 类提供了一些静态方法,用于生成随机数、随机颜色值和渐变颜色。还包括一个计算当前帧率(FPS)的方法。

  2. Vector2d 类表示二维向量,提供了一系列方法来执行向量运算,如缩放、加法、减法、取反、归一化、旋转和转换为字符串表示。

  3. Collision 类用于处理对象之间的碰撞检测和碰撞反弹。它提供了一个 collideAll 方法来检查所有对象对之间的碰撞,并调用 bounce 方法来处理碰撞反弹。

  4. Stopwatch 类用于计时,提供了开始、停止、获取经过时间、检查是否正在运行和重置计时器的方法。

  5. AnimationTimer 类用于动画定时,它可以创建一个基于时间的动画效果,支持不同的缓动函数,如Ease-In、Ease-Out、Ease-In-Out、Elastic和Bounce。还包括一个线性缓动函数和一个方法来检查动画是否完成。

  6. Angle 类用于表示角度,可以增加或减少角度值,并将角度值转换为弧度。

  7. Canvas 类用于创建和管理分形图形的绘制。它提供了初始化、渲染、绘制帧率和响应窗口大小变化的方法。

  8. PointObj 类表示一个二维点,包含 x 和 y 坐标。

  9. FractalRoot 类用于生成分形的根节点,它初始化分形的结构并绘制形状。

  10. Branch 类表示分形中的一个分支,它负责计算分支的中间点、结构点,并绘制分支。

        最后,代码中的自执行函数用于初始化 Canvas 类,并设置窗口大小变化的事件监听器,以确保画布随着浏览器窗口的变化而调整大小。整个代码展示了一个分形动画的生成和渲染过程,包括碰撞检测和帧率显示。

class Utils {static randomNumber(min, max) {return Math.floor(Math.random() * (max - min + 1) + min);}static randomColorRGB() {return ("rgb(" +this.randomNumber(0, 255) +", " +this.randomNumber(0, 255) +", " +this.randomNumber(0, 255) +")");}static randomColorHSL(hue, saturation, lightness) {return ("hsl(" +hue +", " +saturation +"%, " +lightness +"%)");}static gradientColor(ctx, cr, cg, cb, ca, x, y, r) {const col = cr + "," + cg + "," + cb;const g = ctx.createRadialGradient(x, y, 0, x, y, r);g.addColorStop(0, "rgba(" + col + ", " + (ca * 1) + ")");g.addColorStop(0.5, "rgba(" + col + ", " + (ca * 0.5) + ")");g.addColorStop(1, "rgba(" + col + ", " + (ca * 0) + ")");return g;}static calcFPS() {const now = (+new Date());const fps = 1000 / (now - lastTime);lastTime = now;return fps.toFixed();}
}class Vector2d {constructor(x, y) {this.vx = x;this.vy = y;}scale(scale) {this.vx *= scale;this.vy *= scale;}add(vec2) {this.vx += vec2.vx;this.vy += vec2.vy}sub(vec2) {this.vx -= vec2.vx;this.vy -= vec2.vy;}negate() {this.vx = -this.vx;this.vy = -this.vy;}length() {return Math.sqrt(this.vx * this.vx + this.vy * this.vy);}lengthSquared() {return this.vx * this.vx + this.vy * this.vy;}normalize() {let len = Math.sqrt(this.vx * this.vx + this.vy * this.vy);if (len) {this.vx /= len;this.vy /= len;}return len;}rotate(angle) {let vx = this.vx;let vy = this.vy;let cosVal = Math.cos(angle);let sinVal = Math.sin(angle);this.vx = vx * cosVal - vy * sinVal;this.vy = vx * sinVal + vy * cosVal;}toString() {return '(' + this.vx.toFixed(3) + ',' + this.vy.toFixed(3) + ')';}
}class Collision {constructor(targetArr) {this.arr = targetArr;}collideAll() {let vec = new Vector2d(0, 0);let dist;let obj1;let obj2;let c;let i;for (c = 0; c < this.arr.length; c++) {obj1 = this.arr[c];for (i = c + 1; i < this.arr.length; i++) {obj2 = this.arr[i];vec.vx = obj2.x - obj1.x;vec.vy = obj2.y - obj1.y;dist = vec.length();if (dist < obj1.r + obj2.r) {vec.normalize();vec.scale(obj1.r + obj2.r - dist);vec.negate();obj1.x += vec.vx;obj1.y += vec.vy;this.bounce(obj1, obj2);}}}}bounce(obj1, obj2) {let colnAngle = Math.atan2(obj1.y - obj2.y, obj1.x - obj2.x);let length1 = obj1.v.length();let length2 = obj2.v.length();let dirAngle1 = Math.atan2(obj1.v.vy, obj1.v.vx);let dirAngle2 = Math.atan2(obj2.v.vy, obj2.v.vx);let newVX1 = length1 * Math.cos(dirAngle1 - colnAngle);let newVX2 = length2 * Math.cos(dirAngle2 - colnAngle);obj1.v.vy = length1 * Math.sin(dirAngle1 - colnAngle);obj2.v.vy = length2 * Math.sin(dirAngle2 - colnAngle);obj1.v.vx = ((obj1.r - obj2.r) * newVX1 + (2 * obj2.r) * newVX2) / (obj1.r + obj2.r);obj2.v.vx = ((obj2.r - obj1.r) * newVX2 + (2 * obj1.r) * newVX1) / (obj1.r + obj2.r);obj1.v.rotate(colnAngle);obj2.v.rotate(colnAngle);}
}class Stopwatch {constructor(time) {this.startTime = 0;this.running = false;this.elapsed = undefined;}start() {this.startTime = +new Date();this.elapsedTime = null;this.running = true;}stop() {this.elapsed = (+new Date()) - this.startTime;this.running = false;}getElapsedTime() {if (this.running) {return (+new Date()) - this.startTime;} else {return this.elapsed;}}isRunning() {return this.running;}reset() {this.elapsed = 0;}
}class AnimationTimer {constructor(duration, timeWarp) {if (duration !== undefined) this.duration = duration;if (timeWarp !== undefined) this.timeWarp = timeWarp;this.stopwatch = new Stopwatch();}start() {this.stopwatch.start();}stop() {this.stopwatch.stop();}getElapsedTime() {const elapsedTime = this.stopwatch.getElapsedTime();const percentComplete = elapsedTime / this.duration;if (!this.stopwatch.running) return undefined;if (this.timeWarp === undefined) return elapsedTime;return elapsedTime * (this.timeWarp(percentComplete) / percentComplete);}isRunning() {return this.stopwatch.running;}isOver() {return this.stopwatch.getElapsedTime() > this.duration;}makeEaseIn(strength) {return function(percentComplete) {return Math.pow(percentComplete, strength * 2);}}makeEaseOut(strength) {return function(percentComplete) {return 1 - Math.pow(1 - percentComplete, strength * 2);}}makeEaseInOut() {return function(percentComplete) {return percentComplete - Math.sin(percentComplete * 2 * Math.PI) / (2 * Math.PI);}}makeElastic(passes) {passes = passes || default_elastic_passes;return function(percentComplete) {return ((1 - Math.cos(percentComplete * Math.PI * passes)) * (1 - percentComplete)) + percentComplete;}}makeBounce(bounces) {const fn = this.makeElastic(bounces);return function(percentComplete) {percentComplete = fn(percentComplete);return percentComplete <= 1 ? percentComplete : 2 - percentComplete;}}makeLinear() {return function(percentComplete) {return percentComplete;}}
}class Angle {constructor(angle) {this.a = angle;this.rad = this.a * Math.PI / 180;}incDec(num) {this.a += num;this.rad = this.a * Math.PI / 180;return this.rad;}
}let canvas;let lastTime = 0;const simplex = new SimplexNoise();class Canvas {constructor(bool) {this.canvas = document.createElement("canvas");if (bool === true) {this.canvas.style.position = 'relative';this.canvas.style.display = 'block';this.canvas.style.backgroundColor = 'black';this.canvas.style.top = '0';this.canvas.style.left = '0';document.getElementsByTagName("body")[0].appendChild(this.canvas);}this.ctx = this.canvas.getContext("2d");this.width = this.canvas.width = window.innerWidth;this.height = this.canvas.height = window.innerHeight;this.mouseX = null;this.mouseY = null;this.mouseZ = null;this.number_of_shapes = 5;this.shapes_array = [];}init() {for (let i = 0; i < this.number_of_shapes; i++) {const f = new FractalRoot(this.ctx, this.width / 2, this.height / 2, i);this.shapes_array.push(f);}}render() {if (Math.random() < 0.001) this.ctx.clearRect(0, 0, this.width, this.height);for (let i = 0; i < this.shapes_array.length; i++) {this.shapes_array[i].drawShape();}window.requestAnimationFrame(() => {this.render();});}drawFPS() {const ctx = this.ctx;ctx.save();ctx.fillStyle = 'white';ctx.font = '16px sans-serif';ctx.textAlign = 'right';ctx.textBaseline = 'bottom';ctx.fillText(Utils.calcFPS() + ' FPS', this.width, this.height);ctx.restore();}resize() {this.shapes_array = [];this.width = this.canvas.width = window.innerWidth;this.height = this.canvas.height = window.innerHeight;this.init();}
}class PointObj {constructor(ex, ey) {this.x = ex;this.y = ey;}
}class FractalRoot {constructor(ctx, x, y, i) {this.random = Math.random();this.ctx = ctx;this.x = x;this.y = y;this.i = i;this.a = 0;this.r = 100;this.ri = this.r;this.maxLevels = 4;this.structFactor = null;this.rootBranch = null;this.numSlides = 5;this.pointArr = new Array(this.numSlides);this.angleStep = 360 / this.numSlides;this.init();}init(time, noise) {let count = 0;for (let i = 0; i < 360; i += this.angleStep) {let x = this.x + (this.r * Math.cos((this.a + i) * Math.PI / 180));let y = this.y + (this.r * Math.sin((this.a + i) * Math.PI / 180));this.pointArr[count] = new PointObj(x, y);count++;}this.rootBranch = new Branch(this.ctx,0,0,this.pointArr,this.structFactor,this.maxLevels,time,noise);}drawShape() {const time = Date.now() / 5000 * this.random;const noise = simplex.noise3D(this.x, this.y, time);this.structFactor = Math.sin(time) * noise * 3;this.r = Math.sin(time) * noise * this.ri + 100;this.init(time, noise);this.rootBranch.drawMe();this.a += noise;}
}class Branch {constructor(ctx, lev, n, points, factor, max, time, noise) {this.ctx = ctx;this.level = lev;this.num = n;this.outerPoints = points;this.structFactor = factor;this.maxLevels = max;this.time = time;this.noise = noise;this.myBranches = [];this.midPoints = this.calcMidPoints();this.projPoints = this.calcStructPoints();if (this.level + 1 < this.maxLevels) {let childBranch = new Branch(this.ctx,this.level + 1,0,this.projPoints,this.structFactor,this.maxLevels,this.time,this.noise);this.myBranches.push(childBranch);for (let i = 0; i < this.outerPoints.length; i++) {let n = i - 1;if (n < 0) {n += this.outerPoints.length;}let newPoints = [this.projPoints[i],this.midPoints[i],this.outerPoints[i],this.midPoints[n],this.projPoints[n]];let childBranch = new Branch(this.ctx,this.level + 1,i + 1,newPoints,this.structFactor,this.maxLevels,this.time,this.noise);this.myBranches.push(childBranch);}}}drawMe() {const ctx = this.ctx;ctx.save();ctx.lineWidth = 0.1;ctx.strokeStyle = 'hsl(' + 360 * (this.noise * 2) + ', 80% ,60%)';ctx.beginPath();ctx.moveTo(this.outerPoints[0].x,this.outerPoints[0].y);for (let i = 1; i < this.outerPoints.length; i++) {ctx.lineTo(this.outerPoints[i].x, this.outerPoints[i].y);}ctx.closePath();ctx.stroke();ctx.restore();for (let i = 0; i < this.myBranches.length; i++) {this.myBranches[i].drawMe();}}calcMidPoints() {let mpArray = [];for (let i = 0; i < this.outerPoints.length; i++) {let n = i + 1;if (n === this.outerPoints.length) {n = 0;}let thisMp = this.calcMidPoint(this.outerPoints[i], this.outerPoints[n]);mpArray[i] = thisMp;}return mpArray;}calcMidPoint(end1, end2) {let mx, my;if (end1.x > end2.x) {mx = end2.x + ((end1.x - end2.x) / 2);} else {mx = end1.x + ((end2.x - end1.x) / 2);}if (end1.y > end2.y) {my = end2.y + ((end1.y - end2.y) / 2);} else {my = end1.y + ((end2.y - end1.y) / 2);}return new PointObj(mx, my);}calcStructPoints() {let structArray = new Array(this.midPoints.length);for (let i = 0; i < this.midPoints.length; i++) {let n = i + 3;if (n >= this.midPoints.length) {n -= this.midPoints.length;}let thisSP = this.calcProjPoint(this.midPoints[i], this.outerPoints[n]);structArray[i] = thisSP;}return structArray;}calcProjPoint(mp, op) {let px, py, adj, opp;if (op.x > mp.x) {opp = op.x - mp.x;} else {opp = mp.x - op.x;}if (op.y > mp.y) {adj = op.y - mp.y;} else {adj = mp.y - op.y;}if (op.x > mp.x) {px = mp.x + (opp * this.structFactor);} else {px = mp.x - (opp * this.structFactor);}if (op.y > mp.y) {py = mp.y + (adj * this.structFactor);} else {py = mp.y - (adj * this.structFactor);}return new PointObj(px, py);}
}(() => {'use strict';window.addEventListener('load', () => {canvas = new Canvas(true);canvas.init();canvas.render();window.addEventListener("resize", () => {canvas.resize();}, false);}, false);
})();

[simplex-noise.min.js]

        这段代码定义了一个名为 SimplexNoise 的 JavaScript 类,用于生成多维的简单噪声(Simplex Noise)。简单噪声是一种用于生成自然外观的纹理或形状的数学函数,常用于计算机图形学、游戏开发和数据可视化等领域。

        以下是对代码中各个部分的总结:

  1. 初始化和配置

    • 定义了一系列的常量(如 retao),这些常量用于后续的噪声计算。
    • i 函数是一个工厂方法,用于创建 SimplexNoise 实例。它接受一个参数,该参数可以是一个函数或者一个数字。如果参数是一个函数,它会调用该函数来生成随机数;如果参数是数字,它会使用这个数字来初始化噪声生成器的随机数种子。
  2. Permutation Table(置换表)

    • n 函数用于生成置换表,这是一个包含随机排列的字节数组。置换表用于在噪声计算中引入随机性。
    • i.prototype 对象包含了噪声生成的核心方法和数据,如 grad3 和 grad4 梯度数组,以及 noise2Dnoise3D 和 noise4D 方法,用于计算二维、三维和四维的简单噪声。
  3. 噪声计算方法

    • noise2D 方法接受两个参数 t 和 a,分别代表二维空间中的 x 和 y 坐标,返回一个介于 -1 和 1 之间的噪声值。
    • noise3D 方法接受三个参数 re 和 a,分别代表三维空间中的 xy 和 z 坐标,同样返回一个介于 -1 和 1 之间的噪声值。
    • noise4D 方法接受四个参数 ret 和 i,分别代表四维空间中的四个坐标轴,返回一个噪声值。
  4. 兼容性和模块导出

    • 代码的最后部分检查了 defineexports 和 window 对象是否存在,以确定如何导出 SimplexNoise 类。如果使用 AMD(异步模块定义)规范,则通过 define 函数导出;如果使用 CommonJS 规范(如 Node.js 环境),则通过 module.exports 导出;如果运行在浏览器环境中,则将 SimplexNoise 添加到 window 对象上。

        总的来说,这段代码提供了一个完整的简单噪声生成器实现,可以用于各种需要自然随机性的场景。通过提供不同维度的噪声计算方法,它为开发者提供了灵活性,可以根据具体需求选择合适的噪声维度。

!function(){"use strict";var r=.5*(Math.sqrt(3)-1),e=(3-Math.sqrt(3))/6,t=1/6,a=(Math.sqrt(5)-1)/4,o=(5-Math.sqrt(5))/20;function i(r){var e;e="function"==typeof r?r:r?function(){var r=0,e=0,t=0,a=1,o=(i=4022871197,function(r){r=r.toString();for(var e=0;e<r.length;e++){var t=.02519603282416938*(i+=r.charCodeAt(e));t-=i=t>>>0,i=(t*=i)>>>0,i+=4294967296*(t-=i)}return 2.3283064365386963e-10*(i>>>0)});var i;r=o(" "),e=o(" "),t=o(" ");for(var n=0;n<arguments.length;n++)(r-=o(arguments[n]))<0&&(r+=1),(e-=o(arguments[n]))<0&&(e+=1),(t-=o(arguments[n]))<0&&(t+=1);return o=null,function(){var o=2091639*r+2.3283064365386963e-10*a;return r=e,e=t,t=o-(a=0|o)}}(r):Math.random,this.p=n(e),this.perm=new Uint8Array(512),this.permMod12=new Uint8Array(512);for(var t=0;t<512;t++)this.perm[t]=this.p[255&t],this.permMod12[t]=this.perm[t]%12}function n(r){var e,t=new Uint8Array(256);for(e=0;e<256;e++)t[e]=e;for(e=0;e<255;e++){var a=e+~~(r()*(256-e)),o=t[e];t[e]=t[a],t[a]=o}return t}i.prototype={grad3:new Float32Array([1,1,0,-1,1,0,1,-1,0,-1,-1,0,1,0,1,-1,0,1,1,0,-1,-1,0,-1,0,1,1,0,-1,1,0,1,-1,0,-1,-1]),grad4:new Float32Array([0,1,1,1,0,1,1,-1,0,1,-1,1,0,1,-1,-1,0,-1,1,1,0,-1,1,-1,0,-1,-1,1,0,-1,-1,-1,1,0,1,1,1,0,1,-1,1,0,-1,1,1,0,-1,-1,-1,0,1,1,-1,0,1,-1,-1,0,-1,1,-1,0,-1,-1,1,1,0,1,1,1,0,-1,1,-1,0,1,1,-1,0,-1,-1,1,0,1,-1,1,0,-1,-1,-1,0,1,-1,-1,0,-1,1,1,1,0,1,1,-1,0,1,-1,1,0,1,-1,-1,0,-1,1,1,0,-1,1,-1,0,-1,-1,1,0,-1,-1,-1,0]),noise2D:function(t,a){var o,i,n=this.permMod12,f=this.perm,s=this.grad3,v=0,h=0,l=0,u=(t+a)*r,d=Math.floor(t+u),p=Math.floor(a+u),M=(d+p)*e,m=t-(d-M),c=a-(p-M);m>c?(o=1,i=0):(o=0,i=1);var y=m-o+e,w=c-i+e,g=m-1+2*e,A=c-1+2*e,x=255&d,q=255&p,D=.5-m*m-c*c;if(D>=0){var S=3*n[x+f[q]];v=(D*=D)*D*(s[S]*m+s[S+1]*c)}var U=.5-y*y-w*w;if(U>=0){var b=3*n[x+o+f[q+i]];h=(U*=U)*U*(s[b]*y+s[b+1]*w)}var F=.5-g*g-A*A;if(F>=0){var N=3*n[x+1+f[q+1]];l=(F*=F)*F*(s[N]*g+s[N+1]*A)}return 70*(v+h+l)},noise3D:function(r,e,a){var o,i,n,f,s,v,h,l,u,d,p=this.permMod12,M=this.perm,m=this.grad3,c=(r+e+a)*(1/3),y=Math.floor(r+c),w=Math.floor(e+c),g=Math.floor(a+c),A=(y+w+g)*t,x=r-(y-A),q=e-(w-A),D=a-(g-A);x>=q?q>=D?(s=1,v=0,h=0,l=1,u=1,d=0):x>=D?(s=1,v=0,h=0,l=1,u=0,d=1):(s=0,v=0,h=1,l=1,u=0,d=1):q<D?(s=0,v=0,h=1,l=0,u=1,d=1):x<D?(s=0,v=1,h=0,l=0,u=1,d=1):(s=0,v=1,h=0,l=1,u=1,d=0);var S=x-s+t,U=q-v+t,b=D-h+t,F=x-l+2*t,N=q-u+2*t,C=D-d+2*t,P=x-1+.5,T=q-1+.5,_=D-1+.5,j=255&y,k=255&w,z=255&g,B=.6-x*x-q*q-D*D;if(B<0)o=0;else{var E=3*p[j+M[k+M[z]]];o=(B*=B)*B*(m[E]*x+m[E+1]*q+m[E+2]*D)}var G=.6-S*S-U*U-b*b;if(G<0)i=0;else{var H=3*p[j+s+M[k+v+M[z+h]]];i=(G*=G)*G*(m[H]*S+m[H+1]*U+m[H+2]*b)}var I=.6-F*F-N*N-C*C;if(I<0)n=0;else{var J=3*p[j+l+M[k+u+M[z+d]]];n=(I*=I)*I*(m[J]*F+m[J+1]*N+m[J+2]*C)}var K=.6-P*P-T*T-_*_;if(K<0)f=0;else{var L=3*p[j+1+M[k+1+M[z+1]]];f=(K*=K)*K*(m[L]*P+m[L+1]*T+m[L+2]*_)}return 32*(o+i+n+f)},noise4D:function(r,e,t,i){var n,f,s,v,h,l,u,d,p,M,m,c,y,w,g,A,x,q=this.perm,D=this.grad4,S=(r+e+t+i)*a,U=Math.floor(r+S),b=Math.floor(e+S),F=Math.floor(t+S),N=Math.floor(i+S),C=(U+b+F+N)*o,P=r-(U-C),T=e-(b-C),_=t-(F-C),j=i-(N-C),k=0,z=0,B=0,E=0;P>T?k++:z++,P>_?k++:B++,P>j?k++:E++,T>_?z++:B++,T>j?z++:E++,_>j?B++:E++;var G=P-(l=k>=3?1:0)+o,H=T-(u=z>=3?1:0)+o,I=_-(d=B>=3?1:0)+o,J=j-(p=E>=3?1:0)+o,K=P-(M=k>=2?1:0)+2*o,L=T-(m=z>=2?1:0)+2*o,O=_-(c=B>=2?1:0)+2*o,Q=j-(y=E>=2?1:0)+2*o,R=P-(w=k>=1?1:0)+3*o,V=T-(g=z>=1?1:0)+3*o,W=_-(A=B>=1?1:0)+3*o,X=j-(x=E>=1?1:0)+3*o,Y=P-1+4*o,Z=T-1+4*o,$=_-1+4*o,rr=j-1+4*o,er=255&U,tr=255&b,ar=255&F,or=255&N,ir=.6-P*P-T*T-_*_-j*j;if(ir<0)n=0;else{var nr=q[er+q[tr+q[ar+q[or]]]]%32*4;n=(ir*=ir)*ir*(D[nr]*P+D[nr+1]*T+D[nr+2]*_+D[nr+3]*j)}var fr=.6-G*G-H*H-I*I-J*J;if(fr<0)f=0;else{var sr=q[er+l+q[tr+u+q[ar+d+q[or+p]]]]%32*4;f=(fr*=fr)*fr*(D[sr]*G+D[sr+1]*H+D[sr+2]*I+D[sr+3]*J)}var vr=.6-K*K-L*L-O*O-Q*Q;if(vr<0)s=0;else{var hr=q[er+M+q[tr+m+q[ar+c+q[or+y]]]]%32*4;s=(vr*=vr)*vr*(D[hr]*K+D[hr+1]*L+D[hr+2]*O+D[hr+3]*Q)}var lr=.6-R*R-V*V-W*W-X*X;if(lr<0)v=0;else{var ur=q[er+w+q[tr+g+q[ar+A+q[or+x]]]]%32*4;v=(lr*=lr)*lr*(D[ur]*R+D[ur+1]*V+D[ur+2]*W+D[ur+3]*X)}var dr=.6-Y*Y-Z*Z-$*$-rr*rr;if(dr<0)h=0;else{var pr=q[er+1+q[tr+1+q[ar+1+q[or+1]]]]%32*4;h=(dr*=dr)*dr*(D[pr]*Y+D[pr+1]*Z+D[pr+2]*$+D[pr+3]*rr)}return 27*(n+f+s+v+h)}},i._buildPermutationTable=n,"undefined"!=typeof define&&define.amd&&define(function(){return i}),"undefined"!=typeof exports?exports.SimplexNoise=i:"undefined"!=typeof window&&(window.SimplexNoise=i),"undefined"!=typeof module&&(module.exports=i)}();

效果图

总结

  1. HTML

    • 定义了一个网页的基本结构,包括DOCTYPE声明、html、head和body标签。
    • 在head部分,设置了页面字符集为UTF-8,并定义了网页标题。
    • 引入了一个外部CSS文件normalize.min.css用于样式重置,以及两个JavaScript文件simplex-noise.min.jsscript.js,这些文件将用于网页的样式和行为。
  2. CSS

    • 包含了一系列的CSS规则,用于重置和标准化HTML元素的默认样式,以确保在不同浏览器中具有一致的表现。
    • 涉及的样式包括按钮、表单元素、媒体元素等的显示方式、字体、外边距、内边距和边框样式。
    • 还包括了一些针对HTML5新语义元素的样式设置,如articleasidefooter等。
  3. JavaScript

    • 定义了一系列的类和方法,用于生成随机数、颜色、渐变色、计算帧率(FPS)、处理向量运算、碰撞检测、计时和动画定时。
    • Utils类提供了生成随机数和颜色的方法,以及创建渐变色和计算FPS的功能。
    • Vector2d类表示二维向量,提供了一系列向量运算的方法,如缩放、加法、减法、取反、归一化和旋转。
    • Collision类处理对象之间的碰撞检测和碰撞反弹。
    • Stopwatch类用于计时,提供了开始、停止、获取经过时间、检查是否正在运行和重置计时器的方法。
    • AnimationTimer类用于动画定时,支持不同的缓动函数,如Ease-In、Ease-Out、Ease-In-Out、Elastic和Bounce。
    • Angle类用于表示角度,可以增加或减少角度值,并将其转换为弧度。
    • Canvas类用于创建和管理分形图形的绘制,提供了初始化、渲染、绘制帧率和响应窗口大小变化的方法。
    • PointObjFractalRoot类用于生成分形图形的结构和绘制。
    • Branch类表示分形中的一个分支,负责计算分支的中间点、结构点,并绘制分支。
    • 最后,自执行函数用于初始化Canvas类,并设置窗口大小变化的事件监听器。
    • 另外,还有一个SimplexNoise类,用于生成多维的简单噪声,这在计算机图形学中非常有用,可以用于创建自然纹理或形状。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

面试经典算法系列之二叉树1 -- 从前序与中序遍历序列构造二叉树

面试经典算法16 - 从前序与中序遍历序列构造二叉树 LeetCode.105 公众号&#xff1a;阿Q技术站 问题描述 给定两个整数数组 preorder 和 inorder &#xff0c;其中 preorder 是二叉树的先序遍历&#xff0c; inorder 是同一棵树的中序遍历&#xff0c;请构造二叉树并返回其根…

VUE typescript 调用stompjs[Rabbit MQ]

npm拉下来最新的2.3.9版本&#xff0c;发现一些原来Js代码已经不能用了。顺便解读了下最新定义的内容 // <reference types"node" />export const VERSIONS: {V1_0: string;V1_1: string;V1_2: string;supportedVersions: () > string[]; };export class C…

airtest-ios真机搭建实践

首先阅读4 ios connection - Airtest Project Docs 在Windows环境下搭建Airtest对iOS真机进行自动化测试的过程相对复杂&#xff0c;因为iOS的自动化测试通常需要依赖Mac OS系统&#xff0c;但理论上借助一些工具和服务&#xff0c;Windows用户也可以间接完成部分工作。下面是…

前端对接fastGPT流式数据+打字机效果

首先在对接api时 参数要设置stream: true, const data {chatId: abc,stream: true,//这里true返回流式数据detail: false,variables: {uid: sfdsdf,name: zhaoyunyao,},messages: [{ content: text, role: user }]}; 不要用axios发请求 不然处理不了流式数据 我这里使用fetch …

PairAug:增强图像-文本对对放射学有什么用?

论文链接 代码链接GitHub - YtongXie/PairAug: [CVPR2024] PairAug: What Can Augmented Image-Text Pairs Do for Radiology? 发表于CVPR2024 机构 1) 澳大利亚机器学习研究所(AIML)&#xff0c;澳大利亚阿德莱德大学 2) 西北工业大学计算机科学与工程学院 3) 西北工业…

【简明图文教程】Node.js的下载、安装、环境配置及测试

文章目录 前言下载Node.js安装Node.js配置Node.js配置环境变量测试后言 前言 本教程适用于小白第一次从零开始进行Node.js的下载、安装、环境配置及测试。 如果你之前已经安装过了Node.js或删除掉了Node.js想重新安装&#xff0c;需要先参考以下博客进行处理后&#xff0c;再根…

渗透测试实战——第一站

仅供交流学习使用&#xff0c;请勿用于非法用途 前言&#xff1a;刚学了sql注入&#xff0c;只听理论总感觉没啥用&#xff0c;今天花了一半个多小时&#xff0c;去尝试寻找有漏洞的网站&#xff0c;最终找到了一个&#xff1b;实践是检验真理的唯一标准。 我是通过黑客常用语法…

牛客 NC36 在两个长度相等的排序数组中找到上中位数【中等 模拟 Java,Go,PHP】

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/6fbe70f3a51d44fa9395cfc49694404f 思路 直接模拟2个数组有顺序放到一个数组中&#xff0c;然后返回中间的数参考答案java import java.util.Scanner;// 注意类名必须为 Main, 不要有任何 package xxx 信息 pu…

深入剖析UDP反射放大攻击原理及其有效防护策略

引言 随着互联网的飞速发展和业务复杂性的提升&#xff0c;网络安全问题日益凸显&#xff0c;其中分布式拒绝服务&#xff08;DDoS&#xff09;攻击成为危害最为严重的一类网络威胁之一。UDP反射放大攻击作为一种高效的DDoS手段&#xff0c;因其攻击成本低廉、威力巨大&#x…

IDEA中无法保存设置 Cannot Save Settings

确定原因: 在IDEA中父工程不应该存在有子工程的相关东西 首先,这是我的DCYJ项目(观察右侧的Content Root) 其次,这是我的EAPOFode项目(观察右侧的Content Root爆红处) 最后我将DCYJ项目右侧的Content Root全部删掉

关于部署ELK和EFLKD的相关知识

文章目录 一、ELK日志分析系统1、ELK简介1.2 ElasticSearch1.3 Logstash1.4 Kibana&#xff08;展示数据可视化界面&#xff09;1.5 Filebeat 2、使用ELK的原因3、完整日志系统的基本特征4、ELK的工作原理 二、部署ELK日志分析系统1、服务器配置2、关闭防火墙3、ELK ElasticSea…

ASUS华硕ROG幻16Air笔记本电脑GU605M原装出厂Win11系统工厂包下载,带有ASUSRecovery一键重置还原

适用型号&#xff1a;GU605MI、GU605MY、GU605MZ、GU605MV、GU605MU 链接&#xff1a;https://pan.baidu.com/s/1YBmZZbTKpIu883jYCS9KfA?pwd9jd4 提取码&#xff1a;9jd4 华硕原厂Windows11系统带有ASUS RECOVERY恢复功能、自带所有驱动、出厂主题壁纸、系统属性联机支持…

Java后端搭建流程

目录 一、后端开发准备工作 1.下载 2.安装jdk &#xff0c;配置JAVA-HOME path 3.启动Tomcat 4.访问ip和端口 二、创建web项目 1.新建一个项目 2.发布web应用到服务器 &#xff08;1&#xff09;对LoginServlet继承HttpServlet &#xff08;2&#xff09;重写父类方法…

如何让视频流媒体平台免受网络攻击

在各国&#xff0c;流媒体服务已越来越受到大众的欢迎。有统计表明&#xff0c;目前视频流已占网络整体流量的80%以上。不过如您所见&#xff0c;近年来&#xff0c;数字威胁的不断增加&#xff0c;也让网络攻击逐年递增。单个视频用户受到的危险&#xff0c;往往会危及到整个服…

Vue 项目build打包发布到giteepages ,首页正常显示,其他路由页面报错404的解决方法

直接上解决方法&#xff1a; 打包之后dist上传之后&#xff0c;还要新创一个.spa文件&#xff0c;注意&#xff01;是 .spa 有个. 点&#xff0c;如下图 一般这样就可以开始部署了&#xff0c;然后开启giteepages服务。如果出现了首页正常显示&#xff0c;其他页面显示…

全新华为MateBook X Pro发布,将Ultra9放入980g超轻薄机身

2024年4月11日&#xff0c;在华为鸿蒙生态春季沟通会上全新的华为MateBook X Pro正式发布。该机以美学设计、创新科技以及智慧体验&#xff0c;追求重新定义Pro、重新定义旗舰&#xff0c;将颠覆消费者对传统轻薄本的认知。 华为MateBook X Pro追求极致轻薄与强大性能的完美结合…

Java安全管理器-SecurityManager

定义&#xff1a; SecurityManager是Java中的一个类&#xff0c;用于实现安全管理功能。它允许应用程序在运行时对安全策略进行动态管理&#xff0c;并控制哪些操作可以执行&#xff0c;哪些应该被拒绝。主要功能包括&#xff1a; 安全策略管理&#xff1a;SecurityManager允许…

D-LinkNAS 远程命令执行漏洞(CVE-2024-3273)RCE漏

声明&#xff1a; 本文仅用于技术交流&#xff0c;请勿用于非法用途 由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;文章作者不为此承担任何责任。 简介 D-LinkNAS是由D-Link公司制造的网络附加存储设备。…

SOLIDOWRKS怎么将中间格式的模具装配体转化为装配体格式

模具是工业生产中用于制作成型物品的工具&#xff0c;它由各种零件构成&#xff0c;可以通过改变所成型材料的物理状态来实现物品外形的加工。如果工程师已经有其他格式的模具装配体&#xff0c;但是又想将其他格式的模具装配体导入solidworks里面&#xff0c;并且将一个个实体…

数字人项目 ER-NeRF 的使用和部署详细教程

文章目录 1. ER-NeRF简介2. ER-NeRF部署3. 训练自己的数字人4. 生成数字人视频5. 其他数字人模型比较常见错误 1. ER-NeRF简介 ER-NeRF&#xff08;官方链接&#xff09;是一个Talking Portrait Synthesis&#xff08;对嘴型&#xff09;项目。即&#xff1a;给一段某人说话的…