项目实例
运用 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的比值关系
:下一篇 »