[HTA][算法实战008]多段贝塞尔曲线变换特效
本帖最后由 老刘 于 2020-6-30 12:56 编辑创意来自于vicyang兄,论坛不让放链接就不放了。
Windows系统建议保存为hta,其它系统可以保存为html。
<!doctype html>
<html lang="zh_CN" id="main">
<head>
<title>多段贝塞尔曲线变换(创意:Vicyang;HTML实现:老刘)</title>
<HTA:APPLICATION
APPLICATIONNAME="Bezier Curve Variation"
ID="BezierCurveVariation"
VERSION="1.0"
INNERBORDER="no"/>
<style>
html, body {
/*不要边框*/
margin: 0;
border: 0;
padding: 0;
/*不要滚动条*/
overflow-y: hidden;
overflow-x: hidden;
/*自动换行*/
word-wrap: break-word;
word-break: break-all;
}
p {
margin: 0px;
}
#TextArea {
background-color: #222222;
color: white;
font-family: 'Microsoft YaHei';
letter-spacing: 0px;
/*font-size: 12px;
line-height: 12px;*/
color: chartreuse;
height: 100%;
position: relative;
margin: 0 auto;
border: 0;
padding: 0;
}
</style>
</head>
<body>
<div id="TextArea"></div>
<script language="JavaScript">
//设置区。
var lngFontSize = 12; //字体大小
var lngBufferWidth = 80; //缓冲区列数
var lngBufferHeight = 60; //缓冲区行数
var lngPointNumber = 8; //绘制点数
var numMoveSpeed = 0.03; //移动紧密度
var lngLayer = 15; //轨迹保留层数
var lngSleep = 30;//绘制延时
function Point(x, y) {
this.x = x;
this.y = y;
}
window.onload = function () {
//调整窗口布局。
window.resizeTo(lngBufferWidth * lngFontSize, lngBufferHeight * lngFontSize);
window.resizeTo(
2 * lngBufferWidth * lngFontSize - document.documentElement.clientWidth,
2 * lngBufferHeight * lngFontSize - document.documentElement.offsetHeight
);
document.getElementById('main').style.width = (lngBufferWidth * lngFontSize).toString() + 'px';
document.getElementById('main').style.height = (lngBufferHeight * lngFontSize).toString() + 'px';
document.body.style.width = (lngBufferWidth * lngFontSize).toString() + 'px';
document.body.style.height = (lngBufferHeight * lngFontSize).toString() + 'px';
document.getElementById('TextArea').style.fontSize = lngFontSize.toString() + 'px';
document.getElementById('TextArea').style.lineHeight = lngFontSize.toString() + 'px';
//创建缓冲区数组。
//arrBuffer[缓冲区索引][该缓冲区横坐标][该缓冲区纵坐标]
var arrBuffer = new Array();
for (var y = 0; y < lngBufferHeight; y++) {
arrBuffer = new Array();
for (var x = 0; x < lngBufferWidth; x++) {
arrBuffer = ' '; //全角空格
}
}
//创建控制点数组。
//主控制点绘制主轨迹,从控制点控制主控制点按从轨迹移动。
//主从轨迹均为三阶贝塞尔曲线。
//arrPoints
var arrPoints = new Array();
for (var i = 0; i <= 3; i++) {
arrPoints = new Array();
}
//准备绘制。
//初始化随机控制点。
for (var i = 0; i <= 3; i++) {
arrPoints = NewControlPoint();
arrPoints = NewControlPoint();
}
var numServantT = 20011228 //4个从轨迹统一的参数t,超过1时会求新随机点并置0。
var lngUsingBufferIndex = 0;
//创建老点队列并填充。
var queueOldPoints = new Array()
for (var i = 0; i <= lngLayer * lngPointNumber; i++) {
queueOldPoints.push(new Point(-1, -1)); //填充无效点。
}
//循环绘制。
setInterval(function () {
//若主控制点移动完成,则生成新路径。
if (numServantT > 1) {
numServantT = 0;
for (var i = 0; i <= 3; i++) {
//设置新的从轨迹接上旧的。
//即将旧轨迹终点作为新轨迹起点。
arrPoints = arrPoints;
//此处让新的控制点2作为旧控制点3关于旧控制点4/新控制点1的对称点,增加曲线平滑度。
arrPoints = new Point(
2 * arrPoints.x - arrPoints.x,
2 * arrPoints.y - arrPoints.y
);
//其它从控制点随机获得。
for (var j = 2; j <= 3; j++) {
arrPoints = NewControlPoint();
}
}
} else {
numServantT += numMoveSpeed;
}
//算一下主控制点。
for (var i = 0; i <= 3; i++) {
arrPoints = ThirdOrderBezierCurve(
numServantT,
arrPoints,
arrPoints,
arrPoints,
arrPoints
);
}
//绘制缓冲区。
//从缓冲区擦除老点。
for (var t = 0; t <= 1; t += 1 / (lngPointNumber - 1)) {
var OldPoint = queueOldPoints.shift();
if (OldPoint.x >= 0 && OldPoint.x < lngBufferWidth && OldPoint.y >= 0 && OldPoint.y < lngBufferHeight) {
DrawPoint(arrBuffer, OldPoint, " ");
}
}
//绘制新点到缓冲区。
for (var t = 0; t <= 1; t += 1 / (lngPointNumber - 1)) {
var NewPoint = ThirdOrderBezierCurve(
t,
arrPoints,
arrPoints,
arrPoints,
arrPoints
);
//绘制新点并入队。
if (NewPoint.x >= 0 && NewPoint.x < lngBufferWidth && NewPoint.y >= 0 && NewPoint.y < lngBufferHeight) {
DrawPoint(arrBuffer, NewPoint, "ABCDEFGHIJKLMNOPQRSTUVWXYZ".charAt(RandomInteger(0,26)));
}
queueOldPoints.push(NewPoint);
}
//绘制结果。
var strBuffer = '';
for (var i = 0; i < lngBufferHeight; i++) {
strBuffer += arrBuffer.join('') + '<br>';
}
document.getElementById('TextArea').innerHTML = strBuffer;
}, lngSleep);
}
function ThirdOrderBezierCurve(t, p0, p1, p2, p3) {
//三阶贝塞尔曲线计算函数。
return new Point(
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,
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
);
}
function DrawPoint(arrBuffer, objPoint, charText) {
//在arrBuffer中画点。(其实就是修改数组)
//alert(objPoint.y + ' ' + objPoint.x);
arrBuffer = charText;
return;
}
function ArrayDeepCopy(obj) {
//数组深拷贝函数(支持多维数组)。
var out = [], i = 0, len = obj.length;
for (; i < len; i++) {
if (obj instanceof Array) {
out = ArrayDeepCopy(obj);
}
else out = obj;
}
return out;
}
function NewControlPoint() {
//获得新随机控制点。
return NewRandomPoint(0,lngBufferWidth,0,lngBufferHeight);
//24game的建议:将控制点范围限定在与缓冲区同心、宽高均为缓冲区宽高2/3的矩形内。
//这样可以避免主轨迹溢出屏幕。
//但由于对称,无法很好的限制,所以不采纳。
//return NewRandomPoint(
// Math.floor(lngBufferWidth / 6),
// Math.floor(lngBufferWidth * 5 / 6),
// Math.floor(lngBufferHeight / 6),
// Math.floor(lngBufferHeight * 5 / 6)
//);
}
function NewRandomPoint(lngRangeXStart, lngRangeXEnd, lngRangeYStart, lngRangeYEnd) {
//获得新随机点。
return new Point(
RandomInteger(lngRangeXStart, lngRangeXEnd),
RandomInteger(lngRangeYStart, lngRangeYEnd)
);
}
function RandomInteger(lngStart, lngEnd) {
//获得以lngStart为下界(含lngStart),lngEnd为上界(不含lngEnd)的随机整数。
return lngStart + Math.floor(Math.random() * (lngEnd - lngStart));
}
</script>
</body>
</html> 奈何没有文化 只能说一句nb 很牛很漂亮! 虽然看不懂,但是感觉好厉害的样子
页:
[1]