多段Bézier曲线变换效果 HTML实现

头像
老刘001
初来炸道
初来炸道
帖子: 6
注册时间: 2017年03月17日 23:58
拥有现金: 锁定
Has thanked: 5 times
Been thanked: 7 times
联系:

多段Bézier曲线变换效果 HTML实现

帖子 #1 老刘001 » 2020年06月30日 17:11

图片
图片
编写思路来源:http://www.code-by.org/viewtopic.php?f=43&t=109
windows系统建议保存为HTA,非windows系统可以保存为html。
Code: [全选] [展开/折叠] [Download] (Bezier_Curve_Variation.hta)
  1. <!doctype html>
  2. <html lang="zh_CN" id="main">
  3.     <head>
  4.         <title>多段贝塞尔曲线变换(创意:Vicyang;HTML实现:老刘)</title>
  5.         <HTA:APPLICATION
  6.             APPLICATIONNAME="Bezier Curve Variation"
  7.             ID="BezierCurveVariation"
  8.             VERSION="1.0"
  9.             INNERBORDER="no"/>
  10.         <style>
  11.             html, body {
  12.                 /*不要边框*/
  13.                 margin: 0;
  14.                 border: 0;
  15.                 padding: 0;
  16.                
  17.                 /*不要滚动条*/
  18.                 overflow-y: hidden;
  19.                 overflow-x: hidden;
  20.  
  21.                 /*自动换行*/
  22.                 word-wrap: break-word;
  23.                 word-break: break-all;
  24.             }
  25.            
  26.             p {
  27.                 margin: 0px;
  28.             }
  29.            
  30.             #TextArea {
  31.                 background-color: #222222;
  32.                 color: white;
  33.                
  34.                 font-family: 'Microsoft YaHei';
  35.                 letter-spacing: 0px;
  36.                 /*font-size: 12px;
  37.                 line-height: 12px;*/
  38.                 color: chartreuse;
  39.                
  40.                 height: 100%;
  41.                 position: relative;
  42.                 margin: 0 auto;
  43.                 border: 0;
  44.                 padding: 0;
  45.             }
  46.         </style>
  47.     </head>
  48.     <body>
  49.         <div id="TextArea"></div>
  50.         <script language="JavaScript">
  51.             //设置区。
  52.             var lngFontSize = 8;   //字体大小
  53.             var lngBufferWidth = 150;    //缓冲区列数
  54.             var lngBufferHeight = 100;   //缓冲区行数
  55.             var lngPointNumber = 8; //绘制点数
  56.             var numMoveSpeed = 0.03;    //移动紧密度
  57.             var lngLayer = 15;   //轨迹保留层数
  58.             var lngSleep = 30;  //绘制延时
  59.  
  60.             function Point(x, y) {
  61.                 this.x = x;
  62.                 this.y = y;
  63.             }
  64.  
  65.             window.onload = function () {
  66.                 //调整窗口布局。
  67.                 window.resizeTo(lngBufferWidth * lngFontSize, lngBufferHeight * lngFontSize);
  68.                 window.resizeTo(
  69.                     2 * lngBufferWidth * lngFontSize - document.documentElement.clientWidth,
  70.                     2 * lngBufferHeight * lngFontSize - document.documentElement.offsetHeight
  71.                 );
  72.                 document.getElementById('main').style.width = (lngBufferWidth * lngFontSize).toString() + 'px';
  73.                 document.getElementById('main').style.height = (lngBufferHeight * lngFontSize).toString() + 'px';
  74.                 document.body.style.width = (lngBufferWidth * lngFontSize).toString() + 'px';
  75.                 document.body.style.height = (lngBufferHeight * lngFontSize).toString() + 'px';
  76.                 document.getElementById('TextArea').style.fontSize = lngFontSize.toString() + 'px';
  77.                 document.getElementById('TextArea').style.lineHeight = lngFontSize.toString() + 'px';
  78.                
  79.  
  80.                 //创建缓冲区数组。
  81.                 //arrBuffer[缓冲区索引][该缓冲区横坐标][该缓冲区纵坐标]
  82.                 var arrBuffer = new Array();
  83.                 for (var y = 0; y < lngBufferHeight; y++) {
  84.                     arrBuffer[y] = new Array();
  85.                     for (var x = 0; x < lngBufferWidth; x++) {
  86.                         arrBuffer[y][x] = '&#12288;';   //全角空格
  87.                     }
  88.                 }
  89.  
  90.                 //创建控制点数组。
  91.                 //主控制点绘制主轨迹,从控制点控制主控制点按从轨迹移动。
  92.                 //主从轨迹均为三阶贝塞尔曲线。
  93.                 //arrPoints[0-3主轨迹控制点索引][0-3该控制点对应的从轨迹的从控制点,4该控制点]
  94.                 var arrPoints = new Array();
  95.                 for (var i = 0; i <= 3; i++) {
  96.                     arrPoints[i] = new Array();
  97.                 }
  98.                
  99.  
  100.                 //准备绘制。
  101.                 //初始化随机控制点。
  102.                 for (var i = 0; i <= 3; i++) {
  103.                     arrPoints[i][2] = NewControlPoint();
  104.                     arrPoints[i][3] = NewControlPoint();
  105.                 }
  106.                 var numServantT = 20011228 //4个从轨迹统一的参数t,超过1时会求新随机点并置0。
  107.                 var lngUsingBufferIndex = 0;
  108.                 //创建老点队列并填充。
  109.                 var queueOldPoints = new Array()
  110.                 for (var i = 0; i <= lngLayer * lngPointNumber; i++) {
  111.                     queueOldPoints.push(new Point(-1, -1)); //填充无效点。
  112.                 }
  113.  
  114.  
  115.                 //循环绘制。
  116.                 setInterval(function () {
  117.                     //若主控制点移动完成,则生成新路径。
  118.                     if (numServantT > 1) {
  119.                         numServantT = 0;
  120.                         for (var i = 0; i <= 3; i++) {
  121.                             //设置新的从轨迹接上旧的。
  122.                             //即将旧轨迹终点作为新轨迹起点。
  123.                             arrPoints[i][0] = arrPoints[i][3];
  124.                             //此处让新的控制点2作为旧控制点3关于旧控制点4/新控制点1的对称点,增加曲线平滑度。
  125.                             arrPoints[i][1] = new Point(
  126.                                 2 * arrPoints[i][3].x - arrPoints[i][2].x,
  127.                                 2 * arrPoints[i][3].y - arrPoints[i][2].y
  128.                             );
  129.                             //其它从控制点随机获得。
  130.                             for (var j = 2; j <= 3; j++) {
  131.                                 arrPoints[i][j] = NewControlPoint();
  132.                             }
  133.                         }
  134.                     } else {
  135.                         numServantT += numMoveSpeed;
  136.                     }
  137.                     //算一下主控制点。
  138.                     for (var i = 0; i <= 3; i++) {
  139.                         arrPoints[i][4] = ThirdOrderBezierCurve(
  140.                             numServantT,
  141.                             arrPoints[i][0],
  142.                             arrPoints[i][1],
  143.                             arrPoints[i][2],
  144.                             arrPoints[i][3]
  145.                         );
  146.                     }
  147.                     //绘制缓冲区。
  148.                     //从缓冲区擦除老点。
  149.                     for (var t = 0; t <= 1; t += 1 / (lngPointNumber - 1)) {
  150.                         var OldPoint = queueOldPoints.shift();
  151.                         if (OldPoint.x >= 0 && OldPoint.x < lngBufferWidth && OldPoint.y >= 0 && OldPoint.y < lngBufferHeight) {
  152.                             DrawPoint(arrBuffer, OldPoint, "&#12288;");
  153.                         }
  154.                     }
  155.                     //绘制新点到缓冲区。
  156.                     for (var t = 0; t <= 1; t += 1 / (lngPointNumber - 1)) {
  157.                         var NewPoint = ThirdOrderBezierCurve(
  158.                             t,
  159.                             arrPoints[0][4],
  160.                             arrPoints[1][4],
  161.                             arrPoints[2][4],
  162.                             arrPoints[3][4]
  163.                         );
  164.                         //绘制新点并入队。
  165.                         if (NewPoint.x >= 0 && NewPoint.x < lngBufferWidth && NewPoint.y >= 0 && NewPoint.y < lngBufferHeight) {
  166.                             DrawPoint(arrBuffer, NewPoint, "ABCDEFGHIJKLMNOPQRSTUVWXYZ".charAt(RandomInteger(0,26)));
  167.                         }
  168.                         queueOldPoints.push(NewPoint);
  169.                     }
  170.  
  171.                     //绘制结果。
  172.                     var strBuffer = '';
  173.                     for (var i = 0; i < lngBufferHeight; i++) {
  174.                         strBuffer += arrBuffer[i].join('') + '<br>';
  175.                     }
  176.                     document.getElementById('TextArea').innerHTML = strBuffer;
  177.                 }, lngSleep);
  178.             }
  179.  
  180.             function ThirdOrderBezierCurve(t, p0, p1, p2, p3) {
  181.                 //三阶贝塞尔曲线计算函数。
  182.                 return new Point(
  183.                     p0.x * (1 - t) * (1 - t) * (1 - t) + 3 * p1.x * t * (1 - t) * (1 - t) + 3 * p2.x * t * t * (1 - t) + p3.x * t * t * t,
  184.                     p0.y * (1 - t) * (1 - t) * (1 - t) + 3 * p1.y * t * (1 - t) * (1 - t) + 3 * p2.y * t * t * (1 - t) + p3.y * t * t * t
  185.                 );
  186.             }
  187.  
  188.             function DrawPoint(arrBuffer, objPoint, charText) {
  189.                 //在arrBuffer中画点。(其实就是修改数组)
  190.                 //alert(objPoint.y + ' ' + objPoint.x);
  191.                 arrBuffer[Math.floor(objPoint.y)][Math.floor(objPoint.x)] = charText;
  192.                 return;
  193.             }
  194.  
  195.             function ArrayDeepCopy(obj) {
  196.                 //数组深拷贝函数(支持多维数组)。
  197.                 var out = [], i = 0, len = obj.length;
  198.                 for (; i < len; i++) {
  199.                     if (obj[i] instanceof Array) {
  200.                         out[i] = ArrayDeepCopy(obj[i]);
  201.                     }
  202.                     else out[i] = obj[i];
  203.                 }
  204.                 return out;
  205.             }
  206.  
  207.             function NewControlPoint() {
  208.                 //获得新随机控制点。
  209.                 return NewRandomPoint(0,lngBufferWidth,0,lngBufferHeight);
  210.                 //24game的建议:将控制点范围限定在与缓冲区同心、宽高均为缓冲区宽高2/3的矩形内。
  211.                 //这样可以避免主轨迹溢出屏幕。
  212.                 //但由于对称,无法很好的限制,所以不采纳。
  213.                 //return NewRandomPoint(
  214.                 //    Math.floor(lngBufferWidth / 6),
  215.                 //    Math.floor(lngBufferWidth * 5 / 6),
  216.                 //    Math.floor(lngBufferHeight / 6),
  217.                 //    Math.floor(lngBufferHeight * 5 / 6)
  218.                 //);
  219.             }
  220.  
  221.             function NewRandomPoint(lngRangeXStart, lngRangeXEnd, lngRangeYStart, lngRangeYEnd) {
  222.                 //获得新随机点。
  223.                 return new Point(
  224.                     RandomInteger(lngRangeXStart, lngRangeXEnd),
  225.                     RandomInteger(lngRangeYStart, lngRangeYEnd)
  226.                 );
  227.             }
  228.  
  229.             function RandomInteger(lngStart, lngEnd) {
  230.                 //获得以lngStart为下界(含lngStart),lngEnd为上界(不含lngEnd)的随机整数。
  231.                 return lngStart + Math.floor(Math.random() * (lngEnd - lngStart));
  232.             }
  233.  
  234.         </script>
  235.     </body>
  236. </html>

头像
523066680
Administrator
Administrator
帖子: 490
注册时间: 2016年07月19日 12:14
拥有现金: 锁定
储蓄: 锁定
Has thanked: 56 times
Been thanked: 96 times
联系:

Re: 多段Bézier曲线变换效果 HTML实现

帖子 #2 523066680 » 2020年07月01日 14:41

好久没有学习了 :shy


回到 “JavaScript”

在线用户

用户浏览此论坛: 没有注册用户 和 0 访客