<div class="search-surface">
    <div id="dragMe" class="draggable">
        <center>
            <svg id="search" xmlns="http://www.w3.org/2000/svg" width="200" height="200" fill="currentColor" class="bi bi-search" viewBox="0 0 16 16"> <path d="M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001c.03.04.062.078.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1.007 1.007 0 0 0-.115-.1zM12 6.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0z"/> </svg>
            <div id="circle"></div>
        </center>
    </div>
</div>
<div class="styles">
    <input type="button" value="Grayscale" name="grayscale" onclick="grayscale()">
    <input type="button" value="Contrast" name="contrast" onclick="contrast()">
    <input type="button" value="Saturate" name="saturate" onclick="saturate()">
    <input type="button" value="Sepia" name="sepia" onclick="sepia()">
    <input type="button" value="Invert" name="invert" onclick="invert()">
</div>
<div id="bgImg">
    <input type="button" value="Change Img ✿" name="invert" onclick="changeBgImg()" style="font-weight: 600; width: 140px" class="changing">
</div>
<div class="tools">
    <input type="radio" id="magnifier-drag" name="fav_language" value="Magnifier-drag" onclick="magnifierDrag()">
    <label for="magnifier-drag">Magnifier</label><br>
    <input type="radio" id="cursor-pointer" name="fav_language" value="Cursor-pointer"  onclick="cursorPointer()" checked>
    <label for="cursor-pointer">Cursor</label>
</div>
<div id="cursor"></div>
@import url('https://fonts.googleapis.com/css2?family=Nunito:wght@200;300;400;500;600;700;800;900;1000&display=swap');

body {
    background: url('https://images.unsplash.com/photo-1441974231531-c6227db76b6e?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxleHBsb3JlLWZlZWR8MTR8fHxlbnwwfHx8fA%3D%3D&w=1000&q=80');
    min-height: 500px;
    background-attachment: fixed;
    background-position: center;
    background-repeat: no-repeat;
    background-size: cover;
}

.draggable {
    cursor: move;
    position: absolute;
    user-select: none;
    display: none
}

.search-surface {
    width: 100%;
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
}

input {
    background: #eeeeee1e;
    width: 120px;
    height: 34px;
    margin-top: 6px;
    border: none;
    border-radius: 10px;
    font-size: 17px;
	color: #fff;
    border: 3px solid #eeeeee;
    font-family: 'Nunito', sans-serif;
    font-weight: 400;
    cursor: pointer;
}

#bgImg {
    position: relative;
}

.changing, .changingTool {
    position: absolute;
    bottom: 0;
    right: 0;
}

.tools {
    background: #eeeeee1e;
    width: 150px;
    height: fit-content;
    margin-top: 0px;
    border: none;
    border-radius: 10px;
    font-size: 20px;
	color: #fff;
    border: 3px solid #eeeeee;
    font-family: 'Nunito', sans-serif;
    font-weight: 400;
    position: absolute;
    bottom: 0;
    right: 0;
    margin: 10px;
}

.tools input {
    width: 20px;
    height: 20px;
}

#cursor {
    width: 110px;
    height: 110px;
    backdrop-filter: grayscale(100%);
    position: absolute;
    transform: translate(-50%, -50%);
    border-radius: 50%;
    box-shadow: 0 0 20px rgba(16, 0, 54, 0.2);
    transition: 0.1s ease-out;
}

#circle {
    width: 140px;
    height: 140px;
    backdrop-filter: grayscale(100%);
    border-radius: 50%;
    margin-top: -191px;
    margin-right: 39px;
    box-shadow: 0 0 20px rgba(16, 0, 54, 0.2);
    transition: 0.1s ease-out;
}
// The current position of mouse
let x = 0;
let y = 0;

// Query the element
const ele = document.getElementById('dragMe');

// Handle the mousedown event
// that's triggered when user drags the element
const mouseDownHandler = function (e) {
    // Get the current mouse position
    x = e.clientX;
    y = e.clientY;

    // Attach the listeners to `document`
    document.addEventListener('mousemove', mouseMoveHandler);
    document.addEventListener('mouseup', mouseUpHandler);
};

const mouseMoveHandler = function (e) {
    // How far the mouse has been moved
    const dx = e.clientX - x;
    const dy = e.clientY - y;

    // Set the position of element
    ele.style.top = `${ele.offsetTop + dy}px`;
    ele.style.left = `${ele.offsetLeft + dx}px`;

    // Reassign the position of mouse
    x = e.clientX;
    y = e.clientY;
};

const mouseUpHandler = function () {
    // Remove the handlers of `mousemove` and `mouseup`
    document.removeEventListener('mousemove', mouseMoveHandler);
    document.removeEventListener('mouseup', mouseUpHandler);
};

ele.addEventListener('mousedown', mouseDownHandler);

//filters
function grayscale() {
    document.getElementById("cursor").style.backdropFilter = "grayscale(100%)";;
    document.getElementById("circle").style.backdropFilter = "grayscale(100%)";;
}

function contrast() {
    document.getElementById("cursor").style.backdropFilter = "contrast(140%)";;
    document.getElementById("circle").style.backdropFilter = "contrast(140%)";;
}

function saturate() {
    document.getElementById("cursor").style.backdropFilter = "saturate(200%)";;
    document.getElementById("circle").style.backdropFilter = "saturate(200%)";;
}

function sepia() {
    document.getElementById("cursor").style.backdropFilter = "sepia(100%)";;
    document.getElementById("circle").style.backdropFilter = "sepia(100%)";;
}

function invert() {
    document.getElementById("cursor").style.backdropFilter = "invert(100%)";;
    document.getElementById("circle").style.backdropFilter = "invert(100%)";;
}

//images
var imgArray = [
    "url(https://wallpaperaccess.com/full/120171.jpg)",
    "url(https://images.unsplash.com/photo-1441974231531-c6227db76b6e?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxleHBsb3JlLWZlZWR8MTR8fHxlbnwwfHx8fA%3D%3D&w=1000&q=80)",
    "url(https://wallpaperaccess.com/full/1163663.jpg)",
    "url(https://wallpaperaccess.com/full/160808.jpg)", 
    "url(https://wallpapercave.com/wp/wp4076875.jpg)"
];

//background img
function changeBgImg() {
   var randomItem = imgArray[Math.floor(Math.random()*imgArray.length)];
   document.body.style.backgroundImage = randomItem;
}

let myDiv = document.getElementById("cursor");
//Detect touch device
function isTouchDevice() {
  try {
    //We try to create TouchEvent. It would fail for desktops and throw error
    document.createEvent("TouchEvent");
    return true;
  } catch (e) {
    return false;
  }
}
const move = (e) => {
  //Try, catch to avoid any errors for touch screens (Error thrown when user doesn't move his finger)
  try {
    //PageX and PageY return the position of client's cursor from top left of screen
    var x = !isTouchDevice() ? e.pageX : e.touches[0].pageX;
    var y = !isTouchDevice() ? e.pageY : e.touches[0].pageY;
  } catch (e) {}
  //set left and top of div based on mouse position
  myDiv.style.left = x - 50 + "px";
  myDiv.style.top = y - 50 + "px";
};
//For mouse
document.addEventListener("mousemove", (e) => {
  move(e);
});
//For touch
document.addEventListener("touchmove", (e) => {
  move(e);
});

function magnifierDrag() {
    document.getElementById("cursor").style.display = "none";
    document.getElementById("dragMe").style.display = "flex";
};

function cursorPointer() {
    document.getElementById("dragMe").style.display = "none";
    document.getElementById("cursor").style.display = "flex";
};

External CSS

  1. https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.3.0/css/all.min.css

External JavaScript

This Pen doesn't use any external JavaScript resources.