细说css3的动画(4)鼠标处弹出旋转菜单demo
css3手工绘制旋转菜单
下面是css代码:
.box {
text-align: center;
width: 1000px;
height: 600px;
border: 1px solid black;
}
.border {
visibility: hidden;
/*
position:关于absolute绝对定位和absolute相对定位
1、position只作用于当前的div
2、如果要用坐标随时控制当前的div的位置,则使用absolute
3、如果absolute的div内部有relative,则不会有影响,并且内部的div相对于外部的div定位
4、外部如果用了absolute,内部最好加上relative,否则当内部div继承外部absolute时,调试会很麻烦
5、absolute最完美的搭配是用left、top来控制控件的位置,而不要用transform:translate(x,y),后者会被其他div挤到其他位置
*/
position:absolute;
}
.border .spritemenu .spritemenu_sub_child {
transform:rotate(-90deg);
text-align:center;
line-height:50px;
width:50px;
height:50px;
opacity:0; //透明度
animation-duration: 2s;
animation-timing-function: ease;
animation-iteration-count: 1;
animation-delay:1s;
animation-fill-mode:forwards;
}
@keyframes _text_out_ {
from{opacity:0;}to{opacity:1;}
}
@keyframes _text_in_ {
from{opacity:1;}to{opacity:0;}
}
/*整体旋转动画*/
.border .spritemenu {
width:52px;
height:52px;
border: 1px solid transparent;
animation-duration: 2s;
animation-timing-function: ease;
animation-iteration-count: 1;
animation-fill-mode:forwards;
/*animation-name: _rotate_;*/
}
/*展开时旋转*/
@keyframes _rotate_out_ {
100%{
transform:rotate(90deg);
}
}
/*收回时旋转*/
@keyframes _rotate_in_ {
100%{
transform:rotate(-90deg);
visibility:hidden;
}
}
/*菜单的每个按钮范定义*/
.border .spritemenu .spritemenu_sub_box {
position: relative;
width:50px;
height:50px;
border:1px solid transparent;
border-radius: 2em;
animation-duration: .5s;
animation-timing-function: ease;
animation-iteration-count: 1;
animation-fill-mode:forwards;
cursor:pointer;
}
/*自定义光标*/
.mousecur {
position:absolute;
visibility: hidden;
width:50px;
height:50px;
border:1px solid transparent;
border-radius:5em;
/*
filter:alpha(opacity=30);
-moz-opacity:0.3;
-khtml-opacity:0.3;
*/
opacity:.3;
animation-duration: 2s;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-name: _mousecur_;
}
@keyframes _mousecur_ {
0%{}
12.5%{background-color:#DCB5FF}
25%{background-color:#ACD6FF}
37.5%{background-color:#BBFFBB}
50%{background-color:#FFFFAA}
62.5%{background-color:#FFBB77}
75%{background-color:#CF9E9E}
87.5%{background-color:#CDCD9A}
100%{background-color:#FF9797}
}
下面是js代码:
var example = function() {};
example.prototype = {
initDiv: function() {
var border = document.createElement('div');
border.setAttribute('class','border');
border.innerHTML = '<div class="spritemenu"></div>';
document.body.appendChild(border);
var mousecur = document.createElement('div');
mousecur.setAttribute('class','mousecur');
document.body.appendChild(mousecur);
},
createDiv: function(cnt,cls) {
for(i=0;i<cnt;i++){
//创建统dom
var n = document.createElement('div');
n.setAttribute('class',cls+'_sub_box '+cls+'_sub_box_'+(i+1));
document.getElementsByClassName(cls)[0].appendChild(n);
var n1 = document.createElement('div');
n1.setAttribute('class',cls+'_sub_child '+cls+'_sub_child_'+(i+1));
n.appendChild(n1);
}
},
//添加伪类样式string
addCssValText : function(styleid,text) {
s=document.getElementById(styleid);
if(!s){
s=document.createElement('style');
s.setAttribute('id',styleid);
}
s.innerText+=text;
document.body.appendChild(s);
},
//重写样式
rewirteCssValText : function(styleid,text) {
s=document.getElementById(styleid);
if(!s){
s=document.createElement('style');
s.setAttribute('id',styleid);
}
s.innerText=text;
document.body.appendChild(s);
}
}
var aaa = new example();
aaa.initDiv();
aaa.createDiv(8,"spritemenu");
/*x轴标尺添加文字 */
var word = {"anim1":"b1","anim2":"b2","anim3":"b3","anim4":"b4","anim5":"b5","anim6":"b6","anim7":"b7","anim8":"b8"};
for(i=1;i<=8;i++){
document.getElementsByClassName('spritemenu_sub_child')[i-1].innerText = word['anim'+i];
}
var color = {"anim1":"#FF9797","anim2":"#DCB5FF","anim3":"#ACD6FF","anim4":"#BBFFBB","anim5":"#FFFFAA","anim6":"#FFBB77","anim7":"#CF9E9E","anim8":"#CDCD9A"};
var radius = 70;//半径
var round = 9;//圆环度
var movedown = 50;//下移量
var pasitionX = [ 0,
-(2*radius)/(Math.sqrt(2)+2)-(radius/round),
-radius,
-(2*radius)/(Math.sqrt(2)+2)-(radius/round),
0,
+(2*radius)/(Math.sqrt(2)+2)+(radius/round),
+radius,
+(2*radius)/(Math.sqrt(2)+2)+(radius/round)
];
var pasitionY = [ -radius,
-(2*radius)/(Math.sqrt(2)+2)-(radius/round),
0,
+(2*radius)/(Math.sqrt(2)+2)+(radius/round),
+radius,
+(2*radius)/(Math.sqrt(2)+2)+(radius/round),
0,
-(2*radius)/(Math.sqrt(2)+2)-(radius/round)
];
var relative = new Array;
//设置初始位置
var style = "";
var sub_height = 0;
for(i=1;i<=8;i++){
style += ".border .spritemenu .spritemenu_sub_box_"+i+"{";
style += "transform: translateY(-"+sub_height+"px);}";
sub_height += 52; //圆的直径+边距
relative[i-1] = sub_height;
}
//动画设置
for(i=1;i<=8;i++){
style += ".border .spritemenu .spritemenu_sub_box_"+i+"{";
//style += "animation-delay:"+(0.5-i/20)+"s;";
style += "}";
//弹出动画
style += "@keyframes _out_"+i+"{";
style += "0%{transform: translate(0px,"+(-relative[i-1]+movedown)+"px);";
style += "filter:alpha(opacity=0);-moz-opacity:0;-khtml-opacity:0;opacity:0;}"; //透明度
style += "100%{transform: translate("+(pasitionX[i-1])+"px,"+(pasitionY[i-1]-relative[i-1]+movedown)+"px);";
style += "filter:alpha(opacity=100);-moz-opacity:1;-khtml-opacity:1;opacity:1;}}"; //透明度
//收回动画
style += "@keyframes _in_"+i+"{";
style += "0%{transform: translate("+(pasitionX[i-1])+"px,"+(pasitionY[i-1]-relative[i-1]+movedown)+"px);";
style += "filter:alpha(opacity=100);-moz-opacity:1;-khtml-opacity:1;opacity:1;}"; //透明度
style += "100%{transform: translate(0px,"+(-relative[i-1]+movedown)+"px);";
style += "filter:alpha(opacity=0);-moz-opacity:0;-khtml-opacity:0;opacity:0;}}"; //透明度
}
aaa.addCssValText("css",style);
//鼠标右键触发事件
aaa.showflag = false;
document.body.oncontextmenu = function(env) {
if(!aaa.showflag) {
aaa.showflag = true;
style = "";
style += ".border .spritemenu {visibility: visible;}";
//style += ".border {";
//style += "transform:translate("+(env.pageX-32)+"px,"+(env.pageY-32)+"px);}";
style += ".border {left:"+(env.pageX-32)+";top:"+(env.pageY-32)+";}"; //用top和left来控制位置
for(i=1;i<=8;i++){
style += ".border .spritemenu .spritemenu_sub_box_"+i+"{";
style += "animation-name: _out_"+i+";}";
}
style += ".border .spritemenu {"
style += "animation-name: _rotate_out_;}";
style += ".border .spritemenu .spritemenu_sub_child {";
style += "animation-name: _text_out_;}";
aaa.rewirteCssValText("css1",style);
}
return false; //屏蔽鼠标右键
}
//鼠标左键触发事件
document.body.onclick = function(env) {
aaa.showflag = false;
style = "";
for(i=1;i<=8;i++){
style += ".border .spritemenu .spritemenu_sub_box_"+i+"{";
style += "animation-name: _in_"+i+";}";
}
style += ".border .spritemenu {";
style += "animation-name: _rotate_in_;}";
style += ".border .spritemenu .spritemenu_sub_child {";
style += "animation-name: _text_in_;}";
aaa.addCssValText("css1",style);
}
//取消鼠标箭头
//document.body.style.cursor = "none";
//设置新的鼠标箭头
document.body.onmousemove = function(env) {
style = "";
style += ".mousecur {visibility: visible;}";
//style += "transform:translate("+(env.pageX-90)+"px,"+(env.pageY-140)+"px);}";
style += ".mousecur {left:"+(env.pageX-30)+";top:"+(env.pageY-30)+";}";//用top和left来控制位置
aaa.rewirteCssValText("css2",style);
}
//当鼠标移出窗口时隐藏
document.body.onmouseout = function(env) {
style = "";
style += ".mousecur {visibility: hidden;}";
aaa.addCssValText("css2",style);
}
有个问题,当div旋转的时候,里面的文字也跟随旋转,而我的策略是在class=spritemenu_sub_box的div下嵌套一个spritemenu_sub_child的div来填充文字,让其以反方向旋转,这么做感觉很繁琐,如果有好办法的兄弟们不吝赐教哈~~