Scrolling causes the image to blink

I have a specific task to create an effect where an image blinks three times on scrolling (like lights turning on and off consecutively with a 1-second delay), and then stays on until the user scrolls beyond 3600px.

To achieve this, I have added an event listener:

created() {
  window.addEventListener('scroll', this.scrollAnimation)
}

This event listener triggers the method scrollAnimation:

methods: {
  scrollAnimation() {
    let currentPos = window.pageYOffset
    if (currentPos > 3000 && currentPos < 3600) {
      this.$refs.supportOff.style.display = 'none'
      this.$refs.supportOn.style.display = 'block'
    } else {
      this.$refs.supportOff.style.display = 'block'
      this.$refs.supportOn.style.display = 'none'
    }
  }
}

Below is the HTML template for the images:

<div class="support__image-wrapper">
  <img ref="supportOff" class="support__image support__image_on" src="../../assets/images/247-off.png">
  <img ref="supportOn" class="support__image support__image_off" src="../../assets/images/247-on.png">
</div>

The code currently works when scrolling between 3000 and 3600 pixels, showing the appropriate images. However, there is an issue with creating the blinking effect using setInterval as it triggers every time the user scrolls within that range. What would be the best approach to implement the desired blinking effect?

Answer №1

Here are a couple of suggestions to consider...

  1. Avoid manipulating the dom directly using $ref

Instead, create a variable that triggers changes in the dom structure

methods: {
  toggleAnimation() {
    this.toggleVisibility = window.pageYOffset > 2000 && window.pageYOffset < 2500
  }
}
<div>
  <img v-if="toggleVisibility" class="animated" src="../../assets/images/on.png">
  <img v-else src="../../assets/images/off.png">
</div>
  1. Animating Consider using CSS animations (@keyframes). This method allows you to control the animation timing without script intervention. The animation will automatically start when it becomes visible on the page.
.animated {
  animation: pulse 1s infinite;
}

@keyframes pulse {
    0% {opacity: 0}
    50%{opacity: 0}
    100% {opacity: 1}
}

I hope these tips prove helpful for your project.

Answer №2

Let me showcase a brief demonstration for any upcoming readers, inspired by j4n3l's feedback on the potential performance impact caused by unoptimized/debounced scroll events; and also Smithy's excellent suggestion regarding the usage of CSS @keyframes for creating blinking animations:

new Vue({
  el: '#root',

  data() {
    return {
      blinkSpeed: 800,
      blinkFrequency: 4,
      isBlinking: false,
      blinkTimeoutId: -1,

      isActive: false,
      currentPosition: window.pageYOffset
    }
  },

  mounted() {
    window.addEventListener('scroll', _.debounce(() => {
      this.currentPosition = window.pageYOffset;

      if (this.currentPosition > 2500 && this.currentPosition < 3200) {
        this.isActive = true;
      } 
      else {
        this.isActive = false;
      }
    }), 150);
  },

  methods: {
    initiateBlink() {
      if (this.blinkTimeoutId > -1) {
        clearTimeout(this.blinkTimeoutId);
      }

      this.isBlinking = true;

      this.blinkTimeoutId = setTimeout(() => {
        this.isBlinking = false;

      }, 1000 * this.blinkFrequency);
    }
  },

  watch: {
    isActive() {
      this.initiateBlink();
    }
  }
});
#root {
  background-color: lightgray;
  height: 1500vh;
  padding: 15px;
}

.scroll-position {
  position: fixed;
  top: 10px;
  right: 10px;
}

.blink-effect > div {
  border-radius: 50%;
  border: 2px solid white;
  color: white;
  font-weight: bold;
  height: 30px;
  left: 10px;
  line-height: 30px;
  padding: 5px;
  position: fixed;
  text-align: center;
  top: 10px;
  vertical-align: middle;
  width: 30px;
}

.blink-effect.animate > div {
  animation: blinker 1s infinite;
}

.blink-effect .active {
  background-color: blue;
}

.blink-effect .inactive {
  background-color: red;
}

@keyframes blinker {
  0% {
    opacity: 0
  }
  49% {
    opacity: 0
  }
  50% {
    opacity: 1
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.14/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>

<div id="root">
  <div :class="['blink-effect', { 'animate': isBlinking } ]">
    <div class="active" v-if="isActive">ACTIVE</div>
    <div class="inactive" v-else>INACTIVE</div>
  </div>

  <code class="scroll-position">pageYOffset: {{Math.floor(currentPosition)}}</code>
</div>

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

When the second history.push is triggered in react-router-dom, it may result in returning an

Hello, I am working with an Antd modal that contains a form. The code snippet for the modal is as follows: <Modal visible={visible} onOk={handleOk} onCancel={handleCancel}> <MyForm onSubmit={handleOpenUrl}> <CustomInput name= ...

Add a slot to each element within Vue.js

I added a component called vue-select, which is a third-party package that I installed. My goal is to include a slot template in each instance of this component. I envision accomplishing something along the lines of: <v-select> <span slot="no-o ...

Ensuring a dependable detection of WebSocket connection status

I've been researching how to create a dependable method for recovering a WebSocket connection. After exploring various options, I discovered that one approach involves sending heartbeats (ping/pong) to the server and monitoring if the entire pong is ...

Is there a way to access and troubleshoot the complete source code within .vue files?

I've been struggling for hours trying to understand why I'm unable to view the full source of my .vue files in the Chrome debugger. When I click on webpack://, I can see the files listed there like they are in my project tree, but when I try to o ...

Extracting and retrieving data using JavaScript from a URL

After reviewing some code, I am interested in implementing a similar structure. The original code snippet looks like this: htmlItems += '<li><a href="show-feed.html?url=' + items[i].url + '">' + items[i].name + '& ...

RectAreaLight in Three js does not produce any light reflection when used with MeshPhongMaterial due to lack of support for OES_texture_half

After trying to incorporate a RectAreaLight into my three.js scene where I have objects with MeshPhongMaterial, I noticed that there is no light reflection on the objects. A useful example can be found here: Link If you open the developer tools, you can s ...

Why do my posts appear twice on the page after submitting a new post? When I refresh the page, the posts seem to duplicate

After submitting the create post controller via POST, the post appears once. However, upon reloading the page using GET, it shows up twice. How can I prevent this duplication and ensure that existing posts are only displayed once? I aim to have the post d ...

Can a websocket be used to communicate with a server that is not the same as the one hosting the html5 website?

My goal is to establish communication between a hardware device and an HTML5 website. It seems like the best way to do this would be through WebSockets or possibly WebRTC over a WiFi network. Is that correct? I haven't come across any solutions invol ...

Click on a link to open it in the current tab with customized headers

In my Angular project, I am attempting to open a link by clicking a button that redirects to the specified URL using the following code: window.open(MY_LINK, "_self"); However, in this scenario, I also need to include an access token in the header when t ...

It appears that the JavaScript array is able to modify itself autonomously

Currently, I am working on a project using P5.js where I am saving values in an array and then creating a copy of that array to manipulate. However, I have encountered an issue where manipulating the second array also changes the original one, and I cannot ...

Failure when running npm start command in Nest js

After setting up a fresh Nest js on a new EC2 machine, I encountered an error when trying to run it for the first time. The error message indicated that the npm install process failed abruptly without any visible error: ubuntu@ip-172-31-15-190:~/projects/m ...

Tips on personalizing the default html template in nuxt

Struggling to customize the default page from my Nuxt app due to limited documentation. Link to Documentation I'm interested in extracting only certain elements like the title or links in the head section. For example, how can I access just the li ...

v-autocomplete no selected option

Within my Vue.js 2 and Vuetify component, I am receiving the following data : [ { "anio": 2022, "__typename": "Grupo" }, { "anio": 2020, "__typename": "Grupo" }, { "anio": 2018, "__ ...

The output type of a function given an input

Essentially, I have successfully rendered a return type for my combined reducers using the following code: const rootReducer = combineReducers({ notes: notesReducer, categories: categoriesReducer, flyout: flyoutReducer // more reducers }); export ...

The Angular custom modal service is malfunctioning as the component is not getting the necessary updates

As I develop a service in Angular to display components inside a modal, I have encountered an issue. After injecting the component content into the modal and adding it to the page's HTML, the functionality within the component seems to be affected. F ...

Tips for styling text in a mailto function

I am working with two arrays and an object in my project. The first array contains product codes, while the second array contains the quantities of each product. The quantities array corresponds to the product codes array, meaning the first quantity in the ...

Maximizing the Potential of SSJS ContinueRequest

Is there a way to incorporate ContinueRequest into the script shown below in order to bypass the 2500 limit? <script runat="server"> Platform.Load("Core","1"); try { var DEkey = Request.GetQueryStringParameter(&qu ...

Encountered Minified React error #418 and #423 while using Next.js v12.3.1 and React v18.2.0

Ever since the recent updates, I've been facing a couple of errors in my application that go like this: Uncaught Error: Minified React error #418; visit https://reactjs.org/docs/error- decoder.html?invariant=418 for the full message or use the non-mi ...

The PDF document appears quite different from the original HTML page it was created from

Is there a way to create a PDF document that mirrors the appearance of a web page using jsPdf? When attempting this, it seems that the font size, text alignment, and table alignment of the resulting PDF do not match that of the original web page. Additiona ...

Is there a way to adjust a simple program using Discord.js where the setTimeout within a for-loop can print values sequentially instead of simultaneously?

Here is the code I'm using: for (let i = 0; i <= 5; i++) { delay(i); } function delay(i) { setTimeout(() => console.log(`${i} is the number`), 2000); } The output I'm currently getting after 2 seconds is: 0 is the number 1 is the ...