zoukankan      html  css  js  c++  java
  • 仿一个好玩的滑动效果

    起因

    昨天跑步的时候,看到一个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。(完)

  • 相关阅读:
    leetcode--Populating Next Right Pointers in Each Node II
    leetcode—Populating Next Right Pointers in Each Node
    Pascal's Triangle II
    leetcode—pascal triangle
    leetcode—triangle
    October 23rd, 2017 Week 43rd Monday
    October 22nd, 2017 Week 43rd Sunday
    October 21st 2017 Week 42nd Saturday
    October 20th 2017 Week 42nd Friday
    October 19th 2017 Week 42nd Thursday
  • 原文地址:https://www.cnblogs.com/imgss/p/9655845.html
Copyright © 2011-2022 走看看