Dynamic and Rotating Hexagonal Cursor

Written by @kerixa 10 April 2021

Reading the content of websites without using special and attractive styles for them not only is not attractive, but also makes the visitor leave the websites sooner. Giving the style to the cursor is one of the ways that increases the attractiveness of your website. In the following code, there is a hexagonal cursor that rotates, and when hovering a text, the rotating cursor becomes slightly larger around that text.

Code Snippet:

                                                
                                                <!-- this script is provided by https://www.javascriptfreecode.com coded by: Kerixa Inc. -->
<style>
*,
*::after,
*::before {
    box-sizing: border-box;
}

* {
    cursor: none !important;
}

:root {
    --color-text: #f6f1f1;
    --color-bg: #0f0e0e;
    --cursor-sphere-fill: transparent;
    --cursor-sphere-stroke: #ea2e6e;
    --cursor-sphere-stroke-width: 1.5px;
    --cursor-fill: yellow;
}

body {
    color: var(--color-text);
    background-color: var(--color-bg);
    width: 100%;
    height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
}

/* Cursor CSS Start */
.cursor {
    display: none;
}

@media (any-pointer: fine) {
    .cursor,
    .cursor-sphere {
        display: block;
        position: fixed;
        top: 0;
        left: 0;
        pointer-events: none;
    }

    .cursor-sphere__inner {
        fill: var(--cursor-sphere-fill);
        stroke: var(--cursor-sphere-stroke);
        stroke-width: var(--cursor-sphere-stroke-width);
        opacity: 0.7;
        animation: rotationAnim 3s linear infinite;
        transform-origin: center;
    }

    .cursor__path {
        fill: var(--cursor-fill);
    }

    @keyframes rotationAnim {
        to {
            transform: rotate(360deg);
        }
    }
}
/* Cursor CSS End */

</style>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">
<script src='https://cdnjs.cloudflare.com/ajax/libs/gsap/3.5.1/gsap.min.js'>
<script>document.documentElement.className = "js";</script>
<noscript>
  <h1>Enable Javascript to view the app</h1>
</noscript>

<h1>Custom Cursor</h1>

<!-- Cursors -->
<svg class="cursor-sphere" width="37" height="36" viewBox="0 0 37 36" xmlns="#">
  <path class="cursor-sphere__inner" d="M18.5 32.093l-7.593 2.174-3.034-7.292-6.434-4.58 3.809-6.92-.43-7.886 7.784-1.336L18.5 1l5.898 5.253 7.784 1.336-.43 7.886 3.81 6.92-6.435 4.58-3.034 7.292z" fill-rule="evenodd"></path>
</svg>
<svg class="cursor" width="10" height="10" viewBox="0 0 10 10" xmlns="#">
  <g class="cursor__path" fill="none" fill-rule="evenodd">
    <path d="M5 8.884l-2.17.62-.866-2.083L.125 6.113l1.089-1.977-.123-2.253L3.315 1.5 5 0l1.685 1.5 2.224.383-.123 2.253 1.089 1.977L8.036 7.42 7.17 9.505z"></path>
    <circle fill="#060606" cx="5" cy="5" r="1"></circle>
  </g>
</svg>
<script>
// Track the mouse position
let mouse = { x: 0, y: 0 };

window.addEventListener("mousemove", (event) => {
    mouse = getMousePosition(event);
});

// Cursor Implementation
class Cursor {
    constructor(element, doLerp = false) {
        this.DOM = { element, doLerp };
        this.DOM.element.style.opacity = 0;

        this.bounds = this.DOM.element.getBoundingClientRect();

        this.renderedStyles = {
            tx: { previous: 0, current: 0, amt: doLerp ? 0.2 : 1 },
            ty: { previous: 0, current: 0, amt: doLerp ? 0.2 : 1 },
            scale: { previous: 1, current: 1, amt: doLerp ? 0.17 : 1 },
            opacity: { previous: 1, current: 1, amt: doLerp ? 0.17 : 1 }
        };

        this.onMouseMoveEvent = () => {
            this.renderedStyles.tx.previous = this.renderedStyles.tx.current =
                mouse.x - this.bounds.width / 2;
            this.renderedStyles.ty.previous = this.renderedStyles.ty.current =
                mouse.y - this.bounds.height / 2;

            gsap.to(this.DOM.element, {
                duration: 0.9,
                ease: "Power3.easeOut",
                opacity: 1
            });

            requestAnimationFrame(() => this.render());

            window.removeEventListener("mousemove", this.onMouseMoveEvent);
        };

        window.addEventListener("mousemove", this.onMouseMoveEvent);
    }

    enter() {
        this.renderedStyles.scale.current = 1.8;
    }

    leave() {
        this.renderedStyles.scale.current = 1;
    }

    render() {
        this.renderedStyles.tx.current = mouse.x - this.bounds.width / 2;
        this.renderedStyles.ty.current = mouse.y - this.bounds.height / 2;

        for (const key in this.renderedStyles) {
            this.renderedStyles[key].previous = lerp(
                this.renderedStyles[key].previous,
                this.renderedStyles[key].current,
                this.renderedStyles[key].amt
            );
        }

        this.DOM.element.style.transform = `translateX(${this.renderedStyles.tx.previous}px) translateY(${this.renderedStyles.ty.previous}px) scale(${this.renderedStyles.scale.previous})`;
        this.DOM.element.style.opacity = this.renderedStyles.opacity.previous;

        requestAnimationFrame(() => this.render());
    }
}

// Initialize cursor
const cursorSphere = new Cursor(document.querySelector(".cursor-sphere"), true);
new Cursor(document.querySelector(".cursor"));

// Mouse cursor hovers
const hoverText = document.querySelector("h1");
hoverText.addEventListener("mouseenter", () => cursorSphere.enter());
hoverText.addEventListener("mouseleave", () => cursorSphere.leave());

// Linear interpolation
function lerp(a, b, n) {
    return (1 - n) * a + n * b;
}

// Gets the mouse position
function getMousePosition(event) {
    let positionX = 0;
    let positionY = 0;

    if (!event) event = window.event;

    if (event.pageX && event.pageY) {
        positionX = event.pageX;
        positionY = event.pageY;
    } else if (event.clientX && event.clientY) {
        positionX =
            event.clientX +
            document.body.scrollLeft +
            document.documentElement.scrollLeft;
        positionY =
            event.clientY +
            document.body.scrollTop +
            document.documentElement.scrollTop;
    }

    return { x: positionX, y: positionY };
}
</script>
<a target='_blank' href='https://www.javascriptfreecode.com' style='font-size: 8pt; text-decoration: none'>JavaScript Best Codes</a>                                                
                                            

Example:


About @kerixa

I am Krishna Eydat. I studied Software Engineering at University of Waterloo in Canada. I lead a few tech companies. I am passionate about the way we are connected. I would like to be part of something big or be the big deal!

K

Comments


Here you can leave us commments. Let us know what you think about this code tutorial!

0 / 300

TRENDING POST
1
2
3
4
5
VISITORS
Online Users: 12
Recent Members: admin_js, bloxio, yqaice, flooketsu, phuang_test
advertisement 2