热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

每周一点canvas动画——《支付宝价格拖动选择》

效果源码终于到年底了,再过两天我也要回家过年了,想想就激动呢!今天给大家带来一个基于移动端的canvas价格选择效果。主要功能就是拖动标尺变动价格。而且支付宝和京东金融的里也有这样

效果源码

终于到年底了,再过两天我也要回家过年了,想想就激动呢!今天给大家带来一个基于移动端的canvas价格选择效果。

《每周一点canvas动画——《支付宝价格拖动选择》》

主要功能就是拖动标尺变动价格。而且支付宝和京东金融的里也有这样的效果(果然天下设计都是你抄我我抄你啊?)。

效果演示地址

1.实现思路

整个效果的核心就是用canvas绘制的标尺。一共包括标尺主体,数字,和中间固定不变的标定轴,这几个部分都用canvas绘制。最上面的大号价格文字,因为其他地方会需要用它来计算相关的收益。所以,我们就用个DOM来呈现,这样比较方便获取。

标尺拖动的距离与价格之间有有一个映射关系,是整个效果最不好处理的部分,在具体处理到相关问题的时候我们再做分析。现在,我们先实现基础的标尺绘制。

2.标尺属性定义

我们先定义一个类叫Rule.js, 其具体属性如下。

《每周一点canvas动画——《支付宝价格拖动选择》》

现在我们来了解一下每个属性的含义:

  1. x, y: 标尺的坐标位置
  2. vx: 标尺的移动速度
  3. ax: 标尺移动加速度
  4. color: 绘制标尺线条的颜色,与文字颜色
  5. scaleX, scaleY: 缩放比
  6. markShort, markLong: 标尺长短线的长度
  7. textHeight: 文字距离标尺主体的高度
  8. min, max: 要展示的最大值和最小值
  9. width: 标尺的像素宽度
  10. step: 步长
  11. seg: 段数
  12. pxStep: 在canvas上的实际步长(单位为px)
  13. minPxStep: 每个pxStep分10小段,每小段的实际像素宽度
  14. lineBottom: 底部横线参数
  15. lineRed: 标定轴参数

参数比较多,但真正需要传入的参数其实并不是很多。这里我讲解一下(8)~(15)这几个参数的思路。

min, max : 参数的作用是设置需要显示的最大金额和最小金额。这两个参数是外部传入的,比如设定用户最小能存100元,最大能存100000万元。那么min和max就分别对应100和100000。

width : 是整个标尺的实际屏幕长度,比如你只想标尺绘制1000px,那这里就传1000就好了。

step : 步长的含义就是每隔多少分一段,比如我们设定的最大金额为10000元, 那设置step为1000就意味着,每隔1000元表示一个小段,这也是canvas上标尺刻度需要绘制的数据。

seg : 段数等于总金额max除以step。

pxStep : 为真正映射到canvas上的像素步长。

miniPxStep : 每个pxStep分为10小段,每小段的像素距离。

lineBottom : 独立出来不和标尺刻度一起绘制,在绘制标尺的底部横线时,我是这样想的。底部横线的宽度其实就是canvas的宽度,没必要从标尺的初始画到标尺的结尾。而且为了用户体验,刻度的初始位置和结束位置都位于整个canvas的中心。所以,如果合在一起绘制,你需要先绘制一段没刻度的横线,然后再绘制刻度,到最后还要绘制一段没刻度的横线。这给无疑让绘制和后续的标尺移动变得相当麻烦。所以我把它抽出来,就是一条贯穿canvas的普通横线。

lineRed : 标定轴,始终在canvas的中间,也独立出来不和标尺刻度一起绘制。

属性都有了,下面添加一个draw方法,把我们的标尺绘制出来。

2.标尺绘制

a) 绘制标尺刻度部分
《每周一点canvas动画——《支付宝价格拖动选择》》
这里有个截图错误,应该是i+=this.miniPxStep。这应该不难理解,就是每隔miniPxStep绘制一次线段,线段的类型根据n这个变量来确定。

b) 绘制标尺文字部分

《每周一点canvas动画——《支付宝价格拖动选择》》

文字的绘制不能以真实的屏幕像素为准,必须映射到金额上,所以,这里绘制的数字是(n/10)* this.step。同时,还做了一个特殊的处理,就是初始值是1,不是0。因为,我们的金额不允许输入0元。如果你不需要这个,把这里注释掉就ok了。

c) 绘制底部横线

《每周一点canvas动画——《支付宝价格拖动选择》》

d) 绘制标定轴

《每周一点canvas动画——《支付宝价格拖动选择》》

这样整个标尺就完成了,rule.js文件在顶部的github中。现在我们调用一下这个文件,看看画出来的效果怎样。

《每周一点canvas动画——《支付宝价格拖动选择》》

这里我们设置了最大额度为100000元,最小额度为500元。整个标尺的长度为5000px,步长step为1000元。效果图如下:

《每周一点canvas动画——《支付宝价格拖动选择》》

让标尺偏移个200px, 比如设置: x: ruleX - 200, 效果如下:

《每周一点canvas动画——《支付宝价格拖动选择》》

设置步长step为500,效果如下:

《每周一点canvas动画——《支付宝价格拖动选择》》

ok,现在静态标尺就绘制完成,下一步就要完成交互功能,让标尺能够跟随鼠标滚动,并且展示当前拖动的金额。

3.拖动标尺

现在我们开始实现标尺的拖动。标尺的拖动原理很简单,就是让标尺的位置跟随鼠标移动。这里为了演示方便我换成了鼠标事件,到移动端换成touch事件即可。

首先引入我们的工具函数utils.js文件,然后定义几个变量。
《每周一点canvas动画——《支付宝价格拖动选择》》

isMouseDown用来判断鼠标是否抬起, oldX用来记录上一次拖动的位置,mouse是使用captureMouse返回的对象,返回鼠标在canvas上的当前位置信息。

然后,监听canvas的鼠标事件mousedown, mouseup, mousemove。并改变rule的位置。

《每周一点canvas动画——《支付宝价格拖动选择》》

当鼠标按下时,isMouseDown变为true, offsetX在上面忘记写了,它的作用是记录鼠标按下的位置与标尺位置之间的偏移量。然后在鼠标移动时标尺的位置rule.x = mouse.x - offsetX。如果不这样做,在点击canvas并拖动标尺的一瞬间,你会发现标尺的初始位置会瞬移到鼠标点击位置,这样体验很不好,我们需要不管点击哪,标尺都会在现有的位置跟随鼠标移动。如果,无法体会,动手试一试去掉回事什么效果。

oldX也很好理解,就是记录标尺上一次的位置,这里还没有用到它,后面可能会用到。
现在我们把标尺的绘制写进动画函数中

《每周一点canvas动画——《支付宝价格拖动选择》》

看看动画效果如何。

《每周一点canvas动画——《支付宝价格拖动选择》》

ok,现在我们已经实现了标尺跟随鼠标的拖动。下一步,我们就把拖动的金额显示出来。

4.金额显示

首先,增加一个input输入框,然后获取它。

《每周一点canvas动画——《支付宝价格拖动选择》》

这里设置了输入框的最小值为标尺的最小额度,这里可以先不用管它。我们主要看onMouseMove函数

《每周一点canvas动画——《支付宝价格拖动选择》》

注意money的计算值,它为(centerX - rule.x)*rule.ratioScale(centerX - rule.x)比较好理解,因为,我们的标尺是从canvas的中心点绘制的。但rule.ratioScale在最开始的构造函数中并没有定义。这里需要在构造函数中加上,它的含义是每像素代表多少钱,可以认为是图形比例尺。

this.ratioScale = Math.floor(this.max / this.width) //比列尺

那么自然,移动距离乘以比例尺就得出钱数了。我们看看效果。

《每周一点canvas动画——《支付宝价格拖动选择》》

注意到上面的效果中金额显示出现了负数,所以我们需要对移动范围做限制。让其只能在限定的最大和最小金额之间移动。

5.移动范围限定

对一定范围的限定主要分为两部分。一、标尺范围的限定。二、金额显示的限定。这两部分我们放在一起做。

1)重设标尺的初始位置
假设我们设置的最小金额为500元,那么初始标定轴的位置应该就是500元的位置。所以初始化标尺的位置后,我们给它重置为最小金额的位置。这时候需要把金额换算一下。

rule.x = centerX - rule.min / rule.ratioScale;

就是把金额值得计算倒一下。

2)限定标尺的移动范围

《每周一点canvas动画——《支付宝价格拖动选择》》

这里定义了一个检测边界值得函数,当金额小于最小投资金额时,标尺的位置为初始位置start(注意这个初始位置是已经被重置过的), 并且设置金额为最小额度。最大位置同理。
然后,在onMouseMove中调用。

《每周一点canvas动画——《支付宝价格拖动选择》》

看看效果图。

《每周一点canvas动画——《支付宝价格拖动选择》》

6.输入金额移动标尺

标尺的移动除了拖动以外,我们也希望通过金额输入框来达到。即输入金额,标尺便移动到目标金额的位置。

《每周一点canvas动画——《支付宝价格拖动选择》》

同时我们也做了边界限定,当输入的金额小于或者大于设定值时会,设置标尺的位置和输入框的显示为边界值,看看效果。

《每周一点canvas动画——《支付宝价格拖动选择》》

7.来个速度吧

现在拖动的还比较不自然,我们想要手指离开后标尺还会继续移动,直到速度慢慢减为0。为此,新建两个变量。

var speed = 0, fl = 0.95; //初始速度, 摩擦系数

新建一个move函数,在动画循环中调用。

《每周一点canvas动画——《支付宝价格拖动选择》》

《每周一点canvas动画——《支付宝价格拖动选择》》

至此,拖动输入的核心功能就开发完了。如果你要在项目中使用,另一个需要注意的事情是canvas在移动端的模糊问题,这个已经有了很多的解决方案,你只需要耐心调试就好。最后还是祝大家新年快乐,源码在头部地址哦。


推荐阅读
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 解决Cydia数据库错误:could not open file /var/lib/dpkg/status 的方法
    本文介绍了解决iOS系统中Cydia数据库错误的方法。通过使用苹果电脑上的Impactor工具和NewTerm软件,以及ifunbox工具和终端命令,可以解决该问题。具体步骤包括下载所需工具、连接手机到电脑、安装NewTerm、下载ifunbox并注册Dropbox账号、下载并解压lib.zip文件、将lib文件夹拖入Books文件夹中,并将lib文件夹拷贝到/var/目录下。以上方法适用于已经越狱且出现Cydia数据库错误的iPhone手机。 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了logistic回归(线性和非线性)相关的知识,包括线性logistic回归的代码和数据集的分布情况。希望对你有一定的参考价值。 ... [详细]
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • Mac OS 升级到11.2.2 Eclipse打不开了,报错Failed to create the Java Virtual Machine
    本文介绍了在Mac OS升级到11.2.2版本后,使用Eclipse打开时出现报错Failed to create the Java Virtual Machine的问题,并提供了解决方法。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • FeatureRequestIsyourfeaturerequestrelatedtoaproblem?Please ... [详细]
author-avatar
水灵ruru
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有