JavaScript 带粒子效果的进度条
【摘要】
<html>
<head>
<meta charset="utf8"/>
<!--
<meta na...
<html>
<head>
<meta charset="utf8"/>
<!--
<meta name="viewport" content="width=device-width,user-scalable=no, initial-scale=1, maximum-scale=1" />
-->
<title>粒子效果实战</title>
<style type="text/css">
body {
background:#111;
}
#canvas {
background:transparent;
border:1px dashed #171717;
margin:-151px 0 0 -401px;
position:absolute;
left:50%;
top:50%;
}
</style>
</head>
<body onload="init()">
<canvas id="canvas" width="800px" height="300px">浏览器不支持canvas</canvas>
<script type="text/javascript">
//判断是否支持canvaas
function isSupportCanvas(canvas) {
return !!(canvas.getContext && canvas.getContext("2d"));
}
//requestAnimationFrame会自动使用最优的帧率进行渲染
function setupRAF() {
window.lastTime = 0;
//兼容各个浏览器,Internet Explorer11、Google Chrome(Microsoft Edge)、Mozilla Firefox、Opera
var vendors = ["ms", "moz", "webkit", "o"];
for(var i=0; i<vendors.length; i++) {
window.requestAnimationFrame = window[vendors[i] + "RequestAnimationFrame"];
window.cancelAnimationFrame = window[vendors[i] + "CancelAnimationFrame"] || window[vendors[i] + "CancelRequestAnimationFrame"];
//测试浏览器支持哪一张
if(window.requestAnimationFrame) {
console.log(vendors[i] + "requestAnimationFrame");
}
if(window[vendors[i] + "CancelAnimationFrame"]) {
console.log(vendors[i] + "CancelAnimationFrame");
}
if(window[vendors[i] + "CancelRequestAnimationFrame"]) {
console.log(vendors[i] + "CancelRequestAnimationFrame");
}
}
//回退机制
if(!window.requestAnimationFrame) {
window.requestAnimationFrame = function(callback, element) {
var currentTime = new Date().getTime();
var timeToCall = Math.max(0, 16-(currentTime-window.lastTime));
var callTime = currentTime + timeToCall;
var id = window.setTimeout(function() {
callback(callTime);
}, timeToCall);
window.lastTime = callTime;
return id;
};
}
//回退机制
if(!window.cancelAnimationFrame) {
window.cancelAnimationFrame = function(id) {
clearTimeout(id);
}
}
}
//在[min, max]中随机取一个数
function rand(min, max) {
return Math.random() * (max - min + 1) + min;
}
//判断两碰撞盒是否相交
function isHit(x1, y1, w1, h1, x2, y2, w2, h2) {
return !( x1 + w1 < x2 || x2 + w2 < x1 || y1 + h1 < h2 || y2 + h2 < h1);
}
//判断点是否在指定区域内
function isInRect(x, y, rx, ry, rw, rh) {
return !(x < rx || x > rx + rw || y < ry || y > ry + rh);
}
//将数限制在某个范围之内
function limit(value, min, max) {
if(value < min) {
return min;
} else if(value > max) {
return max;
}
return value;
}
var CanvasController = function(canvas) {
var ctx = canvas.getContext("2d");
//进度条对象
var Loader = function() {
//进度条宽度
this.width = canvas.width - 80;
//进度条高度
this.height = 20;
//进度条X坐标
this.x = (canvas.width - this.width) / 2;
//进度条Y坐标
this.y = (canvas.height - this.height) / 2;
//进度条当前值
this.value = 0;
//进度条最大值
this.maxValue = 100;
//进度条更新速度
this.speed = .5;
//加深的颜色
this.lighterColor = "#222";
//HSL(Hue:色相,Saturation:饱和度,Lightness:饱和度)
this.hue = 0;
this.hueStart = 0;
this.hueEnd = 360;
//获取当前值对应的X坐标
this.currentPosX = function() {
return this.x + this.width * this.value / 100;
}
//更新进度条
this.update = function() {
this.value += this.speed;
if(this.value > this.maxValue) {
this.value = 0;
}
}
//渲染进度条
this.render = function() {
ctx.globalCompositeOperation = "source-over";
var currentWidth = this.width * this.value / 100;
this.hue = this.hueStart + (this.hueEnd - this.hueStart) * this.value / 100;
//ctx.fillStyle = "hsl(" + this.hue + ", 100%, 40%)";
var linearGradient = ctx.createLinearGradient(this.x, this.y, this.x + currentWidth, this.y);
linearGradient.addColorStop(0, "hsl(" + this.hueStart + ", 100%, 40%)");
linearGradient.addColorStop(1, "hsl(" + this.hue + ", 100%, 40%)");
ctx.fillStyle = linearGradient;
ctx.fillRect(this.x, this.y, currentWidth, this.height);
ctx.fillStyle = this.lighterColor;
ctx.globalCompositeOperation = "lighter";
ctx.fillRect(this.x, this.y, currentWidth, this.height/2);
}
}
//单个粒子对象
var Particle = function(x, y, hue, minX, maxX) {
//粒子的X坐标
this.x = x;
//粒子的Y坐标
this.y = y;
//粒子的宽度
this.width = rand(1,3);
//粒子的高度
this.height = rand(1,2);
//粒子的HSL颜色的hue分量
this.hue = limit(hue + rand(-15,15), 0, 360);
//粒子在X方向上的速度
this.velocityX = rand(-1,1);
//粒子在Y方向上的速度
this.velocityY = rand(-30,-20);
//粒子在X方向上的加速度
this.accelerationX = -.5;
//粒子在Y方向上的加速度
this.accelerationY = 4;
//单位时间
this.unitTime = .2;
//更新粒子位置
this.update = function() {
this.x += (this.velocityX * this.unitTime);
this.y += (this.velocityY * this.unitTime);
this.velocityX += (this.accelerationX * this.unitTime * rand(-1,1));
this.velocityY += (this.accelerationY * this.unitTime);
}
//渲染粒子
this.render = function() {
ctx.fillStyle = "hsl(" + this.hue + ", 100%, 40%)"
ctx.globalCompositeOperation = "source-over";
ctx.fillRect(this.x, this.y, this.width, this.height);
}
}
//所有粒子效果的对象
var Particles = function(minX, maxX) {
//存放生成的所有粒子对象
this.values = [];
//粒子生成速率
this.rate = 3;
//生成粒子
this.generate = function(x, y, hue) {
for(var i=0; i<this.rate; i++) {
this.values.push(new Particle(x, y, hue, minX, maxX));
}
}
//更新进度值
this.update = function() {
for(var i = this.values.length-1; i >= 0; i--) {
this.values[i].update();
if(!isInRect(this.values[i].x, this.values[i].y, 0, 0, canvas.width, canvas.height)) {
this.values.splice(i, 1);
}
}
}
//渲染进度条
this.render = function() {
for(var i =0; i<this.values.length; i++) {
this.values[i].render();
}
}
}
//清空画布
function clearCanvas() {
//默认值,表示图形将绘制在现有画布之上
ctx.globalCompositeOperation = "source-over";
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
//初始化函数
this.init = function() {
var loader = new Loader();
var particles = new Particles(loader.x, loader.x + loader.width);
var loop = function() {
requestAnimationFrame(loop, canvas);
clearCanvas();
loader.update();
loader.render();
particles.generate(loader.currentPosX()-3, loader.y + loader.height/2, loader.hue);
particles.update();
particles.render();
}
loop();
}
}
function init() {
var canvas = document.getElementById("canvas");
if(!isSupportCanvas(canvas)) {
return;
}
setupRAF();
var canvasController = new CanvasController(canvas);
canvasController.init();
}
</script>
</body>
</html>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
文章来源: blog.csdn.net,作者:福州-司马懿,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/chy555chy/article/details/54177665
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)