星星相CODE——JS制作网页动画





本篇继续上一篇日志,用JS写了一个简短而有意义的动画,紧扣本次百度之星的主题:星星相CODE。
上一篇日志讲了如何用数学函数绘制百度之星,有了这个函数,我们可以随意的在它基础上大做文章。让星星和另外的某个图像相互变型就是一个很好的例子,例如由圆形变型到星星,由心型变型到星星等。
这里我们让星星上的点从网页的四周边缘聚集到网页的正中心。而星星上的点就用0和1来代替,有二进制的味道,凸现程序和CODE的特征。
首先利用上一篇日志中给出的函数,计算星星上的若干点,然后记录下他们的位置。然后同样利用极角计算出网页四周边缘上的点的位置。这样每个点的任务就是从网页边缘移动到星星上的对应位置。这里利用setInterval函数实现定时移动。用一个变量来控制每次移动的步伐大小。并且为了更加有动感,在移动的过程中,每个点上的数字会随机的在0和1之间变动,当然不能变动太快否则会弄晕自己^_^
在移动结束后,用clearInterval删除定时器,并且在页面正中央显示主题“星星相CODE”。
这个动画很简短,首先暗示了程序员和代码从四面八方聚集起来,并汇集到一起;其次表达出他们聚集后产生了“百度之星”,而每一个CODE都是百度之星的一员;最后突出主题“星星相CODE”。
JS代码的兼容性是比较有难度的。这里我们已经在IE8, Firefox4 和Chrome 7上做过测试,均可以正常显示。
为方便观看,我录制了一段GIF如下:

下面也同时附上源代码。可以复制粘贴到任意空白文件中,重命名为html为后缀的文件,打开即可观赏。

本文同时发在百度贴吧,欢迎顶帖支持。http://tieba.baidu.com/f?kz=1089943334

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
<body></body>
<script>
var STAR_SIZE = 150;
var POINT_SIZE = 5;
var POINTS_PER_STAR = 127;
var STEP = 100;
 
var center_x;
var center_y;
var pageWidth;
var pageHeight;
var pageLeft;
var pageTop;
var starWord = "<div>&#26143;&#26143;&#30456;</div><div>CODE</div>";
 
 
pageLeft = document.documentElement.scrollLeft;
pageTop = document.documentElement.scrollTop;
 
pageWidth = document.body.clientWidth;
pageHeight = document.body.clientHeight;
 
center_x = pageWidth / 2 + pageLeft;
center_y = pageHeight / 2 + pageTop;
 
function f(t) {
    return Math.abs(t-(Math.floor((t+Math.PI/10)/(Math.PI*2/5))*Math.PI*2/5+Math.PI/10));
}
 
function g(t) {
    return Math.floor(f(t) / (Math.PI/10));
}
 
function h(r, t) {
    return r*((1 - g(t)) / Math.cos(f(t)) + g(t)/Math.cos(Math.PI/10)*(Math.pow((Math.PI/10)/f(t), 1.5)));
}
 
function getStar(x, y, r, num) {
    this.x = new Array(num);
    this.y = new Array(num);
    for (var i = 0; i < num; i++) {
        var t = Math.PI * 2 * i / num;
        var l = h(r, t);
        this.x[i] = x + l * Math.cos(-t);
        this.y[i] = y + l * Math.sin(-t);
    }
    return this;
}
 
function drawDot(id, x, y, size)
{
    var num;
    if (Math.random() > 0.5) num = 1;
    else num = 0;
 
    var div = "<div id='baiduStar"+i+"' style='font-weight:bold;font-size:10pt;color:red;position:absolute; border:0;left:"+(x) +"; top:" +(y)+ ";width:"+size+";height:"+size+";'>"+num+"</div>";
    return div;
}
 
function getRectangle(x0, y0, w, h, num) {
    var cx = x0 + w / 2;
    var cy = y0 + h / 2;
    this.ox = new Array();
    this.oy = new Array();
    var theta = Math.atan(h / w);
    for (var i = 0; i < num; i++) {
        var t = Math.PI * 2 * i / num;
        if (t <= theta || t >= 2 * Math.PI - theta) {
            this.ox[i] = x0 + w;
            this.oy[i] = cy - Math.tan(t) * w / 2;
        }
        else if (t >= theta && t <= Math.PI - theta) {
            this.ox[i] = cx + Math.tan(Math.PI / 2 - t) * h / 2;
            this.oy[i] = y0;
        }
        else if (t >= Math.PI - theta && t <= Math.PI + theta) {
            this.ox[i] = x0;
            this.oy[i] = cy - Math.tan(Math.PI - t) * w / 2;
        }
        else if (t >= Math.PI + theta && t <= Math.PI * 2 - theta) {
            this.ox[i] = cx - Math.tan(Math.PI * 3 / 2 - t) * h / 2;
            this.oy[i] = y0 + h;
        }
    }
    return this;
}
 
var star = getStar(center_x, center_y, STAR_SIZE, POINTS_PER_STAR);
var rectangle = getRectangle(pageLeft, pageTop, pageWidth, pageHeight, POINTS_PER_STAR);
 
 
var px;
px = new Array();
py = new Array();
 
for (var i = 0; i < POINTS_PER_STAR; i++) {
    px[i] = rectangle.ox[i];
    py[i] = rectangle.oy[i];
}
 
var alldiv = '';
 
for (var i = 0; i < POINTS_PER_STAR; i++) {
    var div = drawDot(i, rectangle.ox[i], rectangle.oy[i], POINT_SIZE);
    alldiv += div;
}
 
document.body.innerHTML = "<div>"+alldiv+"</div>";
 
function sign(i) {
    if (i > 0) return 1;
    if (i < 0) return -1;
    return 0;
}
 
function check_star() {
    for (var i = 0; i < POINTS_PER_STAR; i++) {
        if (px[i] != star.x[i]) return false;
        if (py[i] != star.y[i]) return false;
    }
    return true;
}
 
function move() {
    for (var i = 0; i < POINTS_PER_STAR; i++) {
        var step_x = (star.x[i] - rectangle.ox[i]) / STEP;
        var step_y = (star.y[i] - rectangle.oy[i]) / STEP;
        px[i] += step_x;
        if ((px[i] - star.x[i]) * (rectangle.ox[i] - star.x[i]) < 0) px[i] = star.x[i];
        py[i] += step_y;
        if ((py[i] - star.y[i]) * (rectangle.oy[i] - star.y[i]) < 0) py[i] = star.y[i];
 
        var e = document.getElementById("baiduStar"+i);
 
        e.style.left = (px[i]);
        e.style.top = (py[i]);
        if (Math.random() >= 0.8) {
            e.innerHTML = 1 - parseInt(e.innerHTML);
        }
    }
 
    if (check_star()) {
        document.body.innerHTML += "<div style='position:absolute;left:"+pageLeft+";top:"+(pageTop+pageHeight/2-20)+";width:"+pageWidth+";text-align:center;color:red;font-size:20pt'>" + starWord + "</div>";
        clearInterval(starTimer);
    }    
 
}
 
var starTimer = setInterval(move, 40);
</script>
本文来自Dora Blog,题目为星星相CODE——JS制作网页动画,转载请注明出处。
如果你喜欢我的博客,请订阅本博客的RSS以更方便的阅读
欢迎关注我的新浪微博:http://weibo.com/diaorui1987