User:A2569875/圖表沙盒.js

维基百科,自由的百科全书

注意:保存之后,你必须清除浏览器缓存才能看到做出的更改。Google ChromeFirefoxMicrosoft EdgeSafari:按住⇧ Shift键并单击工具栏的“刷新”按钮。参阅Help:绕过浏览器缓存以获取更多帮助。

$(function() {
	jQuery.expr[':'].regex = function(elem, index, match) {
		var matchParams = match[3].split(','),
			validLabels = /^(data|css):/,
			attr = {
				method: matchParams[0].match(validLabels) ? 
							matchParams[0].split(':')[0] : 'attr',
				property: matchParams.shift().replace(validLabels,'')
			},
			regexFlags = 'ig',
			regex = new RegExp(matchParams.join('').replace(/^\s+|\s+$/g,''), regexFlags);
		return regex.test(jQuery(elem)[attr.method](attr.property));
	};
	var enum_face = ['u','d','f','b','l','r'];
	var enum_color = ['white','yellow','orange','red','green','blue'];
	var enum_face_lookup = {u:0,d:1,f:2,b:3,l:4,r:5};
	var num_list = [0,1,2,3,4,5,6,7,8];
	var inv_num_list = [8,7,6,5,4,3,2,1,0];
	var rotate_face_num_list = {u:inv_num_list,d:num_list,f:num_list,b:inv_num_list,l:num_list,r:num_list};
	var rotate_position_list = [[-1,1],[0,1],[1,1],[-1,0],[0,0],[1,0],[-1,-1],[0,-1],[1,-1]];
	function pos_dif(v0,v1){return [v1[0]-v0[0],v1[1]-v0[1]];}
	function pos_abs(v0){return Math.sqrt(v0[0]*v0[0]+v0[1]*v0[1]);}
	function vec_abs(v0){return [Math.abs(v0[0]),Math.abs(v0[1])];}
	function vec_mul(v0,v1){return [v1[0]*v0[0],v1[1]*v0[1]];}
	var center_dir = [null,0,null,1,null,3,null,2,null];
	var rotate_face_lookup = {
		u:['f','r','b','l'],
		d:['f','l','b','r'],
		f:['u','l','d','r'],
		b:['u','r','d','l'],
		l:['u','b','d','f'],
		r:['u','f','d','b'],
	};
	var rotate_face_lookup_if = {
		u:[[[0,1,2],[0,1,2],[8,7,6],[0,1,2]],[[3,4,5],[3,4,5],[5,4,3],[3,4,5]]],
		d:[[[8,7,6],[8,7,6],[0,1,2],[8,7,6]],[[5,4,3],[5,4,3],[3,4,5],[5,4,3]]],
		f:[[[8,7,6],[2,5,8],[0,1,2],[6,3,0]],[[5,4,3],[1,4,7],[3,4,5],[7,4,1]]],
		b:[[[0,1,2],[2,5,8],[8,7,6],[6,3,0]],[[3,4,5],[1,4,7],[5,4,3],[7,4,1]]],
		l:[[[6,3,0],[6,3,0],[6,3,0],[6,3,0]],[[7,4,1],[7,4,1],[7,4,1],[7,4,1]]],
		r:[[[2,5,8],[2,5,8],[2,5,8],[2,5,8]],[[1,4,7],[1,4,7],[1,4,7],[1,4,7]]],
	};
	var face_center_rotate = [[2,6],[5,3],[8,0],[1,7],[null,null],[7,1],[0,8],[3,5],[6,2]];
	var antipodes_table = {u:'d',d:'u',l:'r',r:'l',f:'b',b:'f'};
	//var cube_dom = $(".cube-main")[0];
	//window.buildCube($(".cube-main")[0])
	window.buildCube=function(cube_dom){
		var the_cube = {};
		the_cube.dom = cube_dom;
		the_cube.face={};
		if($(cube_dom).hasClass("no-inner"))the_cube.innerColor=false;
		else the_cube.innerColor=true;
		the_cube.get_color=function(cube_face_dom){
			var color_data = {html:$(cube_face_dom).html(),class_data:""};
			var class_list = $(cube_face_dom).attr('class');
			if(class_list === undefined || class_list == null)return color_data;
			class_list = class_list.replace(/(cube\-[a-z]+|[udlrfb]\d)/ig,'').replace(/\s+/g,' ').trim();
			if(class_list=="")return color_data;
			color_data.class_data=class_list;
			return color_data;
		};
		var check_cube_length=0;
		for(var enum_it=0; enum_it<enum_face.length; ++enum_it){
			var face_it = enum_face[enum_it];
			the_cube.face[face_it] = [];
			for(var i=0; i<9; ++i){
				var check_data = $(cube_dom).find( "."+face_it+i );
				var check_data_length = check_data.length;
				if(check_data_length === undefined || check_data_length == null || isNaN(parseInt(check_data_length)))check_data_length=0;
				if(check_data_length <= 0)check_data=null;
				else check_data=check_data[0];
				the_cube.face[face_it][i]=check_data;
				if(check_data!=null && check_data!==undefined)++check_cube_length;
			}
		}
		the_cube.face_count=check_cube_length;
		the_cube.side=Math.floor(Math.sqrt(check_cube_length/6));
		the_cube.turn_lock=false;
		the_cube.turnByCommand=function(cmd,wait,callback_single_in,callback_all_in){
			var callback_single = typeof(callback_single_in)===typeof($.noop)?callback_single_in:$.noop;
			var callback_all = typeof(callback_all_in)===typeof($.noop)?callback_all_in:$.noop;
			var parse = (cmd+'').match(/(rand(om)?|[a-z])['\d]*/ig);
			if(parse==null)return null;
			var todo_cmd = [];
			for(var i=0; i<parse.length; ++i){
				var matcher = parse[i].match(/rand(om)?'?(\d+)'?/i);
				if(matcher){
					var m_count = parseInt(matcher[2]);
					if(!isNaN(m_count))if(m_count > 0)for(var m_i=0; m_i<m_count; ++m_i)todo_cmd.push("rand");
				}else todo_cmd.push(parse[i]);
			}
			if(wait){
				if(the_cube.turn_lock==true)return null;
				the_cube.turn_lock=true;
				var queue=[];
				var turned_data=[];
				for(var i=0; i<todo_cmd.length; ++i)queue.unshift(todo_cmd[i]);
				var time_wait = parseInt(wait);
				if(isNaN(time_wait))time_wait=1;
				if(wait==true||time_wait==1)time_wait=250;
				var await_func=function(time_wait_p,todo_the_cube,todolist,turned,doing_call,call_back,callback_single_work){
					window.setTimeout(
						function(){
							var todo = todolist.shift();
							var turn_data = todo_the_cube.turnBySymbol(todo);
							if(turn_data != false){
								turned.push(turn_data!=true?turn_data:todo);
								callback_single_work(turn_data);
							}
							if(todolist.length>0)doing_call(time_wait_p,todo_the_cube,todolist,turned,doing_call,call_back,callback_single_work);
							else {
								the_cube.turn_lock=false;
								call_back(turned);
							}
						}
					, time_wait_p);
				};
				await_func(time_wait,the_cube,todo_cmd,turned_data,await_func,callback_all,callback_single);
				return null;
			}
			var result = [];
			for(var i=0; i<todo_cmd.length; ++i){
				var turn_data = the_cube.turnBySymbol(todo_cmd[i]);
				if(turn_data != false){
					result.push(turn_data!=true?turn_data:todo_cmd[i]);
				}
			}
			return result;
		};
		the_cube.turnBySymbol=function(sym){
			var chk_sym=sym+'';
			var is_rand=false;
			if(chk_sym.match(/rand(om)?/i)){
				var rand_sample = "udlrfbmesxyz";
				if(the_cube.side < 3)rand_sample = "udlrfbxyz";
				chk_sym=rand_sample[Math.floor(Math.random() * rand_sample.length)];
				var rand_count=Math.floor(Math.random()*4);
				if(Math.floor(Math.random()*2)==0)chk_sym=chk_sym.toUpperCase();
				if(rand_count>1)chk_sym+=rand_count;
				if(Math.floor(Math.random()*2)==0)chk_sym+="'";
				is_rand = true;
			}
			var checker = chk_sym.match(/([udlrfbmesxyz])('?)(\-?\d*)('?)/i);
			if(checker==null)return false;
			var turn_count=parseInt(checker[3]);
			if(isNaN(turn_count)||turn_count==null||checker[3]==""||checker[3]==null)turn_count=1;
			if(turn_count<0)turn_count=turn_count+(Math.ceil((4-turn_count)/4)+4)*4;
			turn_count = turn_count % 4;
			var turn_count_inv=false;
			if(turn_count>2){
				turn_count=4-turn_count;
				turn_count_inv=true;
			}
			if(turn_count==0)return false;
			
			var way_test0 = checker[2]==null?"":checker[2];
			var way_test1 = checker[4]==null?"":checker[4];
			var inv_turn = (way_test0 != way_test1 && (way_test0=="'" || way_test1=="'"));
			
			var mid_turn = checker[1].match(/[mes]/i);
			var all_turn = checker[1].match(/[xyz]/i);
			var single_turn = checker[1].toUpperCase()==checker[1];

			if(mid_turn!=null)mid_turn=true;
			if(all_turn!=null)all_turn=true;
			
			if(turn_count_inv)inv_turn=!inv_turn;
			
			var turning=function(){return false};
			
			if(mid_turn && the_cube.side < 3)return false;
			
			if(single_turn && !all_turn || mid_turn){
				var command = checker[1].toLowerCase();
				var mid_table = {m:'d',e:'d',s:'f'};
				if(mid_table[command] != null )command = mid_table[command];
				
				(function(this_the_cube,turn_comm,layer,turn_way){
					turning=function(){
						this_the_cube.turn(turn_comm,layer,turn_way);
						return true;
					};
				})(the_cube,command,mid_turn?1:0,inv_turn?0:1);
			}else if(!single_turn || all_turn){
				var command = checker[1].toLowerCase();
				var mid_table = {x:'r',y:'u',z:'f'};
				if(mid_table[command] != null )command = mid_table[command];
				
				(function(this_the_cube,turn_comm,every_turn,turn_way){
					turning=function(){
						for(var vj=0;vj<2;++vj)this_the_cube.turn(turn_comm,vj,turn_way?0:1);
						if(every_turn)this_the_cube.turn(antipodes_table[turn_comm],0,turn_way?1:0);
						return true;
					};
				})(the_cube,command,all_turn,inv_turn);
			}
			var flag=false;
			for(var i=0;i<turn_count;++i)flag = flag || turning();
			if(is_rand)return chk_sym;
			return flag;
		};
		function removeColor(the_cube_obj,dom,color_data){
			dom.removeClass(color_data.class_data);
		};
		function addColor(the_cube_obj,dom,color_data){
			if(the_cube_obj.innerColor==true)dom.html(color_data.html);
			dom.addClass(color_data.class_data);
		};
		the_cube.turn=function(face,layer,cw){
			var rotate_face_lookup_it=rotate_face_lookup_if[face][layer]
			var face_turn_it_id=(cw==1||cw==true)?0:1;
			var tmp_dom=[];
			var last_color=[];
			for(var i=0; i<rotate_face_lookup_it.length; ++i){
				var i0=i;
				if(cw==1||cw==true)i0=rotate_face_lookup_it.length-1-i;
				var turn_face_it = rotate_face_lookup[face][i0];
				for(var j=0; j<rotate_face_lookup_it[i0].length; ++j){
					var this_color = the_cube.get_color(the_cube.face[turn_face_it][rotate_face_lookup_it[i0][j]]);
					var color_dom = $(the_cube.face[turn_face_it][rotate_face_lookup_it[i0][j]]);
					if(the_cube.face[turn_face_it][rotate_face_lookup_it[i0][j]]===undefined)continue;
					if(i==0){
						tmp_dom[j]=color_dom;
						
						removeColor(the_cube,color_dom,this_color);
						//color_dom.removeClass(this_color);
					}else{
						if(i==rotate_face_lookup_it.length-1)addColor(the_cube,tmp_dom[j],this_color);//tmp_dom[j].addClass(this_color);
						
						removeColor(the_cube,color_dom,this_color);
						//color_dom.removeClass(this_color);
						
						addColor(the_cube,color_dom,last_color[j]);
						//color_dom.addClass(last_color[j]);
					}
					last_color[j]=this_color;
				}
			}
			if(layer<1){
				last_color=[];for(var i=0; i<face_center_rotate.length; ++i)last_color[i]=the_cube.get_color(the_cube.face[face][i]);
				for(var i=0; i<face_center_rotate.length; ++i){
					var move_to = face_center_rotate[i][face_turn_it_id];
					if(move_to == null)continue;
					var this_color = the_cube.get_color(the_cube.face[face][move_to]);
					var color_dom = $(the_cube.face[face][move_to]);
					
					removeColor(the_cube,color_dom,this_color);
					//color_dom.removeClass(this_color);
					
					addColor(the_cube,color_dom,last_color[i]);
					//color_dom.addClass(last_color[i]);
				}
			}
		};
		cube_dom.the_cube=the_cube;
		return the_cube;
	};

	var selected_block = null;
	$(".cube>div").mousedown(function() {
		selected_block = this;
	});
	function rotate_process(current_block, old_block) {
		var p_it = current_block;
		for(var lim_it=0; lim_it<10; ++lim_it){
			if($(p_it).hasClass("cube-main"))break;
			p_it = p_it.parentElement;
		}
		if(!$(p_it).hasClass("cube-main"))return null;
		var start_dom = old_block;
		var end_dom = current_block;
		var start_id = $(start_dom).prop('className').match(/[udfblr][0-9]/i)[0];
		var end_id = $(end_dom).prop('className').match(/[udfblr][0-9]/i)[0];
		var start_norm_id = rotate_face_num_list[start_id[0]][parseInt(start_id[1])];
		var end_norm_id = rotate_face_num_list[end_id[0]][parseInt(end_id[1])];
		var start_pos = rotate_position_list[start_norm_id];
		var end_pos = rotate_position_list[end_norm_id];
		if(start_id[0]==end_id[0]){//同面動作
			var mot_vec=pos_dif(start_pos,end_pos);
			var mot_abs=pos_abs(mot_vec);
			if(Math.abs(pos_abs(start_pos) - 1)<=1e-10){//從邊塊開始操作
				var mask = vec_abs(start_pos);
				var vec_and = pos_dif(start_pos,vec_mul(end_pos,mask));
				if(Math.abs(pos_abs(vec_and))<=1e-10){//轉面
					var rot_target = rotate_face_lookup[start_id[0]][center_dir[start_norm_id]];
					var rot_way = (mot_vec[0]+mot_vec[1])>0?0:1;
					if(start_pos[0]>0)rot_way=1-rot_way;
					else if(start_pos[1]<0)rot_way=1-rot_way;
					p_it.the_cube.turn(rot_target,0,rot_way);
					return rot_target+(rot_way==1?"'":'');
				}
				if(Math.abs(mot_abs-Math.floor(mot_abs))<=1e-10){//轉中間層
					var ct_dir = center_dir[start_norm_id]-1;
					if(ct_dir<0)ct_dir=3;
					var rot_target = rotate_face_lookup[start_id[0]][ct_dir];
					var rot_way = (mot_vec[0]+mot_vec[1])>0?1:0;
					//if(mot_vec[0]<0)rot_way=1-rot_way;
					p_it.the_cube.turn(rot_target,1,0);
					return true;
				}
			}
			if(start_norm_id==4){//從中心塊開始操作
				var ct_dir = center_dir[end_norm_id];
				if(ct_dir==null)return null;
				ct_dir = 3-ct_dir;
				var rot_target = rotate_face_lookup[start_id[0]][ct_dir];
				var rot_way = Math.abs(mot_vec[0])>0?0:1;
				p_it.the_cube.turn(rot_target,1,rot_way);
				return true;
			}
			var check_mot_vec = vec_abs(mot_vec);//從角塊開始操作
			if(check_mot_vec[0] <= 1e-10 || check_mot_vec[1] <= 1e-10){
				var x_y_flag = check_mot_vec[0] <= 1e-10 ? 1 : 0;
				var x_y_table=[
				[[0,0],[1,1]],//0
				null,//1
				[[0,1],[3,0]],//2
				null,//3
				null,//4
				null,//5
				[[2,1],[1,0]],//6
				null,//7
				[[2,0],[3,1]],//8
				];
				var ct_dir = x_y_table[start_norm_id][x_y_flag];
				var rot_target = rotate_face_lookup[start_id[0]][ct_dir[0]];
				p_it.the_cube.turn(rot_target,0,ct_dir[1]);
				return true;
			}
		}else{//跨面動作
			var checker = rotate_face_lookup[start_id[0]].findIndex(function(ele){return ele==end_id[0]});
			var ct_dir = null;
			var rot_way = null;
			var axis_pos = null;
			if(checker % 2 == 1){
				axis_pos = start_pos[1];
				ct_dir = (axis_pos<0)?2:0;
				rot_way = (checker>2)?0:1;
				rot_way = (axis_pos<0)?(1-rot_way):rot_way;
			}else{
				axis_pos = start_pos[0];
				ct_dir = (axis_pos<0)?1:3;
				rot_way = (checker>0)?0:1;
				rot_way = (axis_pos<0)?(1-rot_way):rot_way;
			}
			if(ct_dir!=null && rot_way!=null && axis_pos!= null){
				var rot_target = rotate_face_lookup[start_id[0]][ct_dir];
				p_it.the_cube.turn(rot_target,axis_pos==0?1:0,rot_way);
				return true;
			}
		}
		return null;
	}
	$(".cube>div").mouseup(function() {
		if(selected_block != null && selected_block != this){
			rotate_process(this, selected_block);
		}
		selected_block = null;
	});
	
	$(".cube>div").bind('touchstart', function(event){
		selected_block = $(event.target)[0];
	})
	$(".cube>div").bind('touchmove', function(event){
		selected_block = $(event.target)[0];
	})
	$(".cube>div").bind('touchend', function(event){
		var check_this = $(event.target)[0];
		if(selected_block != null && selected_block != check_this){
			rotate_process(check_this, selected_block);
		}
		selected_block = null;
	})
	var cube_dom_arr = $(".cube-main");
	for(var i=0; i<cube_dom_arr.length; ++i)
		window.buildCube(cube_dom_arr[i])
	$(".cube-cmd").click(function() {
		var checker = $(this).find(".name")
		if(checker.length>0)$("."+$(checker[0]).text())[0].the_cube.turnByCommand($(this)
			.clone().children().remove().end().text()
		,350);
		else $(".cube-main")[0].the_cube.turnByCommand($(this).text(),350);
	})
});