<!DOCTYPE html>
<html>
<head>
<meta charset="utf8">
<meta http-equiv="X-UA-Compatible" content="IE-edge, chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>朝着群星前进(Toward The Stars)</title>
<style>
body {
overflow: hidden;
background-color: #00113F;
}
#inputDiv {
/* 要在canvas上显示控件,需要设置position:absolute,并将left和top置为0 */
position: absolute;
left: 0;
top: -230px;
margin: 5px;
padding:10px;
background-color: white;
border-bottom-left-radius:10px;
border-bottom-right-radius:10px;
transition: top 1s;
}
#inputDiv:hover {
top: 0px;
}
.configLine {
border-bottom: 1px solid black;
padding-top: 5px;
padding-bottom: 5px;
}
#configTitle {
text-align: center;
padding-top: 5px;
}
#inputDiv table{
border-bottom: 1px solid black;
}
#inputDiv input {
margin-bottom: 10px;
/* 要让input居中只要将它的边距全部去掉即可 */
margin:0px;
padding:0px;
/* 添加这句后按钮和文字才会对齐 */
vertical-align:middle;
}
#inputDiv input[type=range] {
margin-top: 5px;
width: 170px;
}
</style>
</head>
<body>
<canvas id="canvas">Your browser can not support canvas</canvas>
<div id="inputDiv">
<table>
<tr class="configLine">
<td>Backgrond Color</td>
<td><input id="bgColor" type="color" value="#00113F"/></td>
</tr>
<tr class="configLine">
<td>Star Color</td>
<td><input id="starColor" type="color" value="#FBFFAF"/></td>
</tr>
</table>
<div class="configLine">
Star Shape<br/>
<input id="starShapeSquare" type="radio" name="starShapes" value="square" checked/>square
<input id="starShapeCircle" type="radio" name="starShapes" value="circle"/>circle
</div>
<div class="configLine">
Animation Schemes<br/>
<input id="starAnimationScheme1" type="radio" name="starAnimationSchemes" value="scheme1" checked/>scheme1
<input id="starAnimationScheme2" type="radio" name="starAnimationSchemes" value="scheme2"/>scheme2
</div>
<div class="configLine">
<div id="towardStepTip">Toward Step:10</div>
<input id="towardStepRange" type="range" min="0" max="30" value="10"/>
</div>
<div id="configTitle">参数面板</div>
</div>
<script>
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var starSky;
//星空
var StarSky = function() {
var doublePI = Math.PI * 2;
var _this = this;
//星星粒子颜色
this.starColor = "#FBFFAF";
//星星的类型(square、circle)
this.starShape = "square";
//动画方案(scheme1、scheme2)
this.animationSchema = "scheme1";
//星星个数是画布长加宽的某个比例
var starCountRatio = 0.4;
//星体缩放系数
var starScaleRatio = 0.3;
//星空深处直径与画布短边的比
var depthSkySizeRatio = 0.5;
//星空深度
this.skyDepth = 400;
//每帧朝前移动的步长
this.towardStep = 10;
//星空中心X坐标
var cx;
//星空中心Y坐标
var cy;
//星空深处的半径
var skyDepthRadius;
//星空深处的直径
var skyDepthDiameter;
//星星粒子个数
var starCount;
//星空粒子数组
var stars;
//判断点是否在画布中
function isOutCanvas(x, y) {
return (x < 0 || y < 0 || x > canvas.width || y > canvas.height);
}
//星空粒子
var StarParticle = function() {
//随机一个画布中心的偏移点
this.offsetX = -skyDepthRadius + skyDepthDiameter * Math.random();
this.offsetY = -skyDepthRadius + skyDepthDiameter * Math.random();
//深度随机为视口到最深处
this.depth = _this.skyDepth * Math.random();
this.update = function() {
//星体每次向视口前进一步
this.depth -= _this.towardStep;
if(this.depth < 0) {
this.depth += _this.skyDepth;
}
var scale = 1;
switch(_this.animationSchema) {
case "scheme1":
//设星空最深处的缩放比例是某个系数
scale = _this.skyDepth / this.depth * starScaleRatio;
//半径等于缩放比例
this.radius = scale;
break;
case "scheme2":
//设星空最深处的缩放比例是1
var scale = _this.skyDepth / this.depth;
//半径等于缩放比例乘以某个系数
this.radius = scale * starScaleRatio;
break;
}
this.x = cx + this.offsetX * scale;
this.y = cy + this.offsetY * scale;
}
this.render = function() {
//画布之外和半径太小的点就没必要绘制了
if(isOutCanvas(this.x, this.y) || this.radius < 0.1) {
return;
}
switch(_this.starShape) {
case "square":
ctx.strokeStyle = _this.starColor;
ctx.lineWidth = this.radius * 2;
ctx.beginPath();
ctx.moveTo(this.x - this.radius, this.y);
ctx.lineTo(this.x + this.radius, this.y);
ctx.stroke();
break;
case "circle":
ctx.fillStyle = _this.starColor;
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, doublePI);
ctx.fill();
break;
}
}
}
function update() {
for(var i=0; i<starCount; i++) {
stars[i].update();
}
}
function render() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
for(var i=0; i<starCount; i++) {
stars[i].render();
}
}
function loop() {
update();
render();
requestAnimationFrame(loop);
}
//初始化星空粒子
this.initStar = function() {
cx = canvas.width / 2;
cy = canvas.height / 2;
starCount = Math.round((canvas.width + canvas.height) * starCountRatio);
skyDepthRadius = Math.min(cx, cy) * depthSkySizeRatio;
skyDepthDiameter = 2 * skyDepthRadius;
this.skyDepth = 2 * this.skyDepth;
stars = new Array(starCount);
for(var i=0; i<starCount; i++) {
stars[i] = new StarParticle();
}
loop();
}
}
//当网页大小改变时触发
function onResize() {
canvas.width = document.body.clientWidth;
canvas.height = window.innerHeight;
starSky.initStar();
}
//当设置星星形状
function onStarShapeChange() {
starSky.starShape = event.target.value;
}
//当设置动画的方案
function onStarAnimationSchemeClick() {
starSky.animationSchema = event.target.value;
}
function init() {
starSky = new StarSky();
onResize();
window.addEventListener("resize", onResize);
document.getElementById("bgColor").addEventListener("change", function() {
document.body.style.backgroundColor = event.target.value;
});
document.getElementById("starColor").addEventListener("change", function() {
starSky.starColor = event.target.value;
});
var starShapeRadios = document.getElementsByName("starShapes");
for(var i=0; i<starShapeRadios.length; i++) {
starShapeRadios[i].addEventListener("change", onStarShapeChange);
}
var starAnimationSchemes = document.getElementsByName("starAnimationSchemes");
for(var i=0; i<starAnimationSchemes.length; i++) {
starAnimationSchemes[i].addEventListener("click", onStarAnimationSchemeClick);
}
document.getElementById("towardStepRange").addEventListener("change", function(){
document.getElementById("towardStepTip").innerHTML = "Toward Step:" + event.target.value;
starSky.towardStep = event.target.value;
});
}
init();
</script>
</body>
</html>
JavaScript 朝着群星前进的动态背景
最新推荐文章于 2022-08-10 13:57:00 发布