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; }
还是用的之前那篇文章里老兄的算法。