`

snap.svg.js学习------分类结构动画展示

阅读更多
wallimn原创,欢迎转载,原文地址:http://wallimn.iteye.com/blog/2373581

一、功能介绍:
  功能很简单,就是一个支持炫酷动画效果的分类结构展示程序包,学习研究snap.svg.js的成果。纯javascript程序,可以html5网页中运行。不支持ie8及以下浏览器,手机运行效果更佳。依赖jQuery。

二、程序界面:





三、工具包代码:

function Snapcat(paper,data,options){
	this.options={
			centerX:100,
			centerY:100,
			bigRadius:70,
			smallRadius:40,
			leafClickHandler:function(json){
				alert("id="+json.id+", data="+json.data);
			},
			colors:["#fa3e3e","#fa9c3e","#fafa3e","#9cfa3e","#3efa3e","#3efa9c","#3efafa","#3e9cfa","#3e3efa","#9c3efa"]
	};
	
	if(options){
		jQuery.extend(this.options,options);
	}
	
	this.paper = paper;
	
	this.data = data;
	
	var exitPathDef = "M"+this.options.centerX+","+this.options.centerY+" Q"+this.options.centerX+" 0,0 0";
	var enterPathDef="M0 0,Q0 "+this.options.centerY+","+this.options.centerX+" "+this.options.centerY;
	//退出路径,内部变量
	this.exitPath = paper.path(exitPathDef).attr({fill:'none'});
	//进行路径,内部变量
	this.enterPath = paper.path(enterPathDef).attr({fill:'none'});
	
	this.getLevelColor=function(level){
		if(level>=this.options.colors.length)return "#f00";
		else return this.options.colors[level];
	};
	
	//根据ID获取数据
	this.getDataById=function (id){
		for(var i=0; i<this.data.length; i++){
			if(this.data[i].id==id)return this.data[i];
		}
		return null;
	};
	
	
	this.getDataByPid=function(id){
		var result=[];
		for(var i=0; i<this.data.length; i++){
			if(this.data[i].pid==id)result.push(this.data[i]);
		}
		return result;
	};
	
	
	this.getLevel=function(id){
		var level = 0;
		var data = this.getDataById(id);
		if(!data)return level;
		
		while(data.pid!=0){
			level++;
			data = this.getDataById(data.pid);
		}
		return level;
	};
	
	
	
	
	//内部私用函数
	function drawMainCat(cx,cy,r,id,millisec){
		var result = {};
		var data = this.getDataById(id);
		var level = this.getLevel(id);
		result.circle=this.paper.circle(cx,cy,r).attr({
			fill:this.getLevelColor(level),
			stroke:this.getLevelColor(level),
			strokeOpacity:0.75,
			r:0,
			"data-id":data.id,
			"data-pid":data.pid,
			strokeWidth:8
		});
		result.text = paper.text(cx,cy,data.label)
						.attr({"opacity":0,"data-id":data.id,"data-pid":data.pid});
		var bbox = result.text.getBBox();
		var matrix = new Snap.Matrix();
		matrix.translate(-bbox.width/2, bbox.height/2);
		result.text.transform(matrix);
		
		if(millisec){
			result.circle.animate({r:r},millisec*9/10,mina.bounce,function(){
				result.text.animate({opacity:1},millisec/10,mina.bounce,function(){
	    		});
	    	});
		}
		else{
			result.circle.attr({r:r});
			result.text.attr({opacity:1});
		}
		
		return result;
	}

	//绘制子类
	function drawSubCat(cx,cy,r1,r2,id,timeOutMillisec,dualMillisec){
		var self = this;//在内部函数中使用
		//显示子类
		var data = this.getDataByPid(id);
		var level = this.getLevel(id);
		if(!data || data.length==0)return;
        var x,y;
        var distance=r1+r2+10;
        var subcircles = this.paper.group();
        var subcircle,subtext,matrix;
        var datalen = data.length;
        var result = [];
        for(var i=0; i<datalen; i++){
        	x = distance*Math.sin(360*i*Math.PI/180/datalen)+this.options.centerX;
        	y = distance*Math.cos(360*i*Math.PI/180/datalen)+this.options.centerY;
        	subcircle=paper.circle(x,y,0).attr({"data-id":data[i].id,"data-pid":data[i].pid,"data-idx":i,"data-data":data[i].data});
        	subcircles.add(subcircle);
        	subtext = paper.text(x,y,data[i].label).attr({"data-id":data[i].id,"data-pid":data[i].pid,"data-data":data[i].data,opacity:0,"data-idx":i});
        	bbox = subtext.getBBox();
        	matrix = new Snap.Matrix();
        	matrix.translate(-bbox.width/2,bbox.height/2);
        	subtext.transform(matrix);
        	result.push({circle:subcircle,text:subtext});
        	
        }
        subcircles.attr({
        	fill:this.getLevelColor(level+1),
        	stroke:this.getLevelColor(level+1),
        	strokeOpacity:0.75,
        	strokeWidth:8
        });
        
        
    	if(timeOutMillisec && dualMillisec){
    		setTimeout(function(){
    			var circle,text;
    			for(var i=0; i<datalen; i++){
    				Snap($("circle[data-id="+data[i].id+"]")[0]).animate({r:r2},dualMillisec*9/10,mina.bounce,function(){
    					var id = this.node.getAttribute("data-id");
    					Snap($("text[data-id="+id+"]")[0]).animate({opacity:1},dualMillisec/10,mina.bounce);
    				});
    			}
    		},timeOutMillisec);
    	}
    	else{
			for(var i=0; i<datalen; i++){
				Snap($("circle[data-id="+data[i].id+"]")[0]).attr({r:r2});
				Snap($("text[data-id="+data[i].id+"]")[0]).attr({opacity:1});
			}
    	}
        
    	
    	
    	//设置事件
    	var clickHandler = function(){
			var idx = this.node.getAttribute("data-idx");
			var pid = this.node.getAttribute("data-pid");
			var id = this.node.getAttribute("data-id");
			var catdata = this.node.getAttribute("data-data");
			
			if(self.getDataByPid(id).length==0){
				self.options.leafClickHandler({id:id,data:catdata});
				return;
			}
			
			$("circle[data-idx!="+idx+"][data-pid="+pid+"]").remove();
			$("text[data-idx!="+idx+"][data-pid="+pid+"]").remove();
			//paper.selectAll("circle[data-id="+pid+"],text[data-id="+pid+"]").remove();
			var length = Snap.path.getTotalLength(self.exitPath);
			var circle = Snap($("circle[data-id="+pid+"]")[0]);
			var text = Snap($("text[data-id="+pid+"]")[0]);
			//移走大圆
			Snap.animate(0,length,function(val){
				var point = Snap.path.getPointAtLength(self.exitPath,val);
				circle.attr({cx:point.x,cy:point.y});
				text.attr({x:point.x,y:point.y});
			},timeOutMillisec,mina.easeout);
			
			//移动上左上角后,增加事件,负责移回大圆
			circle.click(function(){
				var id = this.node.getAttribute("data-id");
				$("circle[data-id!="+id+"]").remove();
				$("text[data-id!="+id+"]").remove();
				var length = Snap.path.getTotalLength(self.enterPath);
				var circle=Snap($('circle[data-id='+id+']')[0]);
				var text=Snap($('text[data-id='+id+']')[0]);
				//移回大圆
				Snap.animate(0,length,
					function(val){
	    				var point = Snap.path.getPointAtLength(self.enterPath,val);
	    				circle.attr({cx:point.x,cy:point.y});
	    				text.attr({x:point.x,y:point.y});
    				},
    				timeOutMillisec,
    				function(){
    					circle.unclick();
					});
				
				drawSubCat.bind(self)(cx,cy,r1,r2,id,timeOutMillisec,dualMillisec);
			});
			
			var subCircle = Snap($("circle[data-id="+id+"]")[0])	;
			var subText = Snap($("text[data-id="+id+"]")[0])	;
			var subPathDef = "M"+subCircle.attr("cx")+" "+subCircle.attr("cy")+" L"+self.options.centerX+" "+self.options.centerY;
			var subPath = paper.path(subPathDef);
			length = Snap.path.getTotalLength(subPath);
			//放大小圆
			Snap.animate(self.options.smallRadius,self.options.bigRadius,
					function(val){
						subCircle.attr({r:val});
					},
					dualMillisec,mina.easeout
			);
			subText.unclick();
			subCircle.unclick();
			
			//小圆移到中心
			Snap.animate(0,length,function(val){
    				var point = Snap.path.getPointAtLength(subPath,val);
    				subCircle.attr({cx:point.x,cy:point.y});
    				subText.attr({x:point.x,y:point.y});
				},
				dualMillisec,mina.easeout,
				function(){
					drawSubCat.bind(self)(cx,cy,r1,r2,id,dualMillisec,dualMillisec);
				}
			);
		};//end of click event
    	for(var i=0; i<result.length;i++){
    		result[i].text.click(clickHandler);
    		result[i].circle.click(clickHandler);
    	}//end of for
        return result;
	}
	
	this.drawCat=function(){
		var millsec=600;
    	drawMainCat.bind(this)(this.options.centerX,this.options.centerY,this.options.bigRadius,1,millsec);
    	drawSubCat.bind(this)(this.options.centerX,this.options.centerY,this.options.bigRadius,this.options.smallRadius,1,millsec,400);
	}

}//end of Snapcat



四、应用示例:
<!DOCTYPE html>
<!--
	作者: wallimn, http://wallimn.iteye.com
	时间:2017年5月7日
	功能:很酷的分类动画展示包
-->
<html lang="zh-cn">
  <head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
    <title>酷炫分类-wallimn</title>
    <style type="text/css">
    	html,body{
    		width:100%;
    		height:100%;
    	}
		#svg {
			margin:0;
			position:relative;
			top:50%;
			border-radius:5px;
			border:1px solid #efefef;
		}
		text{
			font-size:14px;
		}
    </style>
  </head>
  <body>
  
 
	<svg id='paper'></svg>
  
  
    <script type="text/javascript" src="js/jquery-1.11.1.min.js"></script>
	<script type="text/javascript" src="js/snap.svg-min.js"></script>
	<script type="text/javascript" src="js/snapcat.js"></script>
    
	<script type="text/javascript">
	
	    $(function(){
	    	var clientWidth=document.body.clientWidth;
	    	var clientHeight=document.body.clientHeight;
			$("#paper").css("width",clientWidth+"px").css("height",clientHeight+"px");
	    	var minsize = Math.min(clientWidth,clientHeight);
	    	var paper = Snap("#paper");
	    	//创建床半径为80的圆
	    	var centerX=clientWidth/2, centerY=clientHeight/2 ;
	    	var data = [
    			{id:1,pid:0,label:'知识体系',data:null},
    			{id:2,pid:1,label:'产品',data:null},
    			{id:3,pid:1,label:'运营',data:null},
    			{id:4,pid:1,label:'规划',data:null},
    			{id:5,pid:1,label:'创意',data:null},
    			{id:6,pid:1,label:'战略',data:null},
    			{id:9,pid:2,label:'产品-子类1',data:'A001'},
    			{id:10,pid:2,label:'产品-子类2',data:'A002'},
    			{id:31,pid:2,label:'产品-子类3',data:'A001'},
    			{id:32,pid:2,label:'产品-子类4',data:'A002'},
    			
    			{id:11,pid:3,label:'运营-子类1',data:'A003'},
    			{id:12,pid:3,label:'运营-子类2',data:'A004'},
    			{id:13,pid:3,label:'运营-子类3',data:'A005'},
    			
    			{id:14,pid:4,label:'规划-子类1',data:'A006'},
    			{id:15,pid:4,label:'规划-子类2',data:'A007'},
    			{id:16,pid:4,label:'规划-子类3',data:'A008'},
    			{id:17,pid:4,label:'规划-子类4',data:'A009'},
    			
    			{id:18,pid:5,label:'创意-子类1',data:'A010'},
    			{id:18,pid:5,label:'创意-子类2',data:'A011'},
    			
    			{id:20,pid:6,label:'战略-子类1',data:'A012'},
    			{id:21,pid:6,label:'战略-子类2',data:'A013'},
    			{id:22,pid:6,label:'战略-子类3',data:'A014'},
    			{id:23,pid:6,label:'战略-子类4',data:'A012'},
    			{id:24,pid:6,label:'战略-子类5',data:'A013'},
    			{id:25,pid:6,label:'战略-子类6',data:'A014'},
    		];	        
	    	var snapcat = new Snapcat(paper,data,{centerX:centerX,centerY:centerY});
	    	snapcat.drawCat();
	     });
	</script>
  </body>
</html>


五、代码仓库:
  代码上传到github.com,访问地址:https://github.com/wallimn/snapcat,猛戳下载全部程序。

  手机体验,请使用微信扫描下面二维码,不需关注、不需注册、不需下载:


  • 大小: 22.9 KB
  • 大小: 22 KB
  • 大小: 8.4 KB
1
2
分享到:
评论

相关推荐

    snap.svg 中文参考手册 离线php版

    Snap.svg 是一个强大的JavaScript库,专门用于在Web上创建SVG(可缩放矢量图形)动画和交互。这个中文参考手册是为那些希望在PHP环境中使用Snap.svg的开发者准备的,即使你对PHP不感兴趣,也可以通过提供的链接访问...

    前端项目-snap.svg.zpd.zip

    Snap.svg 是一个强大的JavaScript库,专门用于在Web上创建、操作和动画SVG(Scalable Vector Graphics)元素。这个“前端项目-snap.svg.zpd.zip”包含了一个使用Snap.svg库实现的缩放、平移和拖动功能的插件。在深入...

    snap.svg.zip

    Snap.SVG 是一个强大的JavaScript库,专为在Web上创建SVG(可缩放矢量图形)动画和交互式设计而设计。这个库以其简洁的API和广泛的文档支持,深受前端开发者的喜爱。"snap.svg.zip" 文件包含了 Snap.SVG 库的两个...

    snap-svg js库

    Snap.svg 是一个强大的JavaScript库,专门用于在Web页面上创建、操作和动画化SVG(Scalable Vector Graphics)元素。SVG是一种矢量图形格式,它允许网页内容在不同分辨率和尺寸的设备上清晰显示,而不会失真。Snap....

    基于Html5 svg+snap.svg实现带日期的天气预报特效源码.zip

    Snap.svg是基于SVG的JavaScript库,它简化了在浏览器中创建、操作和动画SVG元素的过程。这个库提供了丰富的API,包括选择、创建、操作和动画化SVG图形。在天气预报特效中,Snap.svg可能被用来创建天气图标、动态效果...

    Snap.svg.js实现上下漂浮的纸飞机和隐约可见的纸片飞舞背景动画效果源码.zip

    Snap.svg.js是一个强大的SVG(可缩放矢量图形)库,专为JavaScript设计,用于在Web上创建和操作矢量图形。这个压缩包文件提供了一种实现上下漂浮的纸飞机和隐约可见的纸片飞舞背景动画效果的源码。这种效果常用于...

    HTML5 SVG和snap.svg的超酷天气预报设计特效.zip

    通过学习这个项目,开发者不仅可以掌握SVG和Snap.svg的基本用法,还能了解到如何将这些技术应用于实际的Web应用程序中,提升网页的视觉吸引力和用户体验。同时,对于想要从事前端开发或者增强自身Web设计技能的人来...

    svg:受 raphaeljs、svgjs 和 snap.svg 启发的小型简单 SVG Javascript 库

    介绍一个简单的 SVG javascript 库建造安装依赖npm install 该库使用 gulp 来运行所有任务: 要构建运行gulp 。 文件将输出到 dist 文件夹。教程不。 可能也不会发生。去做对动画方法进行更广泛的测试创建更好的界面...

    Snap.svg-playground:我用 Snap.svg 制作的一些东西

    在 "Snap.svg-playground" 中,你可以找到各种示例,展示了 Snap.svg 库在创建交互式图形、动画和用户界面元素方面的灵活性。这个项目的目的是帮助开发者了解 Snap.svg 的核心概念和功能,从而能够更有效地利用它来...

    一个实验性滑块,使用SVG剪切路径功能和Snap.svg驱动的动画-JavaScript开发

    Elastic Slider一种实验性滑块,它使用SVG剪切路径功能和Snap.svg驱动的动画。 演示文章的用法首先,您需要包括弹性滑块样式和脚本,以及外部Snap.svg弹性滑块。一个实验性滑块,它使用SVG剪切路径功能以及由Snap....

    12个SVG Loading图标

    - 使用JavaScript库(如Snap.svg)进行更复杂的交互和动画操作。 7. **SVG图标优化** - 压缩SVG代码:可以使用工具如SVGO进行代码压缩,减少文件大小。 - 图标符号集:将多个SVG图标组合成一个符号集(symbol)...

    animated-svg-icon:如何使用 CSS 和 Snap.svg 库为 SVG 图标设置动画

    为了使这些图标更具动态性,开发者常常会利用CSS和JavaScript库如Snap.svg来添加动画效果。本篇文章将深入探讨如何通过CSS和Snap.svg库实现SVG图标的动画。 首先,我们需要了解SVG的基本概念。SVG是一种基于XML的...

    clocks:一些使用snap.svg构建的时钟

    对于想要提升前端开发技能,特别是涉及SVG和JavaScript动画的开发者来说,这是一个很好的学习资源。你可以逐个查看项目中的示例,分析它们的代码结构,模仿并尝试创建自己的时钟设计。这样不仅能增强对Snap.svg的...

    svg-animated-infographic:该项目显示了如何使用snap.svg创建动画信息图

    svg动画的信息图表该项目显示了如何使用snap.svg创建动画信息图。开发服务器为开发服务器运行npm start 。 导航到http://localhost:3000/ 。 如果您更改任何源文件,该应用程序将自动重新加载。

    snap.js使用,内嵌SVG图像,动画,轨迹变换等。

    snap.js使用,内嵌SVG图像,动画,轨迹变换,内嵌文字,开关、刀闸等造型。

    svg图形拖拽变大变小旋转.7z

    在本项目中,"svg图形拖拽变大变小旋转.7z" 是一个...通过这些资源,开发者可以学习如何利用SVG、JavaScript(包括jQuery和Snap.svg库)以及HTML5和CSS3来创建具有拖拽、缩放和旋转功能的交互式SVG图形,提升用户体验。

    build_gear:基于 SVG animationMotion 和 snap.svg.js 的动画

    build_gear 基于 SVG animationMotion 和 snap.svg.js 的动画

    html5 svg和css3超神奇图片鼠标hover动画效果

    在本示例中,"html5 svg和css3超神奇图片鼠标hover动画效果"展示了如何利用这两个技术来创建吸引人的交互式元素,特别是鼠标悬停时的动画效果。以下是关于这些技术以及实现此类效果的详细知识: 1. **HTML5 SVG (可...

    12个SVG Loading图标演示

    例如,使用JavaScript库如Snap.svg或D3.js,可以实现更高级的SVG动画和交互。 6. 文件优化:虽然SVG是矢量图形,但包含过多细节或复杂动画可能会导致文件大小增加。可以使用工具如SVGO进行优化,去除不必要的代码,...

Global site tag (gtag.js) - Google Analytics