Day22 - Mouse Anchor Animation Generation Guide

Posted by wesnoel on Tue, 04 Jun 2019 22:39:46 +0200

This article is from: Chunge Personal Blog: http://www.liyuechun.org
Author: extension Li Yuechun - A Time-chasing Man
Introduction: JavaScript30 yes Wes Bos A 30-day challenge to launch. The project provides 30 video tutorials, 30 challenge start documents and 30 challenge solution source code free of charge. The goal is to help people write in pure JavaScript, without using frameworks and libraries or compilers and references. Now you see the 22nd in this series of guidelines. The complete Chinese version of the guide and video tutorial in From Zero to Yiquantan Tribe.

Design sketch

The 22nd day exercise is an animation exercise. When the mouse moves to the anchor, a white color block moves to the current anchor. The illustration is as follows:

HTML source code

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>👀👀👀Follow Along Nav</title>
    <link rel="stylesheet" href="style.css">
</head>

<body>

    <nav>
        <ul class="menu">
            <li><a href="">Home</a></li>
            <li><a href="">Order Status</a></li>
            <li><a href="">Tweets</a></li>
            <li><a href="">Read Our History</a></li>
            <li><a href="">Contact Us</a></li>
        </ul>
    </nav>

    <div class="wrapper">
        <p>Lorem ipsum dolor sit amet, <a href="">consectetur</a> adipisicing elit. Est <a href="">explicabo</a> unde natus
            necessitatibus esse obcaecati distinctio, aut itaque, qui vitae!</p>
        <p>Aspernatur sapiente quae sint <a href="">soluta</a> modi, atque praesentium laborum pariatur earum <a href="">quaerat</a>            cupiditate consequuntur facilis ullam dignissimos, aperiam quam veniam.</p>
        <p>Cum ipsam quod, incidunt sit ex <a href="">tempore</a> placeat maxime <a href="">corrupti</a> possimus <a href="">veritatis</a>            ipsum fugit recusandae est doloremque? Hic, <a href="">quibusdam</a>, nulla.</p>
        <p>Esse quibusdam, ad, ducimus cupiditate <a href="">nulla</a>, quae magni odit <a href="">totam</a> ut consequatur
            eveniet sunt quam provident sapiente dicta neque quod.</p>
        <p>Aliquam <a href="">dicta</a> sequi culpa fugiat <a href="">consequuntur</a> pariatur optio ad minima, maxime <a href="">odio</a>,
            distinctio magni impedit tempore enim repellendus <a href="">repudiandae</a> quas!</p>
    </div>

</body>

</html>

CSS source code

html {
  box-sizing: border-box;
}

*,
*:before,
*:after {
  box-sizing: inherit;
}

body {
  min-height: 100vh;
  margin: 0;
  /* Important! */
  font-family: sans-serif;
  background: linear-gradient(45deg, hsla(340, 100%, 55%, 1) 0%, hsla(340, 100%, 55%, 0) 70%), linear-gradient(135deg, hsla(225, 95%, 50%, 1) 10%, hsla(225, 95%, 50%, 0) 80%), linear-gradient(225deg, hsla(140, 90%, 50%, 1) 10%, hsla(140, 90%, 50%, 0) 80%), linear-gradient(315deg, hsla(35, 95%, 55%, 1) 100%, hsla(35, 95%, 55%, 0) 70%);
}

.wrapper {
  margin: 0 auto;
  max-width: 500px;
  font-size: 20px;
  line-height: 2;
  position: relative;
}

a {
  text-decoration: none;
  color: black;
  background: rgba(0, 0, 0, 0.05);
  border-radius: 20px
}

.highlight {
  transition: all 0.2s;
  border-bottom: 2px solid white;
  position: absolute;
  top: 0;
  background: white;
  left: 0;
  z-index: -1;
  border-radius: 20px;
  display: block;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.2)
}

.menu {
  padding: 0;
  display: flex;
  list-style: none;
  justify-content: center;
  margin: 100px 0;
}

.menu a {
  display: inline-block;
  padding: 5px;
  margin: 0 20px;
  color: black;
}

JS source code

<script>
   const triggers = document.querySelectorAll('a');
   const highlight = document.createElement('span');
   highlight.classList.add('highlight');
   document.body.appendChild(highlight);

   function highlightLink() {
       const linkCoords = this.getBoundingClientRect();
       // console.log(linkCoords);
       const coords = {
           width: linkCoords.width,
           height: linkCoords.height,
           top: linkCoords.top + window.scrollY,
           left: linkCoords.left + window.scrollX
       };

       highlight.style.width = `${coords.width}px`;
       highlight.style.height = `${coords.height}px`;
       highlight.style.transform = `translate(${coords.left}px, ${coords.top}px)`;

   }

   triggers.forEach(a => a.addEventListener('mouseenter', highlightLink));
</script>

Code interpretation

  • Through HTML source code, we can easily find that all anchors are composed of a tag, so in js code, we first get all a tag objects and store them in triggers variables.
const triggers = document.querySelectorAll('a');
  • The highlighted block in the rendering is actually a span tag, creating a span tag in the JS code and adding a class of highlight to it.
const highlight = document.createElement('span');
highlight.classList.add('highlight');
document.body.appendChild(highlight);
  • Event monitoring for all a tags will automatically trigger the highlightLink method when the mouse moves to the anchor.
triggers.forEach(a => a.addEventListener('mouseenter', highlightLink));
  • getBoundingClientRect()

getBoundingClientRect

The Element.getBoundingClientRect() method returns the size of the element and its position relative to the viewport.

Syntax:

rectObject = object.getBoundingClientRect();

Value:
The return value is one DOMRect Object, which is made of this element getClientRects() Method returns a set of rectangles, that is, a set of CSS borders associated with that element.

DOMRect Attribute Table:

attribute type describe
bottom float Y axis, relative to the bottom of the viewport origin rectangular box. Read-only.
height float The height of the rectangular box (equal to the height of the bottom minus the top). Read-only.
left float The X-axis, relative to the left side of the viewport origin rectangular box. Read-only.
right float The X-axis, relative to the right side of the viewport origin rectangular box. Read-only.
top float Y axis, relative to the top of the viewport origin rectangular box. Read-only.
width float The width of the rectangular box (equal to right minus left). Read-only.
x float X-axis abscissa, the distance to the left of the rectangular box relative to the viewport origin. Read-only.
y float Y axis ordinates, the distance between the top of the rectangular box and the viewport origin. Read-only.

DOMRect objects contain a set of read-only attributes for describing borders -- left, top, right, and bottom, in pixels. Attributes other than width and height are relative to the upper left corner of the viewport.

Empty border boxes are ignored. If all element boundaries are empty, then the rectangle returns a width, height value of 0 to the element, and left and top values of the top-left value of the first css box (in content order).

When calculating the boundary rectangle, the scrolling operation in the viewport area (or other scrollable elements) is considered. That is to say, when the scrolling position changes, the top and left attribute values change immediately (therefore, their values are relative to the viewport, not absolute). If you don't want the attribute value to change with the viewport, you can get the constant value independent of the current rolling position by adding the current rolling position (through window.scrollX and window.scrollY) to the top and left attribute values.

  • highlightLink method
function highlightLink() {
  const linkCoords = this.getBoundingClientRect();
  // console.log(linkCoords);
  <!--`coords`Calculate coordinates, width and height.-->
  const coords = {
      width: linkCoords.width,
      height: linkCoords.height,
      top: linkCoords.top + window.scrollY,
      left: linkCoords.left + window.scrollX
  };

<!--Highlighted span Style Settings of Labels-->
  highlight.style.width = `${coords.width}px`;
  highlight.style.height = `${coords.height}px`;
  highlight.style.transform = `translate(${coords.left}px, ${coords.top}px)`;

}

End!

Source download

Github Source Code

Topics: Javascript Attribute github