>  기사  >  웹 프론트엔드  >  JavaScript는 Lagou.com과 유사한 마우스 이동 및 이동 효과를 구현합니다.

JavaScript는 Lagou.com과 유사한 마우스 이동 및 이동 효과를 구현합니다.

高洛峰
高洛峰원래의
2016-12-08 15:28:481555검색

먼저 렌더링(직접 녹음한 gif, 좀 못생겼음, 미안, 도구 licicecap)

JavaScript는 Lagou.com과 유사한 마우스 이동 및 이동 효과를 구현합니다.

구현 아이디어

HTML 구조

<ul>
  <li>
    <div class="bg">
      <p>JS</p>
    </div>
  </li>
  .....
</ul>

li는 mouseenter와 mouseleave의 캐리어 역할을 합니다.

div는 애니메이션 실행의 전달자 역할을 합니다.

CSS

div는 절대 위치 지정을 사용하고 위쪽과 왼쪽을 통해 위치를 변경합니다.

div의 상단과 왼쪽이 li 크기를 초과할 수 있으므로 li의 Overflow:hidden 설정이 필요합니다.

JS

1. JS를 사용하여 CSS3 전환 애니메이션 조작

2. 마우스 움직임의 안팎 방향 판단 방법

마우스 좌표 관련 지식

MouseEvent 객체

다음은 MouseEvent의 좌표에 대한 몇 가지 관련 지식을 소개합니다.

(clientX, clientY): 시각적 영역을 참조 시스템으로 좌표합니다.

(pageX, pageY): 참조 시스템인 전체 페이지(스크롤 막대에 의해 펼쳐진 영역 포함)의 좌표입니다.

(screenX, screenY): 컴퓨터 화면을 기준 시스템으로 사용하는 좌표입니다.

요소 내부의 좌표 가져오기

function pointTo(element, e) {
  var elementBox = element.getBoundingClientRect();
  return {
    x: e.clientX - elementBox.left,
    y: e.clientY - elementBox.top
  };
}

요소의 왼쪽 상단 좌표 계산

function startPoint(element){
  var x = 0,y = 0;
  while(element != null) {
    x += element.offsetLeft;
    y += element.offsetTop;
    element = element.offsetParent;
  }
  return {
    x: x,
    y: y
  }
}

요소의 너비와 높이를 가져옵니다. (너비와 높이로 생각하지 마세요. 초보자는 특히 실수하기 쉽습니다.)

offsetHeight与offsetWidth

CSS3 전환 애니메이션을 간단히 캡슐화

/* options参数: obj: 运动的对象 speed: 运动的持续时间(可选) changeStyle: 改变的属性,这里可能多个,所以采用函数的方式(可选) callback: 回调函数(可选) */
  function animation(options){
    if(!options.obj) {
      return false;
    }
    //设置默认持续时间
    options.speed = options.speed || &#39;.5s&#39;;
    options.obj.style.transition = "all " + options.speed + " ease-in-out";
 
    options.changeStyle.call(options.obj);
 
    var flag = false;
    options.obj.addEventListener(&#39;transitionend&#39;,function(){
      //这里主要由于transitionend在每个属性的动画执行完多会走一遍,所以我们要让它只执行一次。
      if(!flag) {
 
        options.callback && options.callback();
      }
    },false);
  }

방향을 결정하는 방법

접선과 관련된 개념 여기서는 수학에서 직접 그림을 그렸는데, 확실히 이해가 되실지 궁금합니다

JavaScript는 Lagou.com과 유사한 마우스 이동 및 이동 효과를 구현합니다.

요소의 운동방향을 알아보세요

function getDirection(element,startPoint,pagePoint){
  var halfWidth = element.offsetWidth / 2,halfHeight = element.offsetHeight / 2;
  //得到中心点
  var center = {
    x: startPoint.x + halfWidth,
    y: startPoint.y + halfHeight
  }
  //得到鼠标偏离中心点的距离
  var disX = pagePoint.x - center.x;
  var disY = pagePoint.y - center.y;
  if(disY < 0 && Math.abs(disY / disX) >= 1) {
    //上方
    return 1;
  }
  else if(disY > 0 && Math.abs(disY / disX) >= 1) {
    //下
    return 2;
  }
  else if(disX < 0 && Math.abs(disY / disX) < 1) {
    //左
    return 3;
  }
  else {
    //右
    return 4;
  }
}

이벤트를 시작하는 코드에 댓글이 있습니다

/* options中的参数: 触发事件的载体: targetElement 执行动画的载体: animationElement */
  function HoverAction(options) {
    if(!options.targetElement || !options.animationElement) {
      return false;
    }
    this.targetElement = options.targetElement;
    this.animationElement = options.animationElement;
    this.timeId = null;
    this.speed = "0.3s";
  }
  HoverAction.prototype.addEvent = function() {
    //保存this的指向
    var _this = this;
    _this.targetElement.addEventListener(&#39;mouseenter&#39;,function(e){
      //得到鼠标的坐标
      var point = {
        x: e.pageX,
        y: e.pageY
      }
      console.log(point);
      //获得方向
      var dir = getDirection(_this.targetElement,startPoint(_this.targetElement),point);
      clearTimeout(_this.timeId);
      //取消过渡动画(防止重置动画载体位置时触发过渡效果)
      _this.animationElement.style.transition = "";
      //得到运动的方向,要确定动画载体的开始位置
      switch(dir){
        case 1:
          _this.animationElement.style.top = "-100%";
          _this.animationElement.style.left = "0";
          break;
        case 2:
          _this.animationElement.style.top = "100%";
          _this.animationElement.style.left = "0";
          break;
        case 3:
          _this.animationElement.style.top = "0";
          _this.animationElement.style.left = "-100%";
          break;
        case 4:
          _this.animationElement.style.top = "0";
          _this.animationElement.style.left = "100%";
          break;
      }
      //异步执行
      _this.timeId = setTimeout(function(){
        animation({
          obj: _this.animationElement,
          speed: _this.speed,
          changeStyle: function(){
            this.style.top = "0";
            this.style.left = "0";
          }
        });
      },20);
    },false);
    _this.targetElement.addEventListener(&#39;mouseleave&#39;,function(e){
      var left,top;
      var point = {
        x: e.pageX,
        y: e.pageY
      }
      clearTimeout(_this.timeId);
      _this.animationElement.style.transition = "";
      var dir = getDirection(_this.targetElement,startPoint(_this.targetElement),point);
      switch(dir) {
        case 1:
          top = &#39;-100%&#39;;
          left = &#39;0&#39;;
          break;
        case 2:
          top = &#39;100%&#39;;
          left = "0";
          break;
        case 3:
          left = "-100%";
          top = "0";
          break;
        case 4:
          left = "100%";
          top = "0";
          break;
      }
      _this.timeId = setTimeout(function(){
        animation({
          obj: _this.animationElement,
          speed: _this.speed,
          changeStyle: function(){
            this.style.top = top;
            this.style.left = left;
          }
        });
      },20);
    },false);
 
  }


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.