parabola.js抛物线与加入购物车效果的示例代码
程序员文章站
2022-04-09 21:13:27
在做购物车的时候发现一个很好用抛物线特效parabola.js,可先点击demo体验下。下面贴出一些关键代码,具体代码可在github上查看
parabola.js...
在做购物车的时候发现一个很好用抛物线特效parabola.js,可先点击demo体验下。下面贴出一些关键代码,具体代码可在github上查看
parabola.js
var funparabola = function (element, target, options) { /* * 网页模拟现实需要一个比例尺 * 如果按照1像素就是1米来算,显然不合适,因为页面动不动就几百像素 * 页面上,我们放两个物体,200~800像素之间,我们可以映射为现实世界的2米到8米,也就是100:1 * 不过,本方法没有对此有所体现,因此不必在意 */ var defaults = { speed: 166.67, // 每帧移动的像素大小,每帧(对于大部分显示屏)大约16~17毫秒 curvature: 0.001, // 实际指焦点到准线的距离,你可以抽象成曲率,这里模拟扔物体的抛物线,因此是开口向下的 progress: function () { }, complete: function () { } }; var params = {}; options = options || {}; for (var key in defaults) { params[key] = options[key] || defaults[key]; } var exports = { mark: function () { return this; }, position: function () { return this; }, move: function () { return this; }, init: function () { return this; } }; /* 确定移动的方式 * ie6-ie8 是margin位移 * ie9+使用transform */ var movestyle = "margin", testdiv = document.createelement("div"); if ("oninput" in testdiv) { ["", "ms", "webkit"].foreach(function (prefix) { var transform = prefix + (prefix ? "t" : "t") + "ransform"; if (transform in testdiv.style) { movestyle = transform; } }); } // 根据两点坐标以及曲率确定运动曲线函数(也就是确定a, b的值) /* 公式: y = a*x*x + b*x + c; */ var a = params.curvature, b = 0, c = 0; // 是否执行运动的标志量 var flagmove = true; if (element && target && element.nodetype == 1 && target.nodetype == 1) { var rectelement = {}, recttarget = {}; // 移动元素的中心点位置,目标元素的中心点位置 var centerelement = {}, centertarget = {}; // 目标元素的坐标位置 var coordelement = {}, coordtarget = {}; // 标注当前元素的坐标 exports.mark = function () { if (flagmove == false) return this; if (typeof coordelement.x == "undefined") this.position(); element.setattribute("data-center", [coordelement.x, coordelement.y].join()); target.setattribute("data-center", [coordtarget.x, coordtarget.y].join()); return this; } exports.position = function () { if (flagmove == false) return this; var scrollleft = document.documentelement.scrollleft || document.body.scrollleft, scrolltop = document.documentelement.scrolltop || document.body.scrolltop; // 初始位置 if (movestyle == "margin") { element.style.marginleft = element.style.margintop = "0px"; } else { element.style[movestyle] = "translate(0, 0)"; } // 四边缘的坐标 rectelement = element.getboundingclientrect(); recttarget = target.getboundingclientrect(); // 移动元素的中心点坐标 centerelement = { x: rectelement.left + (rectelement.right - rectelement.left) / 2 + scrollleft, y: rectelement.top + (rectelement.bottom - rectelement.top) / 2 + scrolltop }; // 目标元素的中心点位置 centertarget = { x: recttarget.left + (recttarget.right - recttarget.left) / 2 + scrollleft, y: recttarget.top + (recttarget.bottom - recttarget.top) / 2 + scrolltop }; // 转换成相对坐标位置 coordelement = { x: 0, y: 0 }; coordtarget = { x: -1 * (centerelement.x - centertarget.x), y: -1 * (centerelement.y - centertarget.y) }; /* * 因为经过(0, 0), 因此c = 0 * 于是: * y = a * x*x + b*x; * y1 = a * x1*x1 + b*x1; * y2 = a * x2*x2 + b*x2; * 利用第二个坐标: * b = (y2+ a*x2*x2) / x2 */ // 于是 b = (coordtarget.y - a * coordtarget.x * coordtarget.x) / coordtarget.x; return this; }; // 按照这个曲线运动 exports.move = function () { // 如果曲线运动还没有结束,不再执行新的运动 if (flagmove == false) return this; var startx = 0, rate = coordtarget.x > 0 ? 1 : -1; var step = function () { // 切线 y'=2ax+b var tangent = 2 * a * startx + b; // = y / x // y*y + x*x = speed // (tangent * x)^2 + x*x = speed // x = math.sqr(speed / (tangent * tangent + 1)); startx = startx + rate * math.sqrt(params.speed / (tangent * tangent + 1)); // 防止过界 if ((rate == 1 && startx > coordtarget.x) || (rate == -1 && startx < coordtarget.x)) { startx = coordtarget.x; } var x = startx, y = a * x * x + b * x; // 标记当前位置,这里有测试使用的嫌疑,实际使用可以将这一行注释 element.setattribute("data-center", [math.round(x), math.round(y)].join()); // x, y目前是坐标,需要转换成定位的像素值 if (movestyle == "margin") { element.style.marginleft = x + "px"; element.style.margintop = y + "px"; } else { element.style[movestyle] = "translate(" + [x + "px", y + "px"].join() + ")"; } if (startx !== coordtarget.x) { params.progress(x, y); window.requestanimationframe(step); } else { // 运动结束,回调执行 params.complete(); flagmove = true; } }; window.requestanimationframe(step); flagmove = false; return this; }; // 初始化方法 exports.init = function () { this.position().mark().move(); }; } return exports; };
实现
// body <div class="container"> ![](dist/01.png) <center>点击加入购物车查看效果</center> <!--动画图片--> <div class="img-element" id="imgelement"> ![](dist/02.jpg) </div> <!--购物车--> <div class="shop-cart" id="shopcart"></div> <span class="shop-cart-num">0</span> <div class="add-shop-cart"><!--加入购物车--></div> </div>
// script // 起始位置元素 var imgelement = document.queryselector('#imgelement'), // 终点位置元素 shopcartelement = document.queryselector('#shopcart'), // 购物车数量 pronum = 0; // 初始化抛物线动画 var myparabola = funparabola(imgelement, shopcartelement, { speed: 100,// 每帧移动的像素大小 curvature: 0.005,// 实际指焦点到准线的距离 complete: function () { imgelement.style.visibility = "hidden"; $('.shop-cart-num').text(++pronum); } }); // 绑定加入购物车事件 $('.add-shop-cart').click(function () { // 重置位置 $('#imgelement').css({ left: '70px', bottom: '25px', visibility: 'visible' }); myparabola.position().move(); });
效果图
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: 原生JS与jQuery编写简单选项卡
下一篇: javascript计算对象长度的方法