效果源码终于到年底了,过两天就要回家过年了,想想就兴奋!今天给大家带来一款基于移动端的画布选价效果。主要功能是拖动标尺改变价格。而且支付宝和京东金融也有这个效果(果然是世界设计你抄我我抄你?)。效果演示地址1.实现思路整个效果的核心是用canvas绘制的尺子。它包括标尺主体、数字和中间的固定校准轴。这些部分都是用画布绘制的。顶部的大价格文本,因为其他地方需要它来计算相关收入。所以,我们用一个DOM来呈现,获取起来更方便。尺子拖动的距离和价格之间存在映射关系,这是整个效果中最难的部分。我们在处理相关问题时会进行分析。现在,让我们先实现基本的标尺绘制。2.标尺属性定义我们首先定义一个类叫Rule.js,它的具体属性如下。下面我们来了解一下各个属性的含义:x,y:尺子的坐标位置vx:尺子的移动速度ax:尺子的移动加速度color:绘制尺子线条的颜色,文字颜色scaleX,scaleY:缩放比例markShort,markLong:标尺长短线的长度textHeight:文字距离标尺主体的高度min,max:要显示的最大值和最小值width:标尺的像素宽度step:步长seg:分段数pxStep:画布上的实际步长(单位为px)minPxStep:每个pxStep被分成10个小节,每个小节lineBottom的实际像素宽度:底部横线参数lineRed:标定轴的参数比较多,但是真正需要传入的参数并不多,这里我对参数(8)~(15)的思路进行说明。min,max:该参数的作用是设置要显示的最大和最小量。这两个参数是从外部传入的。例如,用户可以设置最低入金100元,最高入金10亿元。那么min和max分别对应100和100000。width:整个标尺的实际屏幕长度。比如你只想让尺子画1000px,那么这里传1000就可以了。step:stepsize的意思是相互分成多少段。比如我们设置最大金额为10000元,那么设置step为1000意味着每1000元代表一个小段,这也是canvas上的刻度需要绘制数据的。seg:段数等于总量max除以step。pxStep:实际映射到画布上的像素步长。miniPxStep:每个pxStep分为10个小段,每个小段的像素距离。lineBottom:它是独立的,不与scale刻度一起绘制。这就是我在绘制刻度的底部水平线时的想法。底部横线的宽度其实就是画布的宽度,不需要从刻度的开头画到刻度的末尾。并且为了用户体验,刻度的初始位置和结束位置位于整个画布的中心。所以,如果把它们画在一起,需要先画一条没有刻度的横线,再画一个刻度,最后画一条没有刻度的横线。这无疑使绘图和随后的标尺移动变得非常麻烦。所以我把它拉出来,它只是一条穿过画布的普通水平线。lineRed:标定轴始终在画布中间,也是独立的,不与刻度标尺绘制在一起。属性都在那里了,让我们添加一个draw方法来绘制我们的标尺。2.标尺绘制a)绘制标尺刻度的部分有截图错误,应该是i+=this.miniPxStep。这个应该不难理解,就是每隔miniPxStep画一条线段,线段的类型根据变量n来决定。b)绘制尺子文字部分文字的绘制不能根据真实屏幕像素,必须映射到量,所以这里绘制的数字为(n/10)*this.step。同时也做了一个特殊的处理,就是初始值为1,而不是0。因为,我们的金额不允许输入0元。如果你不需要这个,就把它注释掉就可以了。c)绘制底部水平线d)绘制标定轴,这样整个刻度就完整了,rule.js文件在最上面的github中。现在让我们调用这个文件,看看绘图是如何工作的。这里我们设置最大金额为10万元,最小金额为500元。整个尺子的长度是5000px,步长是1000元。效果图如下:将标尺偏移200px,例如设置:x:ruleX-200,效果如下:设置步长为500,效果如下:ok,现在静态标尺是画好了,下一步就是完成交互功能了。允许标尺用鼠标滚动并显示当前拖动的量。3.拖动标尺现在我们开始拖动标尺。拖动尺子的原理很简单,就是让尺子的位置跟随鼠标的移动。这里为了演示方便,我把它换成了鼠标事件,在移动端换成了触摸事件。首先引入我们的实用函数utils.js文件,然后定义几个变量。isMouseDown用于判断鼠标是否抬起,oldX用于记录最后一次拖动的位置,mouse是captureMouse返回的对象,返回鼠标当前在画布上的位置信息。然后监听画布的鼠标事件mousedown、mouseup、mousemove。并改变规则的位置。当鼠标按下时,isMouseDown变为true,上面忘记写offsetX了。它的作用是记录鼠标按下的位置与尺子位置之间的偏移量。那么鼠标移动时标尺的位置就是rule.x=mouse.x-offsetX。如果不这样做,当你点击画布并拖动尺子的那一刻,你会发现尺子的初始位置会瞬移到鼠标点击的位置,这是一种糟糕的体验。无论我们点击哪里,标尺都会在现有位置跟随鼠标移动。如果看不懂,就试着自己去掉效果。oldX也很好理解,就是记录尺子最后的位置,这里没有用到,以后可能会用到。现在我们把尺子的绘制写到动画函数中,看看动画效果如何。ok,现在我们已经实现了标尺跟随鼠标的拖动。在下一步中,我们将显示拖动的数量。4.金额显示首先添加一个input输入框,然后获取。这里设置输入框的最小值作为刻度的最小量,这里可以忽略。我们主要看onMouseMove函数,注意计算出的money值,即(centerX-rule.x)*rule.ratioScale。(centerX-rule.x)更容易理解,因为我们的标尺是从画布的中心点绘制的。但是rule.ratioScale没有在初始构造函数中定义。这里需要在constructor中添加,意思是每个像素代表多少钱,可以看做是图形比例尺。this.ratioScale=Math.floor(this.max/this.width)//刻度好自然,移动的距离乘以刻度就得到钱的数量。让我们看看效果。注意上面效果显示的量是负数,所以我们需要限制移动范围。让它只在定义的最大和最小量之间移动。5.移动范围限制一定范围的限制主要分为两部分。1.规模范围的限制。2.金额显示的限制。我们一起做这两部分。1)重新设置秤的初始位置假设我们设置的最小金额是500元,那么初始标定轴的位置应该是500元的位置。所以在初始化标尺的位置后,我们将其重新设置到最小量的位置。这时候就需要转换金额。rule.x=centerX-rule.min/rule.ratioScale;就是计算金额的价值。2)限制尺子的移动范围。这里,定义了检测边界值函数。当金额小于最低投资金额时,标尺位置为初始位置开始(注意初始位置已重置),金额设置为最低金额。最大位置相同。然后,在onMouseMove中调用它。看效果图。6.输入移动标尺的量。除了拖动标尺的移动,我们还希望通过金额输入框来实现。即输入金额,秤就会移动到目标金额的位置。同时,我们也做了边界限制。当输入的量小于或大于设定值时,将刻度的位置和输入框的显示设置为边界值,看效果。7.拿出一个速度。现在拖拽不自然了。我们想让尺子在手指离开后继续移动,直到速度慢慢降低到0。为此,创建两个新变量。var速度=0,fl=0.95;//初始速度,摩擦系数新建一个移动函数,在动画循环中调用。至此,拖动输入的核心功能已经开发完成。如果要在项目中使用,还有一个需要注意的就是移动端canvas的模糊问题。这个已经有很多解决方案,你只需要耐心调试即可。最后祝大家新年快乐,源码在头部地址。
