├── .idea
├── canvasStar.iml
├── modules.xml
└── vcs.xml
├── README.md
├── canvasstar.js
└── index.html
/.idea/canvasStar.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # canvasStar
2 | 自己写的一个少女心满满的canvasStar特效
3 |
4 | ## 使用 canvasstar.js
5 | ### 在 HTML 中创建 canvas 元素
6 | 使用需要在 html 中加入 id 为 canvas 的 canvas,并且需要自己写好 canvas的样式
7 |
8 | ### 引用 `canvasstar.js` 文件
9 | 引用的 `canvasstar.js` 必须在 canvas 元素之后
10 |
11 | ### 创建对象并调用
12 | 创建一个新的`CanvasStar`对象,并且使用`CanvasStar.init()`调用即可
13 |
14 | ```
15 |
19 | ```
20 | ### 修改默认参数
21 | 如果有需要,可以更改默认参数
22 | 默认参数如下:
23 | ```
24 | /*
25 | * @para star_r:star半径系数,系数越大,半径越大
26 | * @para star_alpha:生成star的透明度,star_alpha越大,透明度越低
27 | * @para initStarsPopulation:初始化stars的个数
28 | * @para move_distance:star位移的距离,数值越大,位移越大
29 | * @para dot_r : dot半径系数,系数越大,半径越大
30 | * @para dot_speeds : dots运动的速度
31 | * @para dot_alpha : dots的透明度
32 | * @para aReduction:dot消失条件,透明度小于aReduction时消失
33 | * @para dotsMinDist:dot最小距离
34 | * @para maxDistFromCursor:dot最大距离
35 | *
36 | * */
37 | var config = {
38 | star_r : 3,
39 | star_alpha : 5,
40 | initStarsPopulation : 150,
41 | move_distance : 0.25,
42 | dot_r : 5,
43 | dot_speeds : 0.5,
44 | dot_alpha : 0.5,
45 | dot_aReduction : 0.01,
46 | dotsMinDist : 5,
47 | maxDistFromCursor : 50,
48 | };
49 | ```
50 |
51 | 如需修改,在`CanvasStar.init()`时传入对象的参数
52 | ```
53 |
66 | ```
67 |
--------------------------------------------------------------------------------
/canvasstar.js:
--------------------------------------------------------------------------------
1 | ;(function(undefined) {
2 | "use strict";
3 | var _global;
4 |
5 | /*
6 | * @var star_r:star半径系数,系数越大,半径越大
7 | * @var star_alpha:生成star的透明度,star_alpha越大,透明度越低
8 | * @var initStarsPopulation:初始化stars的个数
9 | * @var move_distance:star位移的距离,数值越大,位移越大
10 | * @var dot_r : dot半径系数,系数越大,半径越大
11 | * @var dot_speeds : dots运动的速度
12 | * @var dot_alpha : dots的透明度
13 | * @var aReduction:dot消失条件,透明度小于aReduction时消失
14 | * @var dotsMinDist:dot最小距离
15 | * @var maxDistFromCursor:dot最大距离
16 | *
17 | * */
18 | var config = {
19 | star_r : 3,
20 | star_alpha : 5,
21 | initStarsPopulation : 150,
22 | move_distance : 0.25,
23 | dot_r : 5,
24 | dot_speeds : 0.5,
25 | dot_alpha : 0.5,
26 | dot_aReduction : 0.01,
27 | dotsMinDist : 5,
28 | maxDistFromCursor : 50,
29 | };
30 | var stars = [],
31 | dots = [],
32 | canvas = document.getElementById('canvas'),
33 | ctx = canvas.getContext('2d'),
34 | WIDTH,
35 | HEIGHT,
36 | mouseMoving = false,
37 | mouseMoveChecker,
38 | mouseX,
39 | mouseY;
40 | function CanvasStar(){}
41 |
42 | var initConfig = function(conf){
43 | if( conf instanceof Object )
44 | for( var item in conf ){
45 | config[item] = conf[item];
46 | }
47 | };
48 |
49 | CanvasStar.prototype.init =function (conf) {
50 | initConfig(conf);//初始化设置
51 |
52 | ctx.strokeStyle = "white";
53 | ctx.shadowColor = "white";
54 | for (var i = 0; i < config.initStarsPopulation; i++) {
55 | stars[i] = new Star(i, Math.floor(Math.random()*WIDTH), Math.floor(Math.random()*HEIGHT),true);
56 | //stars[i].draw();
57 | }
58 | ctx.shadowBlur = 0;
59 | animate();
60 | };
61 |
62 |
63 |
64 | function Star(id, x, y, useCache) {
65 | this.id = id;
66 | this.x = x;
67 | this.y = y;
68 | this.useCacha = useCache;
69 | this.cacheCanvas = document.createElement("canvas");
70 | this.cacheCtx = this.cacheCanvas.getContext("2d");
71 | this.r = Math.floor(Math.random() * config.star_r) + 1;
72 | this.cacheCtx.width = 6 * this.r;
73 | this.cacheCtx.height = 6 * this.r;
74 | var alpha = ( Math.floor(Math.random() * 10) + 1) / config.star_alpha;
75 | this.color = "rgba(255,255,255," + alpha + ")";
76 | if (useCache) {
77 | this.cache()
78 | }
79 | }
80 |
81 | Star.prototype = {
82 | draw : function () {
83 | if (!this.useCacha) {
84 | ctx.save();
85 | ctx.fillStyle = this.color;
86 | ctx.shadowBlur = this.r * 2;
87 | ctx.beginPath();
88 | ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI, false);
89 | ctx.closePath();
90 | ctx.fill();
91 | ctx.restore();
92 | } else {
93 | ctx.drawImage(this.cacheCanvas, this.x - this.r, this.y - this.r);
94 | }
95 | },
96 |
97 | cache : function () {
98 | this.cacheCtx.save();
99 | this.cacheCtx.fillStyle = this.color;
100 | this.cacheCtx.shadowColor = "white";
101 | this.cacheCtx.shadowBlur = this.r * 2;
102 | this.cacheCtx.beginPath();
103 | this.cacheCtx.arc(this.r * 3, this.r * 3, this.r, 0, 2 * Math.PI);
104 | this.cacheCtx.closePath();
105 | this.cacheCtx.fill();
106 | this.cacheCtx.restore();
107 | },
108 |
109 | move : function () {
110 | this.y -= config.move_distance;
111 | if (this.y <= -10) {
112 | this.y += HEIGHT + 10;
113 | }
114 | this.draw();
115 | },
116 |
117 | die : function () {
118 | stars[this.id] = null;
119 | delete stars[this.id]
120 | }
121 | };
122 |
123 | function Dot(id, x, y, useCache) {
124 | this.id = id;
125 | this.x = x;
126 | this.y = y;
127 | this.r = Math.floor(Math.random() * config.dot_r)+1;
128 | this.speed = config.dot_speeds;
129 | this.a = config.dot_alpha;
130 | this.aReduction = config.dot_aReduction;
131 | this.useCache = useCache;
132 | this.dotCanvas = document.createElement("canvas");
133 | this.dotCtx = this.dotCanvas.getContext("2d");
134 | this.dotCtx.width = 6 * this.r;
135 | this.dotCtx.height = 6 * this.r;
136 | this.dotCtx.a = 0.5;
137 | this.color = "rgba(255,255,255," + this.a +")";
138 | this.dotCtx.color = "rgba(255,255,255," + this.dotCtx.a + ")";
139 | this.linkColor = "rgba(255,255,255," + this.a/4 + ")";
140 | this.dir = Math.floor(Math.random()*140)+200;
141 |
142 | if( useCache){
143 | this.cache()
144 | }
145 | }
146 |
147 | Dot.prototype = {
148 | draw : function () {
149 | if( !this.useCache){
150 | ctx.save();
151 | ctx.fillStyle = this.color;
152 | ctx.shadowColor = "white";
153 | ctx.shadowBlur = this.r * 2;
154 | ctx.beginPath();
155 | ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI, false);
156 | ctx.closePath();
157 | ctx.fill();
158 | ctx.restore();
159 | }else{
160 | ctx.drawImage(this.dotCanvas, this.x - this.r * 3, this.y - this.r *3);
161 |
162 | }
163 | },
164 |
165 | cache : function () {
166 | this.dotCtx.save();
167 | this.dotCtx.a -= this.aReduction;
168 | this.dotCtx.color = "rgba(255,255,255," + this.dotCtx.a + ")";
169 | this.dotCtx.fillStyle = this.dotCtx.color;
170 | this.dotCtx.shadowColor = "white";
171 | this.dotCtx.shadowBlur = this.r * 2;
172 | this.dotCtx.beginPath();
173 | this.dotCtx.arc(this.r * 3, this.r * 3, this.r, 0, 2 * Math.PI, false);
174 | this.dotCtx.closePath();
175 | this.dotCtx.fill();
176 | this.dotCtx.restore();
177 | },
178 | link : function () {
179 | if (this.id == 0) return;
180 | var previousDot1 = getPreviousDot(this.id, 1);
181 | var previousDot2 = getPreviousDot(this.id, 2);
182 | var previousDot3 = getPreviousDot(this.id, 3);
183 | var previousDot4 = getPreviousDot(this.id, 4);
184 |
185 |
186 | if (!previousDot1) return;
187 | ctx.strokeStyle = this.linkColor;
188 | ctx.moveTo(previousDot1.x, previousDot1.y);
189 | ctx.beginPath();
190 | ctx.lineTo(this.x, this.y);
191 | if (previousDot2 != false) ctx.lineTo(previousDot2.x, previousDot2.y);
192 | if (previousDot3 != false) ctx.lineTo(previousDot3.x, previousDot3.y);
193 | if (previousDot4 != false) ctx.lineTo(previousDot4.x, previousDot4.y);
194 |
195 | ctx.stroke();
196 | ctx.closePath();
197 | },
198 |
199 | move : function () {
200 |
201 |
202 | this.a -= this.aReduction;
203 | if(this.a <= 0 ){
204 | this.die();
205 | return
206 | }
207 | this.dotCtx.a -= this.aReduction;
208 | this.dotCtx.color = "rgba(255,255,255," + this.dotCtx.a + ")";
209 | this.color = "rgba(255,255,255," + this.a + ")";
210 | this.linkColor = "rgba(255,255,255," + this.a/4 + ")";
211 | this.x = this.x + Math.cos(degToRad(this.dir)) * this.speed;
212 | this.y = this.y + Math.sin(degToRad(this.dir)) * this.speed;
213 |
214 | this.draw();
215 | this.link();
216 |
217 | },
218 |
219 | die : function () {
220 | dots[this.id] = null;
221 | delete dots[this.id];
222 | }
223 | };
224 |
225 | window.onmousemove = function (e) {
226 | mouseMoving = true;
227 | mouseX = e.clientX;
228 | mouseY = e.clientY;
229 | clearInterval(mouseMoveChecker);
230 | mouseMoveChecker = setInterval(function () {
231 | mouseMoving = false
232 | },1000)
233 |
234 | };
235 |
236 | function drawIfMouseMoving() {
237 | if (!mouseMoving) return;
238 |
239 | if (dots.length == 0) {
240 | dots[0] = new Dot(0, mouseX, mouseY,true);
241 | dots[0].draw();
242 | return;
243 | }
244 |
245 | var previousDot = getPreviousDot(dots.length, 1);
246 | var prevX = previousDot.x;
247 | var prevY = previousDot.y;
248 |
249 | var diffX = Math.abs(prevX - mouseX);
250 | var diffY = Math.abs(prevY - mouseY);
251 |
252 | if (diffX < config.dotsMinDist || diffY < config.dotsMinDist) return;
253 |
254 | var xVariation = Math.random() > .5 ? -1 : 1;
255 | xVariation = xVariation*Math.floor(Math.random() * config.maxDistFromCursor)+1;
256 | var yVariation = Math.random() > .5 ? -1 : 1;
257 | yVariation = yVariation*Math.floor(Math.random() * config.maxDistFromCursor)+1;
258 | dots[dots.length] = new Dot(dots.length, mouseX+xVariation, mouseY+yVariation,true);
259 | dots[dots.length-1].draw();
260 | dots[dots.length-1].link();
261 | }
262 |
263 | function getPreviousDot(id, stepback) {
264 | if(id == 0 || id - stepback < 0){
265 | return false
266 | }
267 | if(typeof dots[id - stepback] !== "undefined"){
268 | return dots[id - stepback]
269 | }else{
270 | return false
271 | }
272 | }
273 |
274 | function setCanvasSize() {
275 | WIDTH = document.documentElement.clientWidth;
276 | HEIGHT = document.documentElement.clientHeight;
277 | canvas.setAttribute("width", WIDTH);
278 | canvas.setAttribute("height", HEIGHT);
279 |
280 | }
281 |
282 | function animate() {
283 | ctx.clearRect(0, 0, WIDTH, HEIGHT);
284 |
285 | for (var i in stars) {
286 | stars[i].move();
287 | }
288 | for (var i in dots) {
289 | dots[i].move();
290 | }
291 | drawIfMouseMoving();
292 | requestAnimationFrame(animate);
293 | }
294 |
295 | function degToRad(deg) {
296 | return deg * (Math.PI / 180);
297 | }
298 |
299 | setCanvasSize();
300 |
301 |
302 |
303 | // 最后将插件对象暴露给全局对象
304 | _global = (function(){ return this || (0, eval)('this'); }());
305 | if (typeof module !== "undefined" && module.exports) {
306 | module.exports = CanvasStar;
307 | } else if (typeof define === "function" && define.amd) {
308 | define(function(){return CanvasStar;});
309 | } else {
310 |
311 | !('CanvasStar' in _global) && (_global.CanvasStar = CanvasStar);
312 | }
313 |
314 |
315 | })();
316 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Title
6 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
54 |
55 |
--------------------------------------------------------------------------------