项目实例
运用 snap.js做一个360 旋转的动画, Ie除了第一次循环正常外,其他的旋转都会失效,且产生缩小闪现的效果。
直接上代码
效果图


问题代码,ie9-- ie10 都会出现闪现问题
/**
* Created by wuwg on 2016/11/1 0001.
*/
+function () {
var svg=Snap('#svg');
svg.attr({
width:640,
height:640,
viewBox:'0 0 640 640'
});
var _opts={
category:{
// 审判执行 1
spzx:{
title:"审判执行",
name:"spzx",
fill:"#f35d23",
// 填充颜色
stroke:"#f35d23",
// 边框填充颜色
id:"jsCategorySpzx",
// id
index:1
},
// 司法政务2
sfzw:{
title:"司法政务",
name:"sfzw",
fill:"#762e97",
// 填充颜色
stroke:"#762e97",
// 边框填充颜色
id:"jsCategorySfzw",
// id
index:2
},
// 司法研究 3
sfyj:{
title:"司法研究",
name:"sfyj",
fill:"#0072bb",
// 填充颜色
stroke:"#0072bb",
// 边框填充颜色
id:"jsCategorySfyj",
// id
index:3
},
// 司法人事4
sfrs:{
title:"司法人事",
name:"sfrs",
fill:"#f9c208",
// 填充颜色
stroke:"#f9c208",
// 边框填充颜色
id:"jsCategorySfrs",
// id
index:4
},
// 信息化管理 5
xxhgl:{
title:"信息化管理",
name:"xxhgl",
fill:"#b925b4",
// 填充颜色
stroke:"#b925b4",
// 边框填充颜色
id:"jsCategoryXxhgl",
// id
index:5
},
// 外部数据6
wbsj:{
title:"外部数据",
name:"wbsj",
fill:"#00b08e",
// 填充颜色
stroke:"#00b08e",
// 边框填充颜色
id:"jsCategoryWbsj",
// id
index:6
}
},
centerCircle:{
cx:320,
cy:320,
r:320,
circleObj:{
r:100,
fill:"#00a7ec",
stroke:"#e8faff",
strokeWidth:8,
// 背景图片
image:{
width:230,
height:230,
url:"../images/category/centerCircle.jpg"
}
}
},
// 三角形参数
sanjiao:{
fill:"#f35d23",
asideLength:250,
// 边长
"class":"js-sanjiao-item",
"stroke-linejoin":"round",
//表示描边转角的表现方式
idPrefix:"js-sanjiao-item-",
// id 前缀,这个不能缺少
strokeWidth:20,
stroke:"#000",
cursor:"pointer"
},
};
var _this={
stage:svg
};
function makePolygon(){
// 创建阴影=> 此操作非常消耗性能,在大型web开发中禁止使用 filter 效果
//var _filter = _this.stage.paper.filter(Snap.filter.shadow(0, 0, 20,'rgba(0,98,196,0.25)'));
// 最后给三角全部放到一个容器,方便旋转
_this.sanjiaoGroup = _this.stage.paper.g();
// 起点坐标应该是 x=圆心x坐标, y=圆心y坐标-(圆半径-三角的半径)/2;
var _startX = _opts.centerCircle.cx;
var _startY = _opts.centerCircle.cy - (_opts.centerCircle.r - _opts.sanjiao.asideLength) / 2;
var _startPoint = "M" + _startX + " " + _startY;
// 第二个点的坐标 x=圆心x坐标- 三角边长的一半, y= _startY- 三角形的高
var _movePoint1 = "L" + (_opts.centerCircle.cx - _opts.sanjiao.asideLength / 2) + " " + (_startY - Math.sin(Math.PI / 180 * 60) * _opts.sanjiao.asideLength);
// 第三个点的坐标 x=圆心x坐标- 三角边长的一半, y= _startY- 三角形的高
var _movePoint2 = "L" + (_opts.centerCircle.cx + _opts.sanjiao.asideLength / 2) + " " + (_startY - Math.sin(Math.PI / 180 * 60) * _opts.sanjiao.asideLength);
// 循环划出所有的三角,并且将数据和储存到 data中
$.each(_opts.category, function(key, value) {
var _optsSub = $.extend(true, {}, _opts.sanjiao, value || {});
// _opts.filter=_filter;
_optsSub.d = _startPoint + "," + _movePoint1 + "," + _movePoint2 + "z";
_optsSub.id = _optsSub.idPrefix + _optsSub.index;
// 注意这里的旋转方向,1的应该旋转最多
_optsSub.transform = "rotate(" + (6 - value.index + 1) * 60 + "," + _opts.centerCircle.cx + "," + _opts.centerCircle.cy + ")";
// 赋值给一个对象
_this["sanjiao" + key] = _this.stage.el("path", _optsSub).data("data", _optsSub);
// 添加到一个组中
_this.sanjiaoGroup.add(_this["sanjiao" + key]);
});
}
makePolygon();
function executeAnimate(_index) {
var _rotateDeg =_index*60;
_this.sanjiaoGroup.stop().animate({
transform:'rotate('+ _rotateDeg + ','+ _opts.centerCircle.cx +',' + _opts.centerCircle.cy +')'
},300 , mina.linear, function () {
});
}
_this.sanjiaoGroup.selectAll('.'+ _opts.sanjiao.class).forEach(function (element, index) {
var _element = element;
_element.click(function() {
var _data = _element.data('data');
executeAnimate(_data.index);
});
});
executeAnimate(1);
}();解决方案
/**
* Created by wuwg on 2016/11/1 0001.
*/
+function () {
var svg=Snap('#svg');
svg.attr({
width:640,
height:640,
viewBox:'0 0 640 640'
});
var _opts={
category:{
// 审判执行 1
spzx:{
title:"审判执行",
name:"spzx",
fill:"#f35d23",
// 填充颜色
stroke:"#f35d23",
// 边框填充颜色
id:"jsCategorySpzx",
// id
index:1
},
// 司法政务2
sfzw:{
title:"司法政务",
name:"sfzw",
fill:"#762e97",
// 填充颜色
stroke:"#762e97",
// 边框填充颜色
id:"jsCategorySfzw",
// id
index:2
},
// 司法研究 3
sfyj:{
title:"司法研究",
name:"sfyj",
fill:"#0072bb",
// 填充颜色
stroke:"#0072bb",
// 边框填充颜色
id:"jsCategorySfyj",
// id
index:3
},
// 司法人事4
sfrs:{
title:"司法人事",
name:"sfrs",
fill:"#f9c208",
// 填充颜色
stroke:"#f9c208",
// 边框填充颜色
id:"jsCategorySfrs",
// id
index:4
},
// 信息化管理 5
xxhgl:{
title:"信息化管理",
name:"xxhgl",
fill:"#b925b4",
// 填充颜色
stroke:"#b925b4",
// 边框填充颜色
id:"jsCategoryXxhgl",
// id
index:5
},
// 外部数据6
wbsj:{
title:"外部数据",
name:"wbsj",
fill:"#00b08e",
// 填充颜色
stroke:"#00b08e",
// 边框填充颜色
id:"jsCategoryWbsj",
// id
index:6
}
},
centerCircle:{
cx:320,
cy:320,
r:320,
circleObj:{
r:100,
fill:"#00a7ec",
stroke:"#e8faff",
strokeWidth:8,
// 背景图片
image:{
width:230,
height:230,
url:"../images/category/centerCircle.jpg"
}
}
},
// 三角形参数
sanjiao:{
fill:"#f35d23",
asideLength:250,
// 边长
"class":"js-sanjiao-item",
"stroke-linejoin":"round",
//表示描边转角的表现方式
idPrefix:"js-sanjiao-item-",
// id 前缀,这个不能缺少
strokeWidth:20,
stroke:"#000",
cursor:"pointer"
},
};
var _this={
stage:svg
};
function makePolygon(){
// 创建阴影=> 此操作非常消耗性能,在大型web开发中禁止使用 filter 效果
//var _filter = _this.stage.paper.filter(Snap.filter.shadow(0, 0, 20,'rgba(0,98,196,0.25)'));
// 最后给三角全部放到一个容器,方便旋转
_this.sanjiaoGroup = _this.stage.paper.g();
// 起点坐标应该是 x=圆心x坐标, y=圆心y坐标-(圆半径-三角的半径)/2;
var _startX = _opts.centerCircle.cx;
var _startY = _opts.centerCircle.cy - (_opts.centerCircle.r - _opts.sanjiao.asideLength) / 2;
var _startPoint = "M" + _startX + " " + _startY;
// 第二个点的坐标 x=圆心x坐标- 三角边长的一半, y= _startY- 三角形的高
var _movePoint1 = "L" + (_opts.centerCircle.cx - _opts.sanjiao.asideLength / 2) + " " + (_startY - Math.sin(Math.PI / 180 * 60) * _opts.sanjiao.asideLength);
// 第三个点的坐标 x=圆心x坐标- 三角边长的一半, y= _startY- 三角形的高
var _movePoint2 = "L" + (_opts.centerCircle.cx + _opts.sanjiao.asideLength / 2) + " " + (_startY - Math.sin(Math.PI / 180 * 60) * _opts.sanjiao.asideLength);
// 循环划出所有的三角,并且将数据和储存到 data中
$.each(_opts.category, function(key, value) {
var _optsSub = $.extend(true, {}, _opts.sanjiao, value || {});
// _opts.filter=_filter;
_optsSub.d = _startPoint + "," + _movePoint1 + "," + _movePoint2 + "z";
_optsSub.id = _optsSub.idPrefix + _optsSub.index;
// 注意这里的旋转方向,1的应该旋转最多
_optsSub.transform = "rotate(" + (6 - value.index + 1) * 60 + "," + _opts.centerCircle.cx + "," + _opts.centerCircle.cy + ")";
// 赋值给一个对象
_this["sanjiao" + key] = _this.stage.el("path", _optsSub).data("data", _optsSub);
// 添加到一个组中
_this.sanjiaoGroup.add(_this["sanjiao" + key]);
});
// 三角外围 // 重点
_this.sanjiaoGroupWrap = _this.stage.paper.g();
_this.sanjiaoGroupWrap.add(_this.sanjiaoGroup);
}
makePolygon();
// 执行动画
function executeAnimate(index) {
var _index=index;
var _wrapIndex = _this.sanjiaoGroupWrap.attr("index");
_wrapIndex = _wrapIndex ? _wrapIndex :0;
_index= index<_wrapIndex? (6- (_wrapIndex- index)) : index-_wrapIndex; // 如果 index 小于 _wrapIndex 那么就应该 6 -(_wrapIndex- index)
_wrapIndex=index%6;
var _rotateDeg =_index*60;
// 如果还在动画,那么需要先停止动画,先调用 stop() 方法
// 执行旋转三角动画
_this.sanjiaoGroup.stop().animate({
transform:"rotate(" + _rotateDeg + "," + _opts.centerCircle.cx + "," + _opts.centerCircle.cy + ") "
}, 1000, mina.linear, function() {
// 重点
_this.sanjiaoGroupWrap.attr({
transform:"rotate(" + (60*_wrapIndex) + "," + _opts.centerCircle.cx + "," + _opts.centerCircle.cy + ") ",
index:_wrapIndex
});
_this.sanjiaoGroup.attr({
transform:''
});
});
}
// 给三角绑定点击事件
_this.sanjiaoGroup.selectAll("." + _opts.sanjiao.class).forEach(function(element, index) {
var _element = element;
// 绑定点击事件
_element.click(function () {
var _data = _element.data("data");
if (_data.index != _this.indexActive) {
// 点击执行动画
executeAnimate(_data.index);
}
});
});
executeAnimate(1);
}();其实就是在执行完旋转动画后,将本身的值赋值给父元素,让父元素旋转角度,然后自己还原到初始化的位置,这样旋转动画就能兼容 ie 浏览器
-
« 上一篇:
前端性能优化
-
关于css的比值关系
:下一篇 »