Blur effect in CSS and JavaScript applied around the cursor

I am embarking on the journey of creating a website completely from scratch using html, css, and js with jQuery and other necessary libraries. My goal is to have all the code easily transferable and executable without the need for additional plugins or scripts. To achieve this, I have all required libraries (bootstrap, jQuery, and Vague.js) downloaded in a single folder for plug-and-play convenience.

On one of my pages, I have multiple images moving in a carousel-like fashion. These images dominate the page, with only the logo and menu buttons appearing alongside them. I am trying to implement a special effect where the screen/images are blurred out, leaving only a small circle around the cursor visible. While I have succeeded in blurring all the images and focusing them when the mouse hovers over them, I am struggling to isolate a specific portion of the image for focus.

Admittedly, my current method may not be the most efficient way to approach this issue. In order to smoothly operate the carousel across multiple pages, I had to duplicate all images and apply a CSS transform operation with keyframes to move them by -50%. This aspect could certainly be improved upon and can be disregarded for now. The snippet of code I currently have is as follows:

<div class="scrollWrapper">
        <div id="scroll" class="imgScroll" onclick="toggleAnimation();">
            <img class="scrollingImage" src="image1.jpg" alt="Window showcase image">
          <!-- Additional image tags here -->
        </div>
    </div>

My latest idea involves blurring the div element with the class "scrollWrapper" and figuring out a way to highlight the area around the cursor. However, I am at a loss as to how to proceed with this approach.

I have explored various resources, including this post, but most solutions seem tailored for static images rather than the dynamic ones in my carousel setup. I am currently experimenting with Vague.js but have yet to find a solution that addresses my specific needs.

As someone who is relatively new to web development and has limited experience with JavaScript/jQuery, I must admit that I am feeling frustrated by my inability to solve this challenge. Before considering a complete overhaul of my approach, any assistance or guidance would be greatly appreciated.

Answer №1

Applying the latest CSS backdrop-filter feature can be easily achieved, with the main challenge being creating a cutout in the filter.

Thankfully, there's always Stack Overflow for guidance.

For a circular shape, using a radial-gradient as a mask-image is likely the simplest method, demonstrated in this solution.

const blur_elem = document.getElementById( "blur-around" );
document.onmousemove = (evt) => {
  blur_elem.style.transform = `translate(${evt.clientX}px, ${evt.clientY}px)`;
};
#blur-around {
  position: fixed;
  z-index: 999;
  pointer-events: none;
  /* covering the viewport fully */
  width: 200vw;
  height: 200vh;
  /* offset to cover full viewport */
  left: -100vw;
  top: -100vh;
  /* using transform translate to move it */
  transform-origin: center;  
  -webkit-backdrop-filter: blur(15px);
  backdrop-filter: blur(15px);
  -webkit-mask-image: radial-gradient(50px at 50% 50%, transparent 100%, black 100%);
  mask-image: radial-gradient(50px at 50% 50% , transparent 100%, black 100%)
}

/* fallback for browsers without backdrop-filter support */
@supports not ((backdrop-filter: blur(0px)) or (-webkit-backdrop-filter: blur(0px))) {
  #blur-around {
    background-color: rgba(255,255,255,.8);
  }
}
<div id="blur-around"></div>
<p>Works over any content</p>
<img src="https://picsum.photos/250/250">
<img src="https://picsum.photos/360/200">

Unfortunately, Safari doesn't fully support the mask-image property, requiring an alternative approach.

CSS clip-path with an evenodd path can also be used, demonstrated in this particular answer.

Chrome still lacks support for the path() function in clip-path, necessitating utilization of the polygon() function and defining each vertex point when creating shapes like rectangles, making sure to close both outer and inner shapes properly.

const blur_elem = document.getElementById( "blur-around" );
document.onmousemove = (evt) => {
  blur_elem.style.transform = `translate(${evt.clientX}px, ${evt.clientY}px)`;
};
#blur-around {
  position: fixed;
  z-index: 999;
  pointer-events: none;
  /* covering the viewport fully */
  width: 200vw;
  height: 200vh;
  /* offset to cover full viewport */
  left: -100vw;
  top: -100vh;
  /* using transform translate to move it */
  transform-origin: center; 
  -webkit-backdrop-filter: blur(15px);
  backdrop-filter: blur(15px);

  --rect-size: 100px;
  clip-path: polygon( evenodd,
    /* outer rect */
    0 0,
    100% 0,
    100% 100%,
    0% 100%,
    0 0,
    /* inner rect */
    calc(50% - var(--rect-size) / 2) calc(50% - var(--rect-size) / 2),
    calc(50% + var(--rect-size) / 2) calc(50% - var(--rect-size) / 2),
    calc(50% + var(--rect-size) / 2) calc(50% + var(--rect-size) / 2),
    calc(50% - var(--rect-size) / 2) calc(50% + var(--rect-size) / 2),
    calc(50% - var(--rect-size) / 2) calc(50% - var(--rect-size) / 2)
   );
}

/* fallback for browsers without backdrop-filter support */
@supports not ((backdrop-filter: blur(0px)) or (-webkit-backdrop-filter: blur(0px))) {
  #blur-around {
    background-color: rgba(255,255,255,.8);
  }
}
<div id="blur-around"></div>
<p>Works over any content</p>
<img src="https://picsum.photos/250/250">
<img src="https://picsum.photos/360/200">

Creating a circle (as mentioned in comments) can become less straightforward, but a JavaScript generator can help facilitate this process:

function makeCircleHoleClipPathRule( radius ) {

  const inner_path = [];
  const circumference = Math.PI * radius;
  const step = Math.PI * 2 / circumference;
  const start_step = circumference * (5 / 8);
  for( let i = start_step; i < circumference + start_step; i++ ) {
    const angle = step * i;
    const x = radius * Math.cos( angle );
    const y = radius * Math.sin( angle );
    const str = `calc( 50% + ${ x }px ) calc( 50% + ${ y }px )`;
    inner_path.push( str );
  }
  inner_path.push( inner_path[ 0 ] );

  return `polygon( evenodd,
    0 0,
    100% 0,
    100% 100%,
    0% 100%,
    0 0,
    ${ inner_path.join( "," ) }
   )`;

}

const blur_elem = document.getElementById( "blur-around" );
blur_elem.style.clipPath = makeCircleHoleClipPathRule( 50 );

document.onmousemove = (evt) => {
  blur_elem.style.transform = `translate(${evt.clientX}px, ${evt.clientY}px)`;
};
#blur-around {
  position: fixed;
  z-index: 999;
  pointer-events: none;
  /* covering the viewport fully */
  width: 200vw;
  height: 200vh;
  /* offset to cover full viewport */
  left: -100vw;
  top: -100vh;
  /* using transform translate to move it */
  transform-origin: center;
  -webkit-backdrop-filter: blur(15px);
  backdrop-filter: blur(15px);
}
/* fallback for browsers without backdrop-filter support */
@supports not ((backdrop-filter: blur(0px)) or (-webkit-backdrop-filter: blur(0px))) {
  #blur-around {
    background-color: rgba(255,255,255,.8);
  }
}
<div id="blur-around"></div>
<p>Works over any content</p>
<img src="https://picsum.photos/250/250">
<img src="https://picsum.photos/360/200">

Currently, backdrop-filter works only in the latest Blink + Webkit browsers, with Gecko lacking support. In absence of many cross-browser solutions, consider using this polyfill which duplicates page content in an iframe (less optimal performance).

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

Passing refs in React can be achieved by using sibling components. By passing a

Here is my parent component: import React from 'react' import logo from '../Assets/LOGO.png' import EmailInput from '../Components/LoginPage/EmailInput' import PasswordInput from '../Components/LoginPage/PasswordInput&apo ...

What strategies can I use to solve this JavaScript puzzle?

One of my acquaintances has a webpage online that contains an inline script tag, featuring a JavaScript function: (#1): var domain = window.location.protocol + "//" + window.location.host + '/'; $(document).ready(function() { var count = 5 ...

Tips for sending data to CSS in Angular

I have an Angular application where I need to calculate the width of an element and store it in a variable called finalposition. Then, I want to move this element to the left by (finalposition)px when hovering over it. How can I achieve this styling effect ...

Navigating the maze of Express.js routes

When attempting to use sendFile to call my index.html page, I encountered a problem. The issue is that the index.html page displays without any of the CSS or JS/jQuery effects applied. This is what my server.js file looks like: var express = require("exp ...

Sending information from the parent component to the child Bootstrap Modal in Angular 6

As a newcomer to Angular 6, I am facing challenges with passing data between components. I am trying to launch a child component bootstrap modal from the parent modal and need to pass a string parameter to the child modal component. Additionally, I want t ...

Connecting node.js to a MySQL database on a WAMP/XAMPP server: A step-by-step guide

As a PHP programmer, I am experienced with WP, CI, and OC. However, I am a complete beginner when it comes to node.js and how to connect MySql with WAMP/XAMPP in a step-by-step method. If I were to set up a live server for this project, what would be the ...

Different Approach to Guarantee API

Here is the current structure of the promise executor: let p = new Promise((resolve, reject) => { }); It would be much cleaner if it were like this: let p = new Promise(r => { // r.resolve() / r.reject(); }); Is there a possibility to upd ...

Backbone "recalling" stored data in attributes

Presented here is a basic model: myTestModel = Backbone.Model.extend({ defaults: { title: 'My Title', config: {}, active: 1, } }) While nothing particularly stands out, there is an interesting observation regardi ...

You are unable to select the element in IE if there is an image in the background

Apologies for coming back with the same question, as I realize now that I was not clear in my explanation yesterday. You can find the codepen here (please note that it may not open in IE8). My issue is with dragging the 'move-obj' element in IE b ...

What is the best way to store dropdown values from a PHP foreach loop into local storage?

Within my shopping cart, I have added products that are stored in sessions. https://i.sstatic.net/qxz2V.png I am looking to save the selected options from all dropdowns even after the page is refreshed. When I refresh the page, my sessions need to be up ...

Checking for undefined values in fields within an array of objects using scenarios in JavaScript

I am encountering an issue with checking for undefined and empty strings in an object array using Javascript. The code provided is partly functional, but I have hit a roadblock. Within the array object, If the field value is undefined or empty, it should ...

Obtaining Texture Map coordinates from an Object's surface in Three.js

Seeking a solution for mapping a 3D object in Three.js to a point on its surface and finding the corresponding point on a texture file using x,y coordinates. Currently, I am using raycasting to locate points on the object's face, each of which should ...

Newbie mishap: Utilizing an array retrieved from a function in javascript/jquery

After submitting the form, I call a function called getPosts and pass a variable str through it. My aim is to retrieve the data returned from the function. // Triggered upon form submission $('form#getSome').submit(function(){ var str = $("f ...

Can anyone provide guidance on how to calculate the total sum of a JavaScript array within an asynchronous function?

Currently, I am working with Angularjs Protractor for end-to-end testing and faced an issue while trying to calculate the sum of values in a column. Although I am able to print out each value within the loop successfully, I am struggling to figure out ho ...

Incorporating dynamic variables into Angular: A beginner's guide

I'm working on a form where user input determines the number of additional input boxes created. Below is the JavaScript code used for this functionality. for(i = 1; i <= c; i++) { //c = total input count block = block + '<div class="ro ...

Styles coded in CSS are not reflecting on the displayed webpage, despite being visible in the Integrated

Custom Styling for ASP Membership Login in Visual Studio 2008 I am experimenting with customizing the ASP:Login control by converting it into a template. Here is the updated markup: <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Login.aspx. ...

Various CSS libraries offer a range of design options, including DataTables and Bootstrap

Incorporating both Bootstrap and DataTable into my design has caused conflicts with CSS styles. This issue extends beyond just these libraries, making me wonder if there is a way to prioritize my own styles over library styles. Can anyone provide guidanc ...

Navigating through the map function within Protractor

In my Angular application, I have implemented a timeline that displays event dates with their respective descriptions. Below is the HTML source code for this feature: <!-- timeline --> <h4 class="font-thin m-t-lg m-b-lg text-primary-lt">Hi ...

Tips for getting my scripts to function properly with my components in next.js?

I am facing an issue with my script while using React and Next.js in my pages/_app.js file. The code snippet is as follows: import axios from "axios"; import { $ } from "jquery"; import App from "next/app"; import Router from ...

Tips for converting numbers in JavaScript and troubleshooting issues when trying to filter out non-numeric characters using Tel input commands

After finding this answer on how to convert digits in JavaScript, I attempted to apply the method to convert numbers in a phone number field with tel input type. function toEnglishDigits(str) { const persianNumbers = ["۱", "۲", &quo ...