`
除却巫山不是云
  • 浏览: 14028 次
  • 性别: Icon_minigender_1
  • 来自: 嘉兴
社区版块
存档分类
最新评论

H5页面加入购物车动画【贝塞尔二次曲线】

阅读更多

我又搞了个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;
}

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

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics