Sarah
Sarah

Reputation: 33

Problem with mouseenter for a clip-path animation (CSS/JS)

I have updated my post because I've come up with some solutions since last week.


I'm having a problem with a clip-path section.

I would like my clip-path (circle) to shrink and then disappear when the mouse is leaving the clip section, and to expand again when it's entering the clip section.

The shrinking is working but not the expanding (see code below).

All help is very welcome!

Thank you in advance and have a nice day!

const circleClip = document.querySelector('#hidden');
let divSize = document.querySelector('#top').offsetHeight;

function removeIntro() {
  circleClip.classList.remove('intro');
}

function circleMove(e) {
  removeIntro();
  circleClip.style.setProperty('--x', e.clientX + 'px');
  circleClip.style.setProperty('--y', e.clientY - divSize + 'px');
}

circleClip.addEventListener('mouseleave', function(){
  circleClip.classList.toggle('shrink');
});

/*This one doesn't work on desktop*/
circleClip.addEventListener('mouseenter', function(){
  circleClip.classList.toggle('appear');
});

circleClip.addEventListener('mousemove', circleMove);
circleClip.addEventListener('touchmove', (e) => {
  removeIntro();
  
  let touch = e.touches[0];
  e.preventDefault();
  
  circleClip.style.setProperty('--x', touch.clientX + 'px');
  circleClip.style.setProperty('--y', touch.clientY - divSize + 'px');
});

/*This one doesn't work on mobile*/
  circleClip.addEventListener('touchstart', function(){
  circleClip.classList.toggle('appear');
});

  circleClip.addEventListener('touchend', function(){
  circleClip.classList.toggle('shrink');
});
body {
     position: relative;
     margin: 0;
     overflow: hidden;
}

h1,
h2,
p {
  margin: 0;
  padding: 0;
}

#top {
  color: white;
  background: blue;
  font-size: 30px;
  text-align: center;
}

#hidden p {
  padding: 10%;
  font-family: sans-serif;
}

#hidden {
  font-size: 7vh !important;
  line-height: 1em;
  background: red;
    min-height: 100vh;
    clip-path: circle(10% at var(--x) var(--y));
  cursor: none;
}
 #hidden.intro {
     clip-path: circle(0% at 50% 50%);
     animation: circleIntro 1800ms cubic-bezier(0.645, 0.045, 0.355, 1) both;
}

@keyframes circleIntro {
     100% {
         clip-path: circle(10% at 50% 50%);
    }
}

.shrink {
  clip-path: circle(10% at 50% 50%);
  animation: shrink 800ms cubic-bezier(0.645, 0.045, 0.355, 1) both;
}

@keyframes shrink {
  100% {
    clip-path: circle(0% at 50% 50%);
  }
}

.appear {
  clip-path: circle(0% at 50% 50%);
  animation: appear 800ms cubic-bezier(0645, 0.045, 0.355, 1) both;
}

@keyframes appear {
  100% {
    clip-path: circle(10% at 50% 50%);
  }
}
<div id="top"><h1>This is another div</h1></div>
<div id="hidden" class="intro">
  <p>Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo</p>
</div>

Upvotes: 0

Views: 156

Answers (1)

rmccreary
rmccreary

Reputation: 76

Seems you're looking for something like this?

You can separate the event handlers into their own functions:

function showCircle(e) {
    $(".clip").css({
        "-webkit-clip-path": "circle(0px at var(--x, 0) var(--y, 0))"
    });
}

function hideCircle(e) {
    $(".clip").css({
        "-webkit-clip-path": "circle(0px at var(--x, 0) var(--y, 0))"
    });
}

function moveCircle(e) {
    $(".clip").css ({
        '--x': e.pageX,
        '--y': e.pageY - $("#previoussection").height() - $("#clip_section").height()
    });
}

Then register the handlers for mouse interaction,

$(document).mousemove(moveCircle);
$(".clip_container").mouseleave(hideCircle);
$(".clip_container").mouseenter(showCircle);

and for touch interaction.

$(document).touchmove(moveCircle);
$(".clip_container").touchstart(hideCircle);
$(".clip_container").touchend(showCircle);

The circle isn't shrinking away because its CSS is never changed back to the 0 radius circle.

I think the key here is making sure you change the "clip-path" CSS property to the full value representing the circle you want to see whenever a relevant event fires.

It's also worth noting that your mouseStopped function never gets called in your code.

Upvotes: 1

Related Questions