• Making a seekable progress component a.k.a slider in Vue.

    Making a seekable progress component a.k.a slider in Vue.

    Nov 28, 2020Updated on Apr 3, 2021

    Lately I've been working on an update of an audio player that I created last year as visible on github: xns-audio-player.

    In short it's an audio player that's based to work with vue, the idea being, it should support persistent playback on route changes in a javascript environment, in this case Vue.

    Like on a couple other projects, I always start with an idea then execute it with more bloated code and plugins than favorable. Then I usually proceed with cutting back on the plugins in favor of custom components, re-inventing the wheel so to speak, but with the target of reducing code size and hopefully increasing performance by reducing dependencies.

    So, amongst the plugins I decided to cut off from the project, was a slider component that I used to convey audio playback position and seeking to the UI, which brings us to this article. I decided to share this cause I think it might be useful to someone out there who at first might assume creating such functionality on their project is a complicated task, well, no it's not.

    Let's get down to business.

    Our objective is to achieve this 👇
    Alt The final component

    Since this project is based on Vue, I'll be using code snippets from the component itself which is in a Vue environment, but likewise, you can apply the same concept on any Javascript environment as we will be utilizing Javascript event listeners.

    After setting up the Vue project environment (here for beginners) we will start by creating our seekable component and name it 'SeekProgress.vue'

    Our template will contain only two div blocks, a wrapper which will be setting the dimensions for our component, and it's child which will be an absolute positioned div covering the parent based on the percentage of the total width.

    <template>
      <div id="app">
        <div class="progress-wrapper">
          <div class="progress"></div>
        </div>
      </div>
    </template>
    
    <script>
    export default {
      name: 'SeekProgress',
    }
    </script>
    
    <style lang="scss">
    .progress-wrapper{
      display: block;
      height: 200px;
      margin: 200px 20px;
      position: relative;
      background: #e1e1e1;
    
      .progress{
        position: absolute;
        left: 0;
        right: 0;
        bottom: 0;
        top: 0;
        background: teal;
      }
    }
    </style>
    

    Next, we will add a reference to our wrapper block by using a $ref, whereas we'd utilize the div's id or class to reference it in but not limited to vanilla js.

    <template>
      <div id="app">
        <div ref="listenTo" class="progress-wrapper">
          <div class="progress"></div>
        </div>
      </div>
    </template>
    

    After listening to the Javascript events we'll be modifying the '.progress' div's width by adding inline styling to it, passing the width percentage.

    <template>
      <div id="app">
        <div ref="listenTo" class="progress-wrapper">
          <div :style="'width:'+progress+'%'" class="progress"></div>
        </div>
      </div>
    </template>
    

       

    Buy Me A Coffee