Touch MDB Pro component

MDB Vue custom directive

Note: We are transitioning MDB4 to a legacy version and focusing on developing MDB5. While we'll continue to support for the transition period, we encourage you to migrate to MDB5. We're offering a 50% discount on MDB5 PRO to help with your transition, enabling you to leverage the full potential of the latest version. You can find more information here.
get 50% discount on MDB5 PRO

This directive allows you to improve the user experience on touch screens by calling methods on the following custom events: pinch, swipe, doubletap, longtap and pan.

Live Preview

Basic usage

Step 1: Import the directive from 'mdbvue'

        
            
      <script>
        import {
          mdbTouch
        } from "mdbvue";
      </script>
      
        
    

Step 2: Add mdbTouch to the directives object

        
            
      <script>
        import {
          mdbTouch
        } from "mdbvue";
        export default {
          directives: {
            mdbTouch
          }
        };
      </script>
      
        
    

Step 3: Attach the directive, choose one of supported events to an element and pass a callback

        
            
      <template>
        <div v-mdb-touch:doubleTap="zoom" />
      </template>
      
        
    
        
            
      <script>
        import {
          mdbTouch
        } from "mdbvue";
        export default {
          directives: {
            mdbTouch
          },
          methods: {
            zoom() {
              //...
            }
          }
        };
      </script>
      
        
    

Step 4: For the swipe event you can additionally use modifiers (left, right, up, down)

        
            
      <template>
        <div v-mdb-touch:swipe.left="changeSlide" />
      </template>
      
        
    
        
            
      <script>
        import {
          mdbTouch
        } from "mdbvue";
        export default {
          directives: {
            mdbTouch
          },
          methods: {
            changeSlide() {
              //...
            }
          }
        };
      </script>
      
        
    

Long tap

The v-mdb-touch:longTap calls the chosen method when the touch event on the element lasts longer than 1 second.

        
            
      <template>
        <section>
          <mdb-view src="https://mdbootstrap.com/img/Photos/Lightbox/Original/img%20(151).webp" imgClass="img-fluid">
            <transition enter-active-class="animated fadeIn" leave-active-class="animated fadeOut">
              <mdb-mask flex-center v-if="mask" overlay="stylish-strong"
                text="Hold the button to remove the mask from the image" />
            </transition>
          </mdb-view>
          <mdb-btn v-mdb-touch:longTap="showImage" class="mx-0 mt-2" color="pink">Tap & hold to show image</mdb-btn>
        </section>
      </template>
      
        
    
        
            
      <script>
        import {
          mdbMask,
          mdbView,
          mdbBtn,
          mdbTouch
        } from "mdbvue";
        export default {
          name: "TouchPage",
          components: {
            mdbMask,
            mdbView,
            mdbBtn
          },
          data() {
            return {
              mask: true
            };
          },
          methods: {
            showImage() {
              this.mask = false;
            }
          },
          directives: {
            mdbTouch
          }
        };
      </script>
      
        
    

Double tap

The callback on doubleTap event is called with an object containing origin field - the x and y coordinates of the user's touch. In this example it allows us to transform origin via CSS

        
            
      <template>
        <div class="img-container" v-mdb-touch:doubleTap="resizeImg" ref="img">
          <img src="https://mdbootstrap.com/img/Photos/Lightbox/Original/img%20(147).webp" :style="imgStyle"
            class="w-100" />
        </div>
      </template>
      
        
    
        
            
      <script>
        import {
          mdbTouch
        } from "mdbvue";
        export default {
          data() {
            return {
              scale: 1,
              origin: null
            };
          },
          computed: {
            imgStyle() {
              return {
                transform: `scale(${this.scale})`,
                transformOrigin: this.origin ?
                  `${this.origin.x}px ${this.origin.y}px 0` :
                  "50% 50% 0"
              };
            }
          },
          methods: {
            resizeImg(e) {
              const rect = this.$refs.img.getBoundingClientRect();
              this.origin = {
                x: e.origin.x - rect.x,
                y: e.origin.y - rect.y
              };
              this.scale === 1 ? (this.scale = 2) : (this.scale = 1);
            }
          },
          directives: {
            mdbTouch
          }
        };
      </script>
      
        
    
        
            
      <style scoped>
        .img-container {
          width: 100%;
          max-height: 600px;
          overflow: hidden;
        }

        .img-container img {
          transition: transform 0.4s linear;
        }
      </style>
      
        
    

Pinch

The pinch event calls the given method with an object containing two keys - ratio and origin. The first one it the ratio of the distance between user's fingers on touchend to the same distance on touchstart - it's particularly useful for scaling images. The second one, similarly as in doubleTap event, is a pair of coordinates indicating the middle point between the user's fingers.

        
            
      <template>
        <div class="img-container" v-mdb-touch:pinch="zoom" ref="pinchImg">
          <img src="https://mdbootstrap.com/img/Photos/Lightbox/Original/img%20(152).webp" class="img-fluid"
            :style="imgStyle2" />
        </div>
      </template>
      
        
    
        
            
      <script>
        import {
          mdbTouch
        } from "mdbvue";
        export default {
          data() {
            return {
              scale2: 1,
              origin2: null
            };
          },
          computed: {
            imgStyle2() {
              return {
                transform: `scale(${this.scale2})`,
                transformOrigin: this.origin2 ?
                  `${this.origin2.x}px ${this.origin2.y}px 0` :
                  "50% 50% 0"
              };
            }
          },
          methods: {
            zoom(e) {
              const rect = this.$refs.pinchImg.getBoundingClientRect();
              this.origin2 = {
                x: e.origin.x - rect.x,
                y: e.origin.y - rect.y
              };
              this.scale2 * e.ratio > 1 ?
                (this.scale2 *= e.ratio) :
                (this.scale2 = 1);
            }
          },
          directives: {
            mdbTouch
          }
        };
      </script>
      
        
    
        
            
      <style scoped>
        .img-container {
          width: 100%;
          max-height: 600px;
          overflow: hidden;
        }

        .img-container img {
          transition: transform 0.4s linear;
        }
      </style>
      
        
    

Swipe

The swipe event comes with several modifiers (left, right, up, down) - each of them will ensure that event will fire only on swipe in that particular direction. If the directive is used without any modifier, the callback method will be called each time the swiping occurs, and the string indicating the direction will be passed as an argument.

        
            
      <template>
        <div v-mdb-touch:swipe.left="swipeLeft" v-mdb-touch:swipe.right="swipeRight">
          <mdb-view src="https://mdbootstrap.com/img/Photos/Lightbox/Original/img%20(148).webp" imgClass="img-fluid">
            <mdb-mask :overlay="overlays[activeOverlay]" />
          </mdb-view>
        </div>
      </template>
      
        
    
        
            
      <script>
        import {
          mdbMask,
          mdbView,
          mdbTouch
        } from "mdbvue";
        export default {
          components: {
            mdbMask,
            mdbView
          },
          data() {
            return {
              activeOverlay: 0,
              overlays: [
                "indigo-light",
                "indigo-strong",
                "blue-light",
                "pink-light"
              ]
            };
          },
          methods: {
            swipeRight() {
              if (this.activeOverlay === 0)
                this.activeOverlay = this.overlays.length - 1;
              else this.activeOverlay--;
            },
            swipeLeft() {
              if (this.activeOverlay === this.overlays.length - 1)
                this.activeOverlay = 0;
              this.activeOverlay++;
            }
          },
          directives: {
            mdbTouch
          }
        };
      </script>
      
        
    

Pan

The pan event is useful for dragging elements - every time the user moves a finger on the element to which the directive is attached to, the given method is being called with an argument consisting of two keys: x and y (the values corresponds to the horizontal and vertical translation).

        
            
      <template>
        <div v-mdb-touch:pan="pan" style="overflow: hidden; height: 400px;">
          <img :style="imgStyle3" src="https://mdbootstrap.com/img/Photos/Lightbox/Original/img%20(47).webp" />
        </div>
      </template>
      
        
    
        
            
      <script>
        import {
          mdbTouch
        } from "mdbvue";
        export default {
          data() {
            return {
              translate: {
                x: 0,
                y: 0
              }
            };
          },
          computed: {
            imgStyle3() {
              return {
                transform: `translate(${this.translate.x}px, ${this.translate.y}px)`
              };
            }
          },
          methods: {
            pan(e) {
              this.translate = {
                x: this.translate.x + e.x,
                y: this.translate.y + e.y
              };
            }
          },
          directives: {
            mdbTouch
          }
        };
      </script>