DEV Community

Cover image for How I did a mouse move shadow effect using JavaScript
Raquel Santos | RS-coding
Raquel Santos | RS-coding

Posted on

How I did a mouse move shadow effect using JavaScript

Hi everyone 👋!
How are you doing?

Today I will show you how I did a mouse move shadow effect based on what I have learned in an challenge of JavaScript30 of Wes Bos.
It is a good trick to enhance your portfolio or other websites you are doing.

Let's get started!

1.- I created the HTML structure for the challenge

<div class="hero">
   <div class="container">
      <h1 class="container__title">Hello,👋  I'm <span>Raquel Santos</span></h1>
      <p class="container__paragraph">A self-taught, commited and passionated Front-end developer</p>
      <button class="container__button">About me</button>
   </div>
</div>

Enter fullscreen mode Exit fullscreen mode

I have created a very simple structure that has a div called hero where the event mouseMove runs , a div called container just give some flexbox and align this container to the right. This container has h1, paragraph and a button. The h1 is the element that will be changed.

2.- Added general and specific CSS style in the elements


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

:root{

    --secondary-color: #f151bc;

    --shadow-color:#14011dbe;
    --text-color:#e7e7e7;
}

@import url('https://fonts.googleapis.com/css2?family=Georama:wght@300;400;500;600;700&display=swap');
@import url('https://fonts.googleapis.com/css2?family=PT+Sans&display=swap');

html{
    font-size:100%;
     min-height:100vh;
     width:100vw;
}

body{
    min-height:100vh;
    width:100vw;
    font-family: 'Georama',
    sans-serif;
    box-sizing:border-box;

   background: linear-gradient(90deg, #020024 0%, #06065e 35%, #0273a0 100%);

}

.hero{
    height:100vh;
    width:100vw;
    display:flex;
    align-items:center;
    justify-content:flex-end;
    font-family:'PT Sans',
    sans-serif;
    color:var(--text-color);
    letter-spacing: .1rem;
}

.container{
    margin-right:16rem;
    width:50rem;
    display:flex;
    flex-direction:column;
}

.container__title{
    font-size:7rem;
    font-weight:600;
    margin:4rem 0;
    text-shadow: 10px 10px 1px var(--shadow-color);
    line-height: 6.8rem;
}

.container__title span{
    color:var(--secondary-color);
}

.container__paragraph{
    font-size:3rem;
}

.container__button{
    align-self: flex-end;
    margin-top:4rem;
    border:none;
    padding:2rem 4rem;
    background-color:var(--secondary-color);
    color:white;
    border-radius:5px;
    box-shadow:5px 5px 5px var(--shadow-color);
    font-size:2rem;
    cursor:pointer;
}

Enter fullscreen mode Exit fullscreen mode

3.- Now its time for JavaScript

3.1- First I obtained the elements from DOM and created a variable called walk with 100 value, which means how much the shadow can move/walk.

const hero = document.querySelector('.hero')
const text = hero.querySelector('h1')

cont walk = 100;
Enter fullscreen mode Exit fullscreen mode

3.2- I create an event listener to the hero variable with an event mouvemove and a function called shadow.

hero.addEventListener('mousemove',shadow)

Enter fullscreen mode Exit fullscreen mode

3.3- In this function caleed shadow it where I did put all the functional code to get the result of a shadow moving while I move my mouse in the screen.


const shadow = function(e){
   const width = this.offsetWidth;
   const height = this.offsetHeight;

}

Enter fullscreen mode Exit fullscreen mode

First I created two variables width and height to get the measurements of the here.

Note: what is offsetWidth and offsetHeight?

offsetWidth gives the measurement in pixels of the element's CSS width
offsetHeight gives the measurement in pixels of the element's CSS height
the measure differs if we resize the window of the browser -responsiveness

3.4- I created other two variables x and y that takes as value the measuresments of exact pixel in the here where the event is. (mousemove).I use let instead of const in this variables because I have to update them next.

 let x = e.offsetX
 let y = e.offsetY
Enter fullscreen mode Exit fullscreen mode

Note: what is offsetX and offsetY?
It is property of the MouseEvent interface that provides the offset in the X or Y coordinate of the mouse pointer between that event and the padding edge of the target node.

3.5- After that I needed to change the x and y variables because they are set the value of 0 in the top left of the hero and we want to set the value in the top left of the text.
So I needed to verify if the this(hero) is different from the e.target, if that so I need to update those variables to set the value 0 in the correct place.


const shadow = function(e){
  ...
  if(this !== e.target){
      x = x + e.target.offsetLeft;
      y = y + e.target.offsetTop;
  }
}

Enter fullscreen mode Exit fullscreen mode

3.6- After that I added two new variables which will contain the math to make the shadow move in correct place.
If the shadow walks 100 we have to remember that walks 50 from the zero point to left top and 50 bottom right. so we need to devide the walk in two and subtract to the math made with the 0 point pixel where it begins divided by the height and width of the hero plus the walking .


const shadow = function(e){

    const xWalk = Math.round(( x / width * walk) - (walk / 2))
    const yWalk = Math.round(( y /height * walk) - (walk / 2))

}

Enter fullscreen mode Exit fullscreen mode

This will give the exact pixel moved of the shadow to every direction in the screen until 100/2 = 50.

3.7- After that all I needed to do was to style the text shadow of the variable text with the values from xWalk and yWalk


 const shadow = function(e){
   ...
   text.style.textShadow = `
    ${xWalk}px ${yWalk}px  var(--shadow-color)`;

}

Enter fullscreen mode Exit fullscreen mode

Don't forgetting to put px in the value.

And that is it 🎉 Enjoy it doing and have fun to explore.
If you want to share your examples and new things you tried related to this , comment bellow .

To check the full code click here

to see the demo click here

Discussion (0)