1. 程式人生 > 實用技巧 >用js仿探探拖拽卡片的效果、飛卡片的效果,感覺挺酷,最後有美女看哦!

用js仿探探拖拽卡片的效果、飛卡片的效果,感覺挺酷,最後有美女看哦!

此文轉載自:https://blog.csdn.net/dkm123456/article/details/111724361#commentBox

目錄

前兩天在網上看到一個用vue寫飛卡片的,覺得很有意思,我就自己想寫一個,就花了點時間搞了一下,做的不好望大家多多指教。

兩個主要的功能:

先看看效果:

首先要做一個盒子,然後生成幾張卡片放到這個盒子裡面

然後用js給卡片設定樣式,有幾個要注意的地方

根據拖拽的方向,來處理動畫,橫向就設定left屬性,縱向則設定top屬性。

超過一定範圍就結束動畫,然後將當前移動的卡片轉到佇列的的第一個位置,再呼叫reset函式,就會重新設定好卡片的位置。

程式碼

來幾個美女看一下吧,不知合大家口味不?

給個三連吧,哈哈!


前兩天在網上看到一個用vue寫飛卡片的,覺得很有意思,我就自己想寫一個,就花了點時間搞了一下,做的不好望大家多多指教。

兩個主要的功能:

1.空白的地方點選最上面開始移動卡片,然後這個卡片會回到最下面,同時其他卡片往上移動。

2.拖動卡片超過多少範圍會飛出去(上、下、左、右四種方向)--拖動中間的卡片也可以。

先看看效果:

第一次用視訊做圖片,做的不好,哈哈!

首先要做一個盒子,然後生成幾張卡片放到這個盒子裡面

然後用js給卡片設定樣式,有幾個要注意的地方

1.從下往上每個卡片的寬度加了12px,高度不動;

2.margin-top和margin-left每個增加了6px;

3.每個單獨設定了顏色,為了好看;

4.封裝了reset函式,初始的時候呼叫,當移動動畫完成後,再次呼叫,可以重新排列好盒子(只需要把佇列中卡片的順序調換既即可)。

		//重新設定卡片的樣式
		function reset(){
			for(var i=0;i<boxStack.length;i++){
				//對每一張卡片設定樣式,每張稍微有點不一樣
				var obj = boxStack[i];
				 	obj.style.left=left+'px';
				 	obj.style.top=top+'px';
					obj.style.marginLeft=marginLeft-i*6+'px';
					obj.style.marginTop=marginTop-i*6+'px';
					obj.style.zIndex=zIndex+i;
					obj.style.width=(width+i*12)+'px';
					obj.style.height=height+'px';
					
					//每個卡片設定不同的顏色
					switch (obj.id) {
						case 'card1':
							obj.style.background = 'aliceblue';
							break;
						case 'card2':
							obj.style.background = 'skyblue';
							break;
						case 'card3':
							obj.style.background = 'powderblue';
							break;
						case 'card4':
							obj.style.background = 'steelblue';
							break;
						
					}
			}
		}

看一下盒子初始化好的模樣,還行,不算太醜,哈哈

根據拖拽的方向,來處理動畫,橫向就設定left屬性,縱向則設定top屬性。

			//針對上下左右有不同的設定
					if(direction=='left'){
						distance -= speed;
						dire='left';
						if(distance<=1){
							endFlag=true;
						}
					}else if(direction=='top'){
						distance -= speed;
						dire='top';
						if(distance<=1){
							endFlag=true;
						}
					}else if(direction=='bottom'){
						distance += speed;
						dire='top';
						if(distance>=90){
							endFlag=true;
						}
					}else{
						distance += speed;
						dire='left';
						//超過一定範圍就調整卡片
						if(distance>=90){
							endFlag=true;
						}
					}


                    obj.style[dire]=distance +'%';

超過一定範圍就結束動畫,然後將當前移動的卡片轉到佇列的的第一個位置,再呼叫reset函式,就會重新設定好卡片的位置。

                    if(endFlag){
						//清除定時器
						clearInterval(obj.timer);
						obj.timer=null;
						//把當前元素 從盒子佇列中移動到最前面
						moveFlag=false;
						
						var index = boxStack.findIndex(function(item){
							return obj.id==item.id;
						})
						
						var cur = boxStack.splice(index,1);
						
						boxStack.unshift(cur[0]);//新增到佇列最前面
						
						setTimeout(function(){
							reset();//重新部署盒子
						},50)//設定重寫設定盒子樣式的延時,看起來更舒服	
						return ;
					}

至於拖拽的我就不多說了,我這個好像也還不是很好,拖拽有時候感覺會有點卡頓,後面再完善吧。

程式碼

 
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=GBK">
        <style>
        *{
        	margin:0;padding:0;
        }
		.card{
			 position: absolute;
			 border:1px solid black;
			 border-radius:8px;
		}
        </style>
        </head>
        <body>
       		<div class="box" id="div_box" >
       		</div>
        </body>
        
<script>
//1.空白的地方點選最上面開始移動卡片
//2.拖動卡片超過多少範圍會飛出去(上、下、左、右四種方向)--拖中間的也可以

	(function(){
		var div_box = document.getElementById("div_box");// 獲取盒子
			div_box.addEventListener('click',tranBox);
			
		var boxStack=[];//用來儲存卡片dom物件的
	
		//建立卡片
		function initCard(){
			var screenWidth = window.screen.availWidth-20;
			var screenHeight = window.screen.availHeight-110;
			div_box.style.width=screenWidth+'px';
			div_box.style.height=screenHeight+'px';
			
			var card_num=4;
			for(var i=1;i<=card_num;i++){//生成卡片
				var div = document.createElement("div");
					div.id="card"+i;
					div.className="card";
					div.addEventListener('mousedown',drag);	
					/*var img = document.createElement("img");
						img.src="images/"+i+".jpg";
						div.appendChild(img);*/
					
					div_box.appendChild(div);
					
					boxStack.push(div);//一個個的推入到盒子佇列
			}
			//第一次設定卡片樣式
			reset();
		}
		
		var left=600,top=160,marginLeft=marginTop=24,zIndex=2,width=120,height=200;
		//重新設定卡片的樣式
		function reset(){
			for(var i=0;i<boxStack.length;i++){
				//對每一張卡片設定樣式,每張稍微有點不一樣
				var obj = boxStack[i];
				 	obj.style.left=left+'px';
				 	obj.style.top=top+'px';
					obj.style.marginLeft=marginLeft-i*6+'px';
					obj.style.marginTop=marginTop-i*6+'px';
					obj.style.zIndex=zIndex+i;
					obj.style.width=(width+i*12)+'px';
					obj.style.height=height+'px';
					
					//obj.children[0].style.width=(width+i*12)+'px';
					//obj.children[0].style.height=height+'px';
					
					//每個卡片設定不同的顏色
					switch (obj.id) {
						case 'card1':
							obj.style.background = 'aliceblue';
							break;
						case 'card2':
							obj.style.background = 'skyblue';
							break;
						case 'card3':
							obj.style.background = 'powderblue';
							break;
						case 'card4':
							obj.style.background = 'steelblue';
							break;
						
					}
			}
		}
		//拖動卡片的事件函式
		function tran(e){
			var e = e || window.event;
			var target = e.target || e.srcElement;
			console.log(target.id);
			if(target.id){
				//拖動當前的卡片
			 	move_tran(target);
			}
		}
		//點選box的事件函式
		function tranBox(e){
			var e = e || window.event;
			var target = e.target || e.srcElement;
			if(target.id){
				if(target.id==='div_box'){//點選div_box從最上面開始飛
					move_tran(boxStack[boxStack.length-1]);
				}
			}
		}
		
		var moveFlag=false;//正在移動表示,有卡片正在移動,move 函式將不會被呼叫
		function move_tran(obj,direction,step){
			if(moveFlag) return ;//表示有卡片正在移動,move 函式將不會被呼叫
			if(obj.timer) return ;//避免重複點選
			moveFlag=true;//設定當前正在移動
			step=step||0;
			
			var cb = (function (){//回撥函式
				var speed=5;
				var screenTotal=0;
				var distance = 0;
				var endFlag=false;
				function init(){//處理初始步距
					if(direction=='top'||direction=='bottom'){
						speed=10;
						screenTotal = window.screen.availHeight;
						distance = Math.ceil((top+step)/screenTotal*100);
					}else{
						screenTotal = window.screen.availWidth;
						distance = Math.ceil((left+step)/screenTotal*100);
					}
				}
				
				init();
				
				return function(){
					//針對上下左右有不同的設定
					if(direction=='left'){
						distance -= speed;
						dire='left';
						if(distance<=1){
							endFlag=true;
						}
					}else if(direction=='top'){
						distance -= speed;
						dire='top';
						if(distance<=1){
							endFlag=true;
						}
					}else if(direction=='bottom'){
						distance += speed;
						dire='top';
						if(distance>=90){
							endFlag=true;
						}
					}else{
						distance += speed;
						dire='left';
						//超過一定範圍就調整卡片
						if(distance>=90){
							endFlag=true;
						}
					}
					
					if(endFlag){
						//清除定時器
						clearInterval(obj.timer);
						obj.timer=null;
						//把當前元素 從盒子佇列中移動到最前面
						moveFlag=false;
						
						var index = boxStack.findIndex(function(item){
							return obj.id==item.id;
						})
						
						var cur = boxStack.splice(index,1);
						
						boxStack.unshift(cur[0]);//新增到佇列最前面
						
						setTimeout(function(){
							reset();//重新部署盒子
						},50)//設定重寫設定盒子樣式的延時,看起來更舒服	
						return ;
					}
					console.log("distance===",distance)
					//設定left或者top作移動
					obj.style[dire]=distance +'%';
				}
			})();
			
			
			obj.timer = setInterval(cb,35);
			
		}


		/* 滑鼠拖動 */
	 	/*
         * 分析:
         * 獲取滑鼠實時移動的座標;m_move_x,m_move_y
         * 滑鼠按下時的座標;m_down_x,m_down_y
         * div的座標;dx,dy
         * div的新座標;ndx,ndy
         * 最大邊界maxX,maxY
         * 滑鼠相對位移 nx,ny
         */
 
        var isDown = false;//記錄滑鼠狀態
        var recover = false;
        var move_div;//要操作的div物件
        var m_move_x,m_move_y,m_down_x,m_down_y,dx,dy,ndx,ndy,maxX,maxY,nx=0,ny=0;
 
        //滑鼠按下
        function drag(e){
        	var e = e || event;
            move_div = this;
            isDown = true;
 
            //獲取滑鼠按下時座標
            m_down_x = e.clientX;
            m_down_y = e.clientY;
            
            //實時更新div的座標
            dx = move_div.offsetLeft;
            dy = move_div.offsetTop;
        }
        //滑鼠移動
        document.onmousemove=function move(e){
			 var e = e || event;
            //滑鼠按下時移動才觸發
            if(isDown && move_div){
	            //獲取滑鼠移動實時座標
	            m_move_x = e.clientX;
	            m_move_y = e.clientY;
	           
	            nx = m_move_x-m_down_x;
	            ny = m_move_y-m_down_y;
	            
	            if(Math.abs(nx)>=200){
	          		move_tran(move_div,nx>0?'right':'left',nx);
	          		isDown = false;
            		move_div= null;
	            	return ;
	            }else if(Math.abs(ny)>=100){
	            	move_tran(move_div,ny>0?'bottom':'top',ny);
	          		isDown = false;
            		move_div= null;
	            	return ;
	            }
	         
	            var id = move_div.id.substr(4);
	            ndx = dx+nx-(id-1)*4;
	            ndy = dy+ny-(id-1)*4;
	            
				//設定拖動的邊界
				maxX = window.screen.availWidth-20-move_div.offsetWidth;
				maxY = window.screen.availHeight-110-move_div.offsetHeight;
				if(ndx<=0){
					ndx=1;
				}
				if(ndy<=0){
					ndy=1;
				}
				if(ndx>=maxX){
					ndx=maxX;
				}
				if(ndy>=maxY){
					ndy=maxY;
				}
				
                //把新div座標值賦給div物件
                move_div.style.left = ndx+"px";
                move_div.style.top = ndy+"px";
            }
 
        }
 
        //滑鼠釋放
        document.onmouseup=function up(e){
            var e = e || event;
            //獲取滑鼠移動實時座標
            m_move_x = e.clientX;
            m_move_y = e.clientY;
           
            nx = m_move_x-m_down_x;
            ny = m_move_y-m_down_y;
	            
	        if(nx<300){
          		reset();
            }
            isDown = false;
            move_div= null;
		 }

		//初始化
		initCard();
		
	})()

</script>
</html>

來幾個美女看一下吧,不知合大家口味不?

動圖就沒搞了,這個對動畫要求高,弄出來效果不好,我還不太會弄。

給個三連吧,哈哈!