欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

H5页面加入购物车动画【贝塞尔二次曲线】 博客分类: 代码交流  

程序员文章站 2024-03-14 13:03:16
...

我又搞了个H5的页面,和小程序的不太一样。

废话不多说,上代码。

bezier.js

 

function bezier(points,times){
	console.log(points)
    // 0、以3个控制点为例,点A,B,C,AB上设置点D,BC上设置点E,DE连线上设置点F,则最终的贝塞尔曲线是点F的坐标轨迹。
    // 1、计算相邻控制点间距。
    // 2、根据完成时间,计算每次执行时D在AB方向上移动的距离,E在BC方向上移动的距离。
    // 3、时间每递增100ms,则D,E在指定方向上发生位移, F在DE上的位移则可通过AD/AB = DF/DE得出。
    // 4、根据DE的正余弦值和DE的值计算出F的坐标。
    // 邻控制AB点间距
    var bezier_points = [];
    var points_D = [];
    var points_E = [];
    const DIST_AB = Math.sqrt(Math.pow(points[1]['x'] - points[0]['x'], 2) + Math.pow(points[1]['y'] - points[0]['y'], 2));
    // 邻控制BC点间距
    const DIST_BC = Math.sqrt(Math.pow(points[2]['x'] - points[1]['x'], 2) + Math.pow(points[2]['y'] - points[1]['y'], 2));
    // D每次在AB方向上移动的距离
    const EACH_MOVE_AD = DIST_AB / times;
    // E每次在BC方向上移动的距离 
    const EACH_MOVE_BE = DIST_BC / times;
    // 点AB的正切
    const TAN_AB = (points[1]['y'] - points[0]['y']) / (points[1]['x'] - points[0]['x']);
    // 点BC的正切
    const TAN_BC = (points[2]['y'] - points[1]['y']) / (points[2]['x'] - points[1]['x']);
    // 点AB的弧度值
    const RADIUS_AB = Math.atan(TAN_AB);
    // 点BC的弧度值
    const RADIUS_BC = Math.atan(TAN_BC);
    // 每次执行
    for (var i = 1; i <= times; i++) {
      // AD的距离
      var dist_AD = EACH_MOVE_AD * i;
      // BE的距离
      var dist_BE = EACH_MOVE_BE * i;
      // D点的坐标
      var point_D = {};
      
      if(points[0]['x']<points[1]['x']){
        point_D['y'] = dist_AD * Math.sin(RADIUS_AB) + points[0]['y'];
        point_D['x'] = dist_AD * Math.cos(RADIUS_AB) + points[0]['x'];
      }else{
        point_D['y'] = points[0]['y']- dist_AD * Math.sin(RADIUS_AB);
        point_D['x'] = points[0]['x']- dist_AD * Math.cos(RADIUS_AB)  ;
        console.log(points[0]['x'] + '.....' + dist_AD*Math.cos(RADIUS_AB))
      }
   
      
      points_D.push(point_D);
      // E点的坐标
      var point_E = {};
      
      
      if (points[0]['x'] < points[1]['x']) {
        point_E['y'] = dist_BE * Math.sin(RADIUS_BC) + points[1]['y'];
        point_E['x'] = points[1]['x'] + dist_BE * Math.cos(RADIUS_BC);
      }else{
        point_E['y'] = points[1]['y']-dist_BE * Math.sin(RADIUS_BC);
        point_E['x'] = points[1]['x'] - dist_BE * Math.cos(RADIUS_BC);
      }
      
      points_E.push(point_E);
      // 此时线段DE的正切值
        var tan_DE = (point_E['y'] - point_D['y']) / (point_E['x'] - point_D['x']);

      
      // tan_DE的弧度值
      var radius_DE = Math.atan(tan_DE);
      // 地市DE的间距
      var dist_DE = Math.sqrt(Math.pow((point_E['x'] - point_D['x']), 2) + Math.pow((point_E['y'] - point_D['y']), 2));
      // 此时DF的距离
      var dist_DF = (dist_AD / DIST_AB) * dist_DE;
      // 此时DF点的坐标
      var point_F = {};
      // console.log(point_D['x'] +'........'+dist_DF * Math.cos(radius_DE))
      
      if (points[0]['x'] < points[1]['x']) {
        point_F['y'] = dist_DF * Math.sin(radius_DE) + point_D['y'];
        point_F['x'] = dist_DF * Math.cos(radius_DE) + point_D['x'];
      }else{
       
        point_F['y'] = point_D['y'] - dist_DF * Math.sin(radius_DE);


        point_F['x'] = point_D['x']-dist_DF * Math.cos(radius_DE) ;
        
      }

      bezier_points.push(point_F);
    }
    return {
      'bezier_points': bezier_points
    };
}
 function startAnimation(linePos,width,height) {
    var index = 0,bezier_points = linePos['bezier_points'];
	$('.animateImage').css({"visibility":'visible'})
	console.log(bezier_points)
	timer = setInterval(function () {
	  	index++;
	  	width = width-6;
	  	height = height-6;
	  	
	  	var bus_x=bezier_points[index]['x']-width/2;
		var bus_y=bezier_points[index]['y']-height/2;
		console.log(bus_x,bus_y)
		//更改抛入购物车的图片的大小	
		$('.animateImage').attr({'width':width,'height':height})
	  	//更改图片位置
	  	$('.animateImage').css({'top':bus_y+'px',"left":bus_x+'px'})
	  
		
	   	if(index>28){
	   		clearInterval(timer);
	   		$('.animateImage').css({"visibility":'hidden'})
	   	}

    }, 35);
}

 点击购物车按钮后事件:

 

 

$('.buys').click(function(event){
	//获取贝塞尔曲线起始点
	var e = event;
	var img = $(this).parent().parent().parent().children().children(img)[0];
        //这里是查找加入购物车那个图标上方对应的图片。
	var pos = img.getBoundingClientRect();
	console.log(pos.top+','+pos.left)
	imgWidth = pos.width;
	imgHeight = pos.height;
	//显示图片
	$('.animateImage').attr('src',img.src)
	var startX = pos.left+pos.width/2;
	var startY = pos.top+pos.height/2;
	finger['x']=startX;
	finger['y']=startY
	//获取贝塞尔曲线终点
	var cart = $('.cart')[0];
	console.log(cart)
	var cartPos = cart.getBoundingClientRect();
	var endX = cartPos.left+cartPos.width/2;
	var endY = cartPos.top+cartPos.height/2;
	busPos['x'] = endX;
	busPos['y'] = endY;
	//计算控制点坐标
	if (finger['x'] < busPos['x']) {
      controlPoint['x'] = Math.abs(busPos['x'] - finger['x']) / 2 + finger['x'];

    } else {
      controlPoint['x'] = Math.abs(finger['x'] - busPos['x']) / 2 + busPos['x'];
    }
	controlPoint['y'] = finger['y'] - 100;
	console.log(controlPoint['x'],controlPoint['y'])
         //finger数组是商品图片中心点对应的坐标
         //controlPoint数组是控制点坐标 我选择的是x坐标是起点终点x坐标差的一半+起点x坐标
         //busPos数组是购物车坐标,一般都是固定位置的,算出坐标就行了
	linePos=bezier([finger,controlPoint,busPos],30)
	
    $(".goods_select").removeClass("hide").addClass("show");
    $(".all_share").removeClass("hide").addClass("show")
});

 选完参数点击加入购物车按钮后的代码:

 

$(".payment-bar").click(function(){
    startAnimation(linePos,imgWidth,imgHeight);
    imgWidth,imgHeiht是商品图片大小
}

 html 页面 和 css 

 

<!--购物车-->
<div class="cart">
	<img src="images/gw.png" />
</div>
<!--复制一个商品图片出来,用来移动-->
<image class='animateImage' ></image>


.cart{
	width: 50px;
	height: 50px;
	border: 1px solid #DCDCDC;
	border-radius: 50%;
	position: fixed;
	bottom: 100px;
	right: 30px;
	display: flex;
	justify-content: center;
	align-items: center;
	background-color: #F5F5F5;
	box-shadow: 2px 2px 2px #DCDCDC;
}
.cart img{
	width: 30px;
	height: 30px;
}

.animateImage{
	visibility: hidden;
	position: fixed;
	z-index: 9999;
}

 还是用的之前那篇文章里老兄的算法。