Implement a smooth transition effect when changing the image source

I am currently working on enhancing a Squarespace website by adding a new image fade-in/fade-out effect when the mouse hovers over one of three buttons. The challenge I'm facing is that the main static image is embedded as an img element in the HTML rather than in the CSS, making it difficult to change it directly. I attempted to modify the element.src using JavaScript, but unfortunately, there was no transition effect. Would it be advisable to introduce another element into the JavaScript code to achieve the desired image transition with opacity? However, this seems like additional work especially when operating within the constraints of Squarespace.

Any advice or suggestions on how to approach this issue would be greatly appreciated. Additionally, I have included a snippet displaying my current code and highlighting the problem at hand.

Just a note - the buttons are currently positioned beneath the image and do not require any adjustments to their placement.

Answer №1

To create a visually dynamic effect, I suggest layering two <img> elements within a <div> container and adjusting the opacity. When not hovering over a button, the fixed image will be on top. Upon hover, switch the image below using imageBelow.src = images[i] and alter the opacity of the image above with

imageAbove.style.opacity = "0";

wrapImages();

let imageBelow = document.querySelector('.pics .below');
let imageAbove = document.querySelector('.pics .above');
let jw_btn = document.querySelectorAll('.sqs-block-content h1 a');
let images = ['https://static1.squarespace.com/static/5fe99a39cc46cf62c078c5a0/t/5ff85ea72dbf216159f9567d/1610112687144/homepage_story_1500x896.jpg', 'https://static1.squarespace.com/static/5fe99a39cc46cf62c078c5a0/t/5ff85e88b1f66202d7f3e8e4/1610112659325/homepage_art_1500x896.jpg', 'https://static1.squarespace.com/static/5fe99a39cc46cf62c078c5a0/t/5ff85ebf1701e075bcb4c460/1610112707995/homepage_Studio_1500x896.jpg'];

jw_btn.forEach(function(jw_btn_current, index) {
  jw_btn_current.addEventListener('mouseenter', function() {
    imageBelow.src = images[index]; 
    imageAbove.style.opacity = "0";
  });
  jw_btn_current.addEventListener('mouseleave', function() {
    imageAbove.src = 'https://static1.squarespace.com/static/5fe99a39cc46cf62c078c5a0/t/5ff44194b93643179814a20d/1610108761001/Lady+in+blue.jpg';
    imageAbove.style.opacity = "1";
    
  });
});


function wrapImages() {

let sectionBackground = document.querySelector('.section-background');
let images = sectionBackground.getElementsByTagName('img');
var newDiv = document.createElement("div");
newDiv.className="pics";
sectionBackground.insertBefore(newDiv, sectionBackground.firstChild);
newDiv.appendChild(images[0]);
newDiv.appendChild(images[1]);
images[0].className="below";
images[1].className="above";

}
*,*::before,*::after {
    box-sizing: border-box;
    padding: 0;
    margin: 0;
}
body{
    height: 200vh;
}

img{
    background-repeat: no-repeat;

    transition: all .5s ease-in-out;
}

.pics {

    position: relative;
    width: 100%;
    height: 100vh;
}

.pics > img {

    position: absolute;
    transition: all .4s ease;
}



.ulwrapper{
    display: flex;
    height: 100vh;
    align-items: center;
}
.sqs-block-content{
    display: flex;
    width: 100%;
    height: 4rem;
    list-style: none; 
}
h1{
    margin: auto;
    cursor: pointer;
}
h1 a{
    font-weight: bolder;
    text-decoration: none;
    color: black;
}
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="style.css">


</head>

<body>

    <div class='section-background'>
    
            <img alt="" 
                data-src="https://static1.squarespace.com/static/5fe99a39cc46cf62c078c5a0/t/5ff44194b93643179814a20d/1610108761001/Lady+in+blue.jpg"
                data-image="https://static1.squarespace.com/static/5fe99a39cc46cf62c078c5a0/t/5ff44194b93643179814a20d/1610108761001/Lady+in+blue.jpg"
                data-image-dimensions="2000x1195" data-image-focal-point="0.24133662454825583,0.20697233746829613"
                data-load="false" data-parent-ratio="1.4"
                style="width: 100%; height: 100%; object-position: 0% 20.6972%; object-fit: cover;" 
                data-image-resolution="2500w"
                src="https://images.unsplash.com/photo-1610043238036-7309f1cc52d8?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=1534&q=80"></em>
            <img alt="" 
                data-src="https://static1.squarespace.com/static/5fe99a39cc46cf62c078c5a0/t/5ff44194b93643179814a20d/1610108761001/Lady+in+blue.jpg"
                data-image="https://static1.squarespace.com/static/5fe99a39cc46cf62c078c5a0/t/5ff44194b93643179814a20d/1610108761001/Lady+in+blue.jpg"
                data-image-dimensions="2000x1195" data-image-focal-point="0.24133662454825583,0.20697233746829613"
                data-load="false" data-parent-ratio="1.4"
                style="width: 100%; height: 100%; object-position: 0% 20.6972%; object-fit: cover;" 
                data-image-resolution="2500w"
                src="https://static1.squarespace.com/static/5fe99a39cc46cf62c078c5a0/t/5ff44194b93643179814a20d/1610108761001/Lady+in+blue.jpg?format=2500w"></em></em>;
            
        </div>
        <div class="ulwrapper">

            <div class="sqs-block-content">
                <h1 class="jw_btn"><a>Button1</a></h1>
                <h1 class="jw_btn"><a>Button2</a></h1>
                <h1 class="jw_btn"><a>Button3</a></h1>
            </div>
        </div>
    </div>


    <script src="app.js"></script>
</body>

</html>

EDIT

If SquareSpace doesn't allow manual HTML wrapping, you can dynamically add a wrapper. Introducing the wrapImages() function at the start of the JS code accomplishes this.

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

Error: The specified JSON path for Ajax request could not be

Although my expertise lies in C++, I must confess that my knowledge about web development is quite limited. Therefore, please bear in mind that my question requires a simple answer. Recently, I stumbled upon a fascinating C++ library for creating a web se ...

Creating a typewriter animation using Tailwind CSS and Next.js

I am currently working on implementing a typewriter effect that is almost exactly how I want it. However, I am facing an issue with the printing process. Right now, each word gets printed on a new line and falls into place when done printing. What I actual ...

Invoke a method on a child component once an event has been emitted

Currently, I am working on creating a custom button component that includes a spinner. The functionality works well - the button gets disabled and displays a spinner upon click. However, I am facing issues when it comes to resetting the button's state ...

Unlocking the power of promises: How Node.js excels at handling

I'm facing a situation where my controller code is structured like this. const Users = require("../models/users"); class UserController() { getUserById(req, res) { const id = req.params.id; const users = new Users(); ...

"Enhanced interactivity: Hover effects and selection states on an image map

Hello there, I need assistance with my code. Here it is: <img id="body_image" usemap="#body_map" src="assets/images/body.jpg" alt=""> <map name="body_map"> <area shape="poly" alt="d" href="#body_chart" name="ad" coords="153, 153, 145, 1 ...

The PHP "include" function seems to be malfunctioning when used inside

Hey there! I'm trying to incorporate an echo statement that includes a variable along with some CSS and an image, but for some reason it's not working as expected. Can anyone lend a hand? <?php if (isset($_POST['sharebutton'])) ...

Having trouble with Bootstrap not hiding on small screens as intended?

I'm not sure if the issue is related to my browser, but I need the first pills-tab to be hidden on small screens and visible on medium to larger screens. The second pills-tab should be visible on small screens and hidden on larger screens. <!D ...

Utilizing jquery and ajax to submit a form seamlessly without the need to refresh the web page

I've been struggling to submit a form without refreshing the entire page. I integrated some source code that I found, but for some reason, it's not working! Here is the HTML form I'm trying to submit: <form method="POST" action="" name= ...

What is the best way to cancel a Promise if it hasn't been resolved yet

Let's consider a situation where I have implemented a search function to make an HTTP call. Each call made can have varying durations, and it is crucial for the system to cancel any previous HTTP requests and only await results from the latest call. ...

Steps for creating a dynamic progress bar with inverted text style using only CSS

I am working on creating a dynamic progress bar with inverted text color using only CSS. To see examples of what I am trying to achieve, you can refer to the following links. Inverted Colors CSS progress bar CSS Progress Bars https://i.sstatic.net/VSs5 ...

The dimensions of the bottom border on left floating divs are inconsistent

One of my designers frequently uses a particular technique in various designs, and I'm struggling to determine the most effective way to style it with CSS so that it fluidly adapts (as it will be incorporated into a CMS). Essentially, when implementi ...

Using Webpack postcss prefixer with Vue CLI 3

As I work on implementing Bulma CSS in my project using Vue CLI 3, I encounter the need to prefix the classes with webpack. While I found an example of this process, adapting it from a webpack config to vue.config.js poses some challenges. Here is the ini ...

Utilizing a for loop to iterate through an array based on its length

Just delving into the world of JavaScript and recently grasped the concept of For loops. I have a variable that holds an array with a list of first names, and my goal is to add last names to each of them. Here's the code snippet I came up with: l ...

Encountering issues while attempting to utilize pdf2json in a TypeScript environment

When attempting to import pdf2json (3.0.1) into my Node project using TypeScript, I encountered the following error: "Could not find a declaration file for module 'pdf2json'." I also tried installing @types/pdf2json for TypeScript but found tha ...

Emulate an AngularJS ng-click action

My website has HTML code with three buttons: <button ng-click='showStats(player.data,0)'>Death Match</button> <button ng-click='showStats(player.data,1)'>Champions Rumble</button> <button ng-click='sho ...

The Year as a Reference Point

I came across an interesting issue while working with dictionaries and JSON in sessionStorage. Initially, I had a dictionary structured like this: "name" : { "2016" : { "1" : "info" } } After successfully adding it to sessionS ...

Combine several pages from PDF files into a single document

I am currently working on developing a small electron application that combines multiple PDF files or pages into one larger page to help save paper when printing several CAD drawings. Essentially, I am looking for a cross-platform solution similar to the ...

How to customize the button color in a Next.js application

Help Needed: Issue with Changing Default Button Color in Next.JS Web Application. The button text color appears as grey on Desktop Google Chrome, but shows up as blue on Mobile Chrome browser. I want to unify the color to be grey on both platforms. Custo ...

Displaying an email exist error message is important when updating an email address, and it is necessary to validate both the

      My code is triggering an email exists error when I remove NOT EXISTS from the SELECT query. However, it also incorrectly claims that my current email already exists when I try to update it. How can I modify the select query to handle the email e ...

Transfer only certain directories located within the primary directory

Imagine having a main-folder, which contains folders of type my-folder-x. Within these my-folder-x folders, there are subfolders and files. -main-folder -my-folder-a -build-folder -demo-folder dummy.js dummy.css my.json -dummy-folder - ...