Transitioning smoothly between different backgrounds will be like changing the cursor color

As I work on my website, I encounter the need for a cursor that smoothly changes its color. Specifically, I want the cursor to appear blue (#0059ff) when hovering over a white background and white when over a blue background, with a seamless transition like this: https://i.stack.imgur.com/szS27.png

To achieve the white color using mix-blend-mode, I calculate the inverted color by applying `adjust-hue($color, 180)` in SCSS, which gives me the desired shade for the cursor when on a white background. However, things get tricky when I try to make the cursor change to white when it is not over the white background.

Initially, I tried using `mix-blend-mode: difference` for "primary colors," such as #ff0000 and #ff00ff, which worked fine. But when dealing with #0000ff transitioning to #0059ff, the results were not satisfactory. The calculated inverted color of #ffa600 did not give the desired effect of white-on-blue and blue-on-white backgrounds.

I'm stuck at this point and unsure how to proceed to ensure the cursor displays correctly based on the background color. If you have any insights or suggestions, please share them with me!

Below is the current code snippet I've been working on:

const bigBall = document.querySelector('.cursor-ball-big');
const smallBall = document.querySelector('.cursor-ball-small');
const allHoverable = document.querySelectorAll('a, .hoverable');

TweenMax.to(bigBall, .3, {fill: 'none'});

allHoverable.forEach(hoverable => {
    hoverable.addEventListener('mouseenter', () => {
        TweenMax.to(bigBall, .3, {scale: 4});
        TweenMax.to(bigBall.querySelector('circle'), .3, {strokeWidth: 1});
    });
    hoverable.addEventListener('mouseleave', () => {
        TweenMax.to(bigBall, .3, {scale: 1});
        TweenMax.to(bigBall.querySelector('circle'), .3, {strokeWidth: 2});
    });
});

document.body.addEventListener('mousemove', e => {
    const {clientX, clientY} = e;

    TweenMax.to(smallBall, .1, {x: clientX - 5, y: clientY - 7});
    TweenMax.to(bigBall, .4, {x: clientX - 15, y: clientY - 17});
});
:root {
  --color1: #0059FF;
  --color2: #FFFFFF;
  --cursor: #ffa600;
}

body {
  height: 100vh;
  cursor: none;
  margin: 0;
  display: flex;
  font-family: monospace;
}

.cursor {
  pointer-events: none;
  mix-blend-mode: difference;
}
.cursor .cursor-ball {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 1000;
}
.cursor .cursor-ball.cursor-ball-small circle {
  fill: var(--cursor);
}
.cursor .cursor-ball.cursor-ball-big circle {
  stroke: var(--cursor);
}

a {
  border-bottom: 2px solid transparent;
  padding: 10px 0;
  margin-top: 25px;
  text-decoration: none;
  display: inline-block;
  cursor: none;
}

.left,
.right {
  height: 100%;
  width: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

.left {
  background-color: var(--color1);
}
.left a {
  border-color: var(--color2);
}
.left h1,
.left p,
.left a {
  color: var(--color2);
}

.right {
  background-color: var(--color2);
}
.right a {
  border-color: var(--color1);
}
[right h1,
.right p,
.right a {
  color: var(--color1);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.3/TweenMax.min.js"></script>
<div class="cursor">
    <div class="cursor-ball cursor-ball-big">
        <svg xmlns="http://www.w3.org/2000/svg" height="30" width="30">
            <circle cx="15" cy="15" r="12" stroke-width="2"/>
        </svg>
    </div>
    <div class="cursor-ball cursor-ball-small">
        <svg height="10" width="10">
            <circle cx="5" cy="5" r="4" stroke-width="0"/>
        </svg>
    </div>
</div>

<div class="left">
    <a href="#" title="Hover me">Hover me</a>
</div>

<div class="right">
    <a href="#" title="Hover me">Hover me</a>
</div>

Answer №1

I'm trying to figure out how to change the cursor color depending on whether it's over a white background or a blue background.

Unfortunately, using mix-blend mode for this purpose is too limiting when you want completely different colors.

However, I found a workaround using clip-path:

// JavaScript code here
// CSS code here
// HTML code here

I've tested this solution on Chrome 97 on Windows 10.
If the required font is not available, you can check out how it looks https://i.stack.imgur.com/zVEHP.png


Explanation

  • I created an element called left2 with inverted colors compared to left.
  • left2 overlaps exactly with left.
  • I applied a clip-path #ball1 to left2.
  • The #ball1 clips left2, revealing part of left underneath.
  • To create the outer ring, I used a circular font character 'O' in an SVG and increased its size on hover.
  • These steps were repeated for the right side with elements like right2.
  • To ensure only one cursor shows at a time, I had to create a duplicate clipPath ball2 for the right side and position it accordingly.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to align text in the center of a div?

I just created this dropdown menu, but I am encountering an issue. Whenever I resize the div or h4 element, the text ends up at the top. Even after trying to solve it with text-align: center;, the problem persists. Here is a visual representation of what ...

Is there a way to use CSS to swap out the content of one HTML element with another HTML element's content?

Having an issue with editing or locating a plugin's HTML template on WordPress. Wondering if it is possible to replace the content of one HTML element with another using just CSS? Appreciate any help! ...

Tips for alternating the color of <li> or <tr> elements consecutively

Looking to alternate the background color of li or tr elements consecutively. Please note: A static class will not work as I need to call this in a while loop. The desired output should look like: <li>line1</li> //white background <li> ...

Adaptive component transformation

Hey there, I'm having some trouble figuring this out... I need help with making sure that the element identified by the red rectangle in the images moves in alignment with the containers below, regardless of the screen size. I want to create a respon ...

- shorthand CSS properties roster- index of abbreviated CSS attributes

I have created a JavaScript function that needs to extract CSS values, even those that may contain multiple values. For instance, margin:0 0 4px 12px; consists of four separate values (margin-top, margin-right, etc). Specifically, I am looking for a list ...

What is the best way to eliminate HTML <li> bullets using codebehind?

When working in codebehind, I often create an HTML list using the following method: HtmlGenericControl list = new HtmlGenericControl("ul"); for (int i = 0; i < 10; i++) { HtmlGenericControl listItem = new HtmlGenericControl("li"); Label textLabel ...

include a button next to the input field

As you reduce the browser window size, you may notice a different layout designed specifically for iPhone. One question that arises is how to add a button next to the search text box dynamically using JavaScript. The issue at hand is that the text box is b ...

In IE9/10, the absolutely positioned pseudo element within a table cell does not fully overlay its parent

My layout includes nested div elements displayed as a table and table-cell, with each cell containing an absolutely positioned :before element that covers the entire cell. While this setup works perfectly in most browsers, I am facing an issue in IE9, 10, ...

Creating a Burger Navigation Menu with CSS and HTML using Image Overlapping

I'm encountering an issue with the new website I created for my local Church. I followed a tutorial on building a burger menu using just HTML and CSS, which you can view here. The problem arises when I attempt to place an image below the navigation m ...

Adjusting the text color for select values within a <td> element

I have a table that is populated with data retrieved from an API. Each cell in the table contains multiple pieces of data. Below is the code used to create the table: <td class="myclass"> <?php $myvar = explode(" ", $json["data"]); ...

CSS animation for input range slider

Is there a way to create smoother animations for the input[type="range"] element, especially when dealing with short audio files? You can check out my Codepen where I've been experimenting with solutions using a short audio file: Codepen Link I am s ...

What is the best way to show information entered into a textbox on a different webpage?

Looking for advice on how to collect data in a text box and display it on another page? I have included HTML code for both the announcement page (where the data is entered) and the archive page (where the data should be shown). Could someone guide me on ...

The navigation dropdown menu in Bootstrap 4 spills over the edges of the window

In the code snippet provided above, an example of a navbar with a dropdown menu is given. One issue that arises is when the dropdown menu is clicked and it overflows to the right, causing a horizontal scroll bar to appear on the window. The question at ha ...

Always keep your phone in landscape orientation for optimal website viewing

Currently, I am facing an issue with my website where it functions perfectly on mobile devices in landscape orientation but elements get distorted when viewed in portrait mode. Is there a method to ensure that the website is always displayed in landscape ...

The integration of PHP code with an HTML form is causing issues

When I use the insert_teacher('bla bla','bla bla','dqsd') function in a PHP file, everything works fine. However, when I try to implement it with an HTML form, nothing is displayed and no data is inserted into my database. &l ...

The effectiveness of the javascript widget is hindered by the absence of the meta viewport tag,

As I work on creating a widget to appear at the bottom of webpages, I've encountered a styling issue. The widget's display varies based on whether the webpage includes a specified meta viewport tag or not. <meta name="viewport" content="width ...

Space between flex content and border increases on hover and focus effects

My code can be found at this link: https://jsfiddle.net/walshgiarrusso/dmp4c5f3/5/ Code Snippet in HTML <body onload="resize(); resizeEnd();"> <div style="margin: 0% 13.85%; width 72.3%; border-bottom:1px solid gray;"><spanstyle="visibilit ...

Adjust the number of images in each row based on the width of the screen

I have experimented with various methods, but none seem to work flawlessly. My goal is to neatly display around 50 images in rows and columns, adjusting the length of each row based on the screen width. Here are the approaches I've tried: Placing ...

Steps for accessing CSS variables within a scoped style block in Vue with Buefy_integration

After diving into the Buefy documentation, I successfully personalized my color scheme and even crafted unique hues by applying the is-[colorName] as a class to HTML elements. <style lang="scss"> // Importing Bulma's core @import "~bulm ...

Aligning Checkbox Labels for Web Forms

Can an image convey more than a thousand words? I'm looking to align the second (and following) lines with the first one. Any suggestions? Html stands for <input><span>text</span> ...