Interactive Cursor Effects In jQuery And GSAP
File Size: | 12.6 KB |
---|---|
Views Total: | 2411 |
Last Update: | |
Publish Date: | |
Official Website: | Go to website |
License: | MIT |
A set of pretty cool custom cursors and interactive cursor effects implemented in jQuery and GSAP.
See Also:
- Fancy Cursor Animations In jQuery & GSAP - Cursor & Magnetic
- Elastic Hover Effect With jQuery And GSAP
Table Of Contents:
How to use it:
1. These custom cursor effects requires the latest jQuery and GSAP libraries.
<script src="/path/to/cdn/gsap.min.js"></script> <script src="/path/to/cdn/jquery.min.js"></script>
2. Create a custom cursor that interacts with mouse movement. Live Demo.
/* Custom Cursor */ .custom-cursor, .custom-cursor-dot { position:fixed; z-index:999; top:0; left:0; transform:translate(-50%, -50%); pointer-events:none; opacity:0; } /* decorative */ .custom-cursor { width:62px; height:62px; border:1px solid #1c1c1c; border-radius:50%; } .custom-cursor-dot { width:7px; height:7px; border-radius:50%; background-color:#1c1c1c; }
function customCursor(options) { let settings = $.extend({ targetClass: 'custom-cursor', // create element with this class wrapper: $('body'), // jQuery speed: .1, movingDelay: 300, // fire event onStop after delay hasHover: false, // has hover events hoverTarget: $('a[href], button'), touchDevices: false, // show on touch devices onMove: function(data) {} }, options), data = {}, checkTouch = !settings.touchDevices && "undefined" !== typeof document.documentElement.ontouchstart, timer = null; // exit if (checkTouch || !settings.wrapper.length) return; // append the ball settings.wrapper.append(`<div class="${settings.targetClass}"></div>`); let $cursor = $('.' + settings.targetClass), position = { x: window.innerWidth / 2, y: window.innerHeight / 2 }, mouse = { x: position.x, y: position.y }, setX = gsap.quickSetter($cursor, "x", "px"), setY = gsap.quickSetter($cursor, "y", "px"); // update data data.cursor = $cursor; // on mouse move window.addEventListener("mousemove", init); function init() { // remove default mousemove event window.removeEventListener("mousemove", init); // add new custom event window.addEventListener("mousemove", e => { mouse.x = e.x; mouse.y = e.y; // update data and trigger event data.isMoving = true; settings.onMove(data); timer = setTimeout(function() { // update data and trigger event data.isMoving = false; settings.onMove(data); }, settings.movingDelay); }); // fade out cursor document.addEventListener("mouseleave", e => { // update data and trigger event data.isInViewport = false; settings.onMove(data); }); // update cursor's position document.addEventListener("mouseenter", e => { mouse.x = position.x = e.x; mouse.y = position.y = e.y; // update data and trigger event data.isInViewport = true; settings.onMove(data); }); gsap.ticker.add((time, deltaTime) => { let fpms = 60 / 1000, delta = deltaTime * fpms, dt = 1 - Math.pow(1 - settings.speed, delta); position.x += (mouse.x - position.x) * dt; position.y += (mouse.y - position.y) * dt; setX(position.x); setY(position.y); }); data.isInViewport = true; } // on hover if (settings.hasHover && settings.hoverTarget.length) { setTimeout(function() { settings.hoverTarget.hover(function() { data.hoverTarget = $(this); data.isHover = true; settings.onMove(data); }, function() { data.hoverTarget = $(this); data.isHover = false; settings.onMove(data); }); }, 100); } } // big ball customCursor({ hasHover: true, onMove: function(data) { if (data.isInViewport) { // in viewport if (data.isMoving) { if (data.isHover) { gsap.to(data.cursor, { opacity: 1, scale: 1.5 }); } else { gsap.to(data.cursor, { opacity: .5, scale: .8 }); } } else { if (data.isHover) { gsap.to(data.cursor, { opacity: 1, scale: 1.5 }); } else { gsap.to(data.cursor, { opacity: .5, scale: 1 }); } } } else { // out viewport gsap.to(data.cursor, { opacity: 0, scale: 0 }); } }, }); // dot inside customCursor({ targetClass: 'custom-cursor-dot', speed: .5, onMove: function(data) { if (data.isInViewport) { gsap.to(data.cursor, { opacity: 1 }); } else { gsap.to(data.cursor, { opacity: 0 }); } }, });
3. Create a magnetic button that interacts with mouse cursor. Live Demo.
.buttons { height:30vh; display:flex; flex-direction:column; justify-content:space-around; } .magnetic { padding:15px 30px; font-size:1.2em; border-radius:5px; background-color:#1c1c1c; color:#fff; }
function magneticButton(options) { let settings = $.extend({ target: $('[data-magnetic]'), // jQuery element class: 'magnetizing', attraction: 0.45, // 1 is weak, 0 is strong distance: 100, // magnetic area around element onEnter: function(data) {}, onExit: function(data) {}, onUpdate: function(data) {}, }, options), isEnter = false, // distance from mouse to center of target distanceFromMouse = function($target, mouseX, mouseY) { let centerX = $target.offset().left + $target.outerWidth() / 2, centerY = $target.offset().top + $target.outerHeight() / 2, pointX = mouseX - centerX, pointY = mouseY - centerY, distance = Math.sqrt(Math.pow(pointX, 2) + Math.pow(pointY, 2)); return Math.floor(distance); }, // processing magnetize = function($this, e) { let mouseX = e.pageX, mouseY = e.pageY; $this.each(function() { let $this = $(this), centerX = $this.offset().left + $this.outerWidth() / 2, centerY = $this.offset().top + $this.outerHeight() / 2, deltaX = Math.floor(centerX - mouseX) * -1 * settings.attraction, deltaY = Math.floor(centerY - mouseY) * -1 * settings.attraction, mouseDistance = distanceFromMouse($this, mouseX, mouseY), data = { target: $this, y: deltaY, x: deltaX, distance: mouseDistance }; if (mouseDistance < settings.distance) { gsap.to($this, { y: deltaY, x: deltaX }); // enter if (!isEnter) { isEnter = true; $this.addClass(settings.class); settings.onEnter(data); } // update settings.onUpdate(data); } else { gsap.to($this, { y: 0, x: 0 }); // exit if (isEnter) { isEnter = false; $this.removeClass(settings.class); settings.onExit(data); } } }); }; // exit if (!settings.target.length) return; // on mouse move $(window).on('mousemove', function(e) { magnetize(settings.target, e); }); } // init magneticButton({ distance: 120, onEnter: function(data) { //gsap.to(data.target, {scale: 1.2}); console.log(data); }, onExit: function(data) { //gsap.to(data.target, {scale: 1}); console.log(data); }, onUpdate: function(data) { console.log(data); } });
4. Enable an element to always follow your mouse cursor. Live Demo.
.follower { /* positioning */ position:absolute; top:50%; left:50%; transform:translate(-50%, -50%); /* decorative */ width:100px; height:100px; border-radius:50%; background-color:#1c1c1c; color:#fff; /* avoid transition conflict with GSAP */ transition:none; /* sometimes you need this to avoid hovering flicker */ pointer-events:none; }
function cursorFollowAndReturn(options) { let settings = $.extend({ follower: '', // jQuery element container: '', // jQuery element }, options); // exit if elements are not found if (!settings.follower.length && !settings.container.length) return; // set button position when mouse move inside wrapper settings.container.on("mousemove", function(e) { let x = e.pageX, y = e.pageY, // mouse offset offsetX = settings.container.offset().left, // container offset offsetY = settings.container.offset().top, valX = x - offsetX - (settings.container.outerWidth() / 2), valY = y - offsetY - (settings.container.outerHeight() / 2); gsap.to(settings.follower, .5, { x: valX, y: valY }); }); // set button to center of wrapper when mouse out settings.container.on("mouseout", function(e) { gsap.to(settings.follower, .5, { x: 0, y: 0 }); }); } // init cursorFollowAndReturn({ follower: $('.follower'), container: $('.box'), });
This awesome jQuery plugin is developed by phucbm. For more Advanced Usages, please check the demo page or visit the official website.