• 仿一个好玩的滑动效果


    起因

    昨天跑步的时候,看到一个app(华为手机自带的运动健康)上的滑动效果很有意思,回来之后就想着,能不能在dom上实现一下,于是有了这篇文章。首先看一下效果图,滑动下面的绿色滑块可以看到效果(https://codepen.io/imgss/embed/wEEvKB):

    See the Pen wEEvKB by imgss (@imgss) on CodePen.

    贴出app上的效果图,模仿效果可以说是差强人意吧:
    WechatIMG167.png

    实现

    其实原理很简单,就是在小圆点移动时,计算数字和小圆点的距离,来控制数字的上升和下降。

    首先,要使小圆点跟随鼠标移动起来:代码如下:

    slide.addEventListener('mousedown', function(e){
      e.preventDefault()
      let left = parseInt(slide.style.left) || 0
      let startX = e.clientX
      // slider能移动的最远距离
      let maxLength = document.querySelector('.table').getBoundingClientRect().width - slideWidth
      function move(e){
    	// move的逻辑
    
      }
      document.addEventListener('mousemove', move)
      
      document.addEventListener('mouseup', function(){
        document.removeEventListener('mousemove', move)
      })
    })
    

    这段代码监听了3个事件,mousedown,mouseup,mousemove,当鼠标按下时,触发滑块的mousedown事件,同时给document绑定了mousemove和mouseup事件,来使滑块可以跟着鼠标移动,当鼠标弹起时,使滑块不再随鼠标移动。

    之所以在document元素上监听mousemove事件,是因为如果在滑块上监听,很容易由于鼠标滑动过快,造成鼠标离开滑块的区域,导致mousemove事件失效,而在document元素上监听就不会有这样的问题。接下来我们来看看move这个函数:

      function move(e){
        e.preventDefault()
        let moveX = e.clientX - startX
        if(left + moveX < 0 || left + moveX > maxLength) {
          return
        }
        newLeft = left + moveX
        let newCenterLeft = newLeft + slideWidth / 2
        slide.style.left = newLeft + 'px'
        // 控制数字的上升和下降
        // console.log('========')
        for(let label of labels){
    
          let dist = label.left - newCenterLeft
          // console.log(dist, slideWidth/2)
          if(Math.abs(dist) <= slideWidth / 2){
            label.el.style.top = Math.abs(dist) - slideWidth / 2 + 'px'
            label.el.style.opacity = 0.3 + Math.abs(1 - dist / (slideWidth / 2)) * 0.7
          } else {
            label.el.style.top = '0px'
            label.el.style.opacity = 0.3
          }
        }
      }
    
    

    move函数主要干了两件事,一个是改变滑块的位置,另一个是通过实时判断数字和滑块的距离来改变数字的高度。改变位置都是通过改变元素的left/top样式来实现的。在改变数字高度的实现上,偷了一点懒,从形状上看,滑块边缘是一个半圆形,因此数字距离底部的高度(y)和数字距离滑块圆心的距离(x)应该是一个非线性的关系,函数表达式:

    y = Math.sqrt(R*R - x*x)// R是滑块边缘半径
    

    在实现上直接线性转换了一下R-x。(完)

  • 相关阅读:
    非静态成员的sizeof
    Android中java.lang.ClassNotFoundException: ***.**** in loader dalvik.system.PathClassLoader[/data/app
    手机 SIM卡的EF
    android 获取手机ip的三种方式
    获取图片倒影效果
    python基础
    Python学习_数据处理split方法
    Python学习_从文件读取数据和保存数据
    Python学习_列表推导和Lambda表达式
    python学习_数据处理编程实例(一)
  • 原文地址:https://www.cnblogs.com/imgss/p/9655845.html
Copyright © 2020-2023  润新知