仿Google+的Circle功能

http://www.circlehack.com/ (qiang外)是facebook四个工程师通宵一晚上的成果,体验和效果上和Google+中的circle相比还是逊色一些

整个源代码在github上https://github.com/voloko/facebook-circles

circlehack.com中的示例截图(都是使用CSS3来画圈):

image

Google+的示例截图(使用图片+Canvas,动画、过渡效果明显比上面要好,复杂度比上面实现要高):

image

下面就是Google+用到的图片

image

 

我把它抽离出一个demo出来,点击链接可以在线查看示例(需要使用 支持CSS3的浏览器查看,建议使用Chrome):

http://fiddle.jshell.net/meteoric_cry/2szaD/show/

 

实现上述的效果,里面应用了很多CSS3的属性,这样就减少了很多对DOM的操作,完整的代码如下:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>~circlehack~</title>
<meta name="generator" content="editplus" />
<meta name="author" content="" />
<meta name="keywords" content="" />
<meta name="description" content="" />
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<style type="text/css">
body, html {width: 100%; height: 100%; padding: 0; margin: 0; font-family: arial, sans-serif;}
[draggable] {-webkit-user-drag: element;}


.circle {color: #FFF; width: 125px; height: 125px; position: relative; margin: 35px;}
.circle__disk {border: 1px solid #CCC; border-radius: 200px; position: absolute; width: 124px; height: 124px; top: 50%; left: 50%; margin-left: -62px; margin-top: -62px; z-index: 2; -webkit-transition-property: width, height, margin-left, margin-top; -webkit-transition-duration: 0.3s; -moz-transition-property: width, height, margin-left, margin-top; -moz-transition-duration: 0.3s; background: -webkit-gradient(linear, left top, left bottom, from(#ededed), to(#d7d7d7));}
.circle__disk {background: -webkit-linear-gradient(top, #ededed 0%, #d7d7d7 100%);}
.circle__disk {background: -moz-linear-gradient(top, #ededed 0%,#d7d7d7 100%);}
.circle_full.circle_tmp .circle__disk, .circle_over .circle__disk {width: 170px; height: 170px; margin-left: -85px; margin-top: -85px; background: #e1e1e1;}
.circle__inner {background: #4797cf; border-radius: 70px; box-shadow: inset 0 1px 1px rgba(0,0,0,0.3); border-bottom: 1px solid #FFF; width: 98px; height: 98px; position: absolute; top: 50%; left: 50%; margin-left: -49px; margin-top: -49px; z-index: 3;}
.circle_tmp .circle__inner {background: #FFF;}
.circle__text {position: absolute; z-index: 4; top: 50%; left: 50%; width: 98px; text-align: center; font-size: 13px; margin-top: -13px; margin-left: -49px; color: #999;}
.circle__create {position: absolute; z-index: 4; top: 50%; left: 50%; width: 98px; text-align: center; font-size: 13px; margin-top: -7px; margin-left: -49px; color: #309;}
.circle__create__a {text-decoration: underline; color: #30C; cursor: pointer;}
.circle__create__a:hover {color: #C03;}
.circle_empty .circle__create {display: none;}
.circle_full .circle__text {display: none;}
.circle_tmp .circle__number, .circle_tmp .circle__name {display: none;}
.circle__number {position: absolute; top: 50%; width: 98px; text-align: center; font-size: 16px; margin-top: 5px; opacity: 0.5;}
.circle__name {position: absolute; bottom: 50%; width: 98px; text-align: center; font-size: 13px;}
.circleFriend {position: absolute; left: 50%; top: 50%; border-radius: 30px; z-index: 4; opacity: 0; width: 30px; height: 30px; -webkit-transition-property: opacity; -webkit-transition-duration: 0.3s; -moz-transition-property: opacity; -moz-transition-duration: 0.3s;}
.circle_full.circle_tmp .circleFriend, .circle_over .circleFriend {-webkit-transition-delay: .1s; -moz-transition-delay: .1s; opacity: 1;}
.circle__popup {position: absolute; width: 32px; height: 32px; border-radius: 32px; z-index: 300; left: 50%; top: 50%; margin-top: 40px; margin-left: 60px; -webkit-transition-property: opacity, margin-top, margin-left; -webkit-transition-duration: 0.7s; -moz-transition-property: opacity, margin-top, margin-left; -moz-transition-duration: 1s; opacity: 0; text-align: center; line-height: 32px; color: #FFF; font-size: 15px;}
.circle__popup_red {background: -webkit-gradient(linear, left top, left bottom, from(#d20040), to(#d20040));}
.circle__popup_red {background: -webkit-linear-gradient(top, #d20040 0%, #ae0035 100%);}
.circle__popup_red {background: -moz-linear-gradient(top, #d20040 0%, #ae0035 100%);}
.circle__popup_green {background: -webkit-gradient(linear, left top, left bottom, from(#00d240), to(#00d240));}
.circle__popup_green {background: -webkit-linear-gradient(top, #00d240 0%, #00ae35 100%);}
.circle__popup_green {background: -moz-linear-gradient(top, #00d240 0%, #00ae35 100%);}
.circle__popup_phase1 {margin-top: -60px; margin-left: 30px; opacity: 1;}
.circle__popup_phase2 {opacity: 0;}

#test {margin:100px;}
button {width:100px; height:32px; margin-left:50px; cursor:pointer; background:-webkit-linear-gradient(top, #EEE 0%, #BBB 100%); border:1px solid #666;}
</style>

</head>

<body>


<div class="circle circle_full" id="test">
<div class="circle__disk"></div>
<div class="circle__inner">
<div class="circle__name">测试1</div>
<div class="circle__number" id="friend_num">0</div>
</div>
</div>

<button>add Frient</button>

<script type="text/javascript">
function getEl(id) {
return typeof id === 'string' ? document.getElementById(id) : id;
}

getEl("test").onmouseover = function() {
this.className = "circle circle_full circle_over";
};

getEl("test").onmouseout = function() {
this.className = "circle circle_full";
};

var index = 0;
document.getElementsByTagName("button")[0].onclick = function() {
if (index >= 12) {
this.disabled = true;
return ;
}

var img = document.createElement("img");

img.className = "image circleFriend";
img.src = [
'http://profile.ak.fbcdn.net/hprofile-ak-snc4/41487_691724478_6265_q.jpg',
'http://profile.ak.fbcdn.net/hprofile-ak-snc4/41531_851335273_3046447_q.jpg',
'http://profile.ak.fbcdn.net/hprofile-ak-snc4/211978_100001174061425_2365381_q.jpg',
'http://profile.ak.fbcdn.net/hprofile-ak-snc4/70365_794569104_6244312_q.jpg',
'http://profile.ak.fbcdn.net/hprofile-ak-snc4/273926_1023602453_4918544_q.jpg',
'http://profile.ak.fbcdn.net/hprofile-ak-snc4/41388_668019731_9699_q.jpg',
'https://fbcdn-profile-a.akamaihd.net/hprofile-ak-snc4/276415_6815841748_4775941_q.jpg',
'https://fbcdn-profile-a.akamaihd.net/hprofile-ak-snc4/275680_100001553835190_4022025_q.jpg',
'http://profile.ak.fbcdn.net/hprofile-ak-snc4/41487_691724478_6265_q.jpg',
'http://profile.ak.fbcdn.net/hprofile-ak-snc4/275688_100001963685246_6575661_q.jpg',
'http://profile.ak.fbcdn.net/hprofile-ak-snc4/274603_100002541323180_733311_q.jpg',
'http://profile.ak.fbcdn.net/hprofile-ak-snc4/186196_1223485640_4353838_q.jpg'
][index];

var b = 2 * Math.PI / 12 * index,
c = 67,
d = Math.sin(b) * c,
e = -Math.cos(b) * c;

img.style.marginLeft = d - 15 + "px";
img.style.marginTop = e - 15 + "px";

getEl("test").appendChild(img);
getEl("test").onmouseover();

var rect = getEl("test").getBoundingClientRect(),
tip = document.createElement("div");

tip.innerHTML = (index % 2 === 0) ? "-1" : "+1";
tip.className = (index % 2 === 0 ? "circle__popup_red" : "circle__popup_green") + " circle__popup";
tip.style.cssText = "left: " + rect.left + "px; top: " + rect.top + "px";
document.body.appendChild(tip);

setTimeout(function() {
tip.className += " circle__popup_phase1";

tip._timer = setTimeout(function() {
tip.className += " circle__popup_phase2";
setTimeout(function() {
document.body.removeChild(tip);
tip = null;
}, 700);
}, 700);
}, 1);

getEl("friend_num").innerHTML = ++index;
};
</script>

</body>
</html>

posted @ 2011-08-02 13:00  meteoric_cry  阅读(1060)  评论(0编辑  收藏  举报