Jump to content
Search Community

Change hover cursor to image on each gallery item

Louienator test
Moderator Tag

Recommended Posts

I assume you were looking to do something like this?: 

See the Pen dyjywaZ?editors=0110 by GreenSock (@GreenSock) on CodePen

 

Your version had quite a few issues, like:

  1. Variables were referenced out of scope, throwing errors
  2. A new callback was being added to the gsap.ticker on every single mousemove which is extremely inefficient
  3. A new gsap.set() was created on every tick too (inefficient)
  4. There's really no need for jQuery

Much of this code was borrowed from the mouse follower example in the gsap.quickTo() docs: 

https://greensock.com/docs/v3/GSAP/gsap.quickTo()

 

I hope that helps!

Link to comment
Share on other sites

Hi,

 

You have a syntax error:

var tl = gsap.timeline();

var items = tl.utils.toArray(".gallery-item__inner"), // Here
    cursor = document.querySelector(".me"),
    xTo = tl.quickTo(cursor, "x", {duration: 0.3, ease: "power3"}), // Here
    yTo = tl.quickTo(cursor, "y", {duration: 0.3, ease: "power3"}); // Here

The issue is that you're referencing the timeline instance. There is a difference between an instance and GSAP core constructor. The utils object and the quickTo method is part of the core constructor, not a timeline instance.

https://greensock.com/docs/v3/GSAP

https://greensock.com/docs/v3/GSAP/Timeline

 

This seems to work the way you expect:

var tl = gsap.timeline();

var items = gsap.utils.toArray(".gallery-item__inner"),
    cursor = document.querySelector(".me"),
    xTo = gsap.quickTo(cursor, "x", {duration: 0.3, ease: "power3"}),
    yTo = gsap.quickTo(cursor, "y", {duration: 0.3, ease: "power3"});

Hopefully this clear things up. Let us know if you have more questions.

 

Happy Tweening!

  • Like 1
Link to comment
Share on other sites

  • 5 months later...

I assume you meant to do something like this?: 

var items = gsap.utils.toArray(".gallery-item__inner"),
    cursor = document.querySelector(".me"),
    xTo = gsap.quickTo(cursor, "x", {duration: 0.3, ease: "power3"}),
    yTo = gsap.quickTo(cursor, "y", {duration: 0.3, ease: "power3"});
    
gsap.set(cursor, {xPercent: -50, yPercent: -50, autoAlpha: 1, scale: 0, pointerEvents: "none"});

window.addEventListener("mousemove", (e) => {
  xTo(e.pageX);
  yTo(e.pageY);
});

items.forEach((item) => {
  item.addEventListener("mouseenter", () => {
    gsap.to(cursor, {scale: 1, duration: 0.2, overwrite: "auto"});
  });
  item.addEventListener("mouseleave", () => {
    gsap.to(cursor, {scale: 0, duration: 0.01, overwrite: "auto"});
  });
});

https://jsfiddle.net/t6byepfa/

  • Like 3
Link to comment
Share on other sites

Heya, no this is definitely 100% not valid at all.
 

var bannerHover = gsap.timeline();

bannerHover.utils.toArray(".box-inner a")
bannerHover.quickTo(cursor, "x", {duration: 0.3, ease: "power3"})


quickTo and utils are a method belonging to GSAP itself, they aren't timeline methods. There's no need to reassign GSAP itself to a different variable name. What's your thinking here? Is there something you're trying to avoid or guard against?

  • Like 1
Link to comment
Share on other sites

I don't understand what you mean by that, sorry. What exactly didn't work? Where's the minimal demo that's broken? When I put the code into your demo that I provided, it seems to work great. What am I missing? 

 

Here are some tips that will increase your chance of getting a solid answer:

 

  • A clear description of the expected result - "I am expecting the purple div to spin 360degrees"
  • A clear description of the issue - "the purple div only spins 90deg"
  • A list of steps for someone else to recreate the issue - "Open the demo on mobile in IOS safari and scroll down to the grey container" 
  • A minimal demo - if possible, using no frameworks, with minimal styling, only include the code that's absolutely necessary to show the issue. Please don't include your whole project. Just some colored <div> elements is great.

 

Link to comment
Share on other sites

  • 7 months later...

Hey there,

 

Thanks for the help that has already been provided here. Everything works for me. But now I have encountered a problem. If I place a container with 90% width, position relative and margin-auto (all 3 must haves) around your demo, the cursor has an offset to the actual mouse position. Seen here. I'm currently in the process of researching what it is. Maybe it's easy for pros? I'm still a beginner learning GSAP here.:-) 

 

https://jsfiddle.net/epLra8bj/

 

Thank you for your time.
Greetings Robin

Link to comment
Share on other sites

Hi @Robbor,

 

Since you have a known width for your main container (90%) you know that the margin on each side (the left side is the one we care about actually) is 5% of the window object's width, so just offset your calculations with that and the dimensions of the mouse follower:

let _width = window.innerWidth;

window.addEventListener("mousemove", (e) => {
  xTo(e.pageX - 30 - _width * 0.05);
  yTo(e.pageY - 30);
});

window.addEventListener("resize", () => _width = window.innerWidth);

Here is a fork of your fiddle:

https://jsfiddle.net/f26qnvp0/2/

 

Hopefully this helps.

Happy Tweening!

  • Like 1
Link to comment
Share on other sites

Hi Rodrigo,

thank you for your quick response. I'm researching again because I think we're addressing a symptom here, but not the cause. Maybe I haven't fully understood it yet :-P
What I mean is: why does everything work perfectly with position: static, but no longer with position:relative. As soon as I switch to relative, the mouse coordinates are no longer correct and the cursor is offset.
I don't always know the offset, so your solution doesn't work 100% for me.


Example: container has max-width:1000px, margin:auto.
Or content with variable height on top ( same problem with the Y coordinate offset).

 

 

https://jsfiddle.net/rsk257bd/1/

 

Link to comment
Share on other sites

You're fighting a CSS spec here. You've created an element that tis relative to the container it is in and it can not be out of the element. You can do a few things in this instance. 

 

  • Move the element out of the container so that it is not relative to anything 
  • Make the element position: fixed;
  • Calculate where the mouse is relative to the box it is in.

The easiest is just to move the cursor element outside everything and make sure it doesn't have a parent element. Also I've removed your timeline, because each mouse enter and leave you were creating new tweens to that timeline and I've also set xPercent: -50, yPercent: -50 to the initial .set() so that the element is in the middle of the cursor.

 

I'd looked at your question yesterday and was almost done debugging it, but then jsfiddle just froze on me and I couldn't do anything on the page anymore, that is why I've moved to codepen here. 

 

Hope it helps and happy tweening! 

 

See the Pen qBvLLVQ?editors=0010 by mvaneijgen (@mvaneijgen) on CodePen

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...