Ways to incorporate a smooth transition between the opened and closed fab functionality

I am currently utilizing VueJS and Vuetify in my project. I have successfully implemented Vuetify's FAB component, which displays a list of fab buttons as demonstrated in the documentation:

<div id="fab-button">
  <v-speed-dial v-model="fabActiveStatus" bottom left fixed direction="top" transition="slide-y-reverse-transition" style="margin: 25px">
    <template v-slot:activator>
      <v-btn v-model="fabActiveStatus" dark fab x-large :color="fabBgColor">
        <v-icon v-if="fabActiveStatus">mdi-close</v-icon>
        <v-icon v-else>mdi-plus</v-icon>
      </v-btn>
    </template>
    <v-tooltip right>
      <template v-slot:activator="{ on, attrs }">
        <v-btn v-bind="attrs" v-on="on" fab dark :color="fabBgColor" @click="$emit('fl-btn-settings-popup', true)">
          <v-icon>mdi-upload</v-icon>
        </v-btn>
      </template>
      <span>add</span>
    </v-tooltip>
    <v-tooltip right>
      <template v-slot:activator="{ on, attrs }">
        <v-btn v-bind="attrs" v-on="on" fab dark :color="fabBgColor" @click="$emit('fl-btn-settings-popup', true)">
          <v-icon>mdi-cloud</v-icon>
        </v-btn>
      </template>
      <span>goto</span>
    </v-tooltip>
    <v-tooltip right>
      <template v-slot:activator="{ on, attrs }">
        <v-btn v-bind="attrs" v-on="on" fab dark :color="fabBgColor" @click="$emit('fl-btn-settings-popup', true)">
          <v-icon>mdi-share-variant</v-icon>
        </v-btn>
      </template>
      <span>share</span>
    </v-tooltip>
  </v-speed-dial>
</div>

While this setup functions well, I am looking to incorporate a smoother transition between opening and closing the fab buttons. I would like to achieve an animation similar to that seen in the vue-fab library:

Instead of a simple switch between the '+' and 'x' icons, I want to introduce a seamless turning motion as depicted in the examples above.

Is there a way to achieve this using Vuetify?

Answer №1

Customize the fab icon with your own classes and make it spin when activated:

Vue.config.productionTip = false;
Vue.config.devtools = false;
new Vue({
  el: '#app',
  vuetify: new Vuetify(),
  data: () => ({
    isFabOpen: false,
  })
})
#example {
  width: calc(100vw - 6rem);
  height: calc(100vh - 6rem);
  margin: 3rem;
}

div.theme--light.v-application {
  background-color: #f4f6f8;
}

#app .v-speed-dial {
  position: absolute;
}

#app .v-btn--floating {
  position: relative;
}


/* 👇 Add your custom classes here */

.rotator {
  transition: transform .3s cubic-bezier(.4, 0, .2, 1);
  transform: rotate(0.125turn);
}

.is-rotated {
  transform: rotate(.5turn);
}
<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="7107041431435f475f4045">[email protected]</a>/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="2e585b4b5a4748576e1c0056">[email protected]</a>/dist/vuetify.js"></script>
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@mdi/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="8bede4e5ffcbbda5f3">[email protected]</a>/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="3e484b5b4a5758477e0c1046">[email protected]</a>/dist/vuetify.min.css" rel="stylesheet">
<div id="app">
  <v-app>
    <v-card id="example" shaped>
      <v-container>
        <v-speed-dial v-model="isFabOpen" :bottom="true" :right="true" :direction="'top'" :transition="'slide-y-reverse-transition'">
          <template v-slot:activator>
            <v-btn
              v-model="isFabOpen"
              :color="isFabOpen ? 'red darken-2' : 'blue darken-2'"
              dark
              fab>
                             <!-- 👇 Insert your custom classes here -->
              <v-icon :class="['rotator', isFabOpen ? 'is-rotated' : '']">
                mdi-close
              </v-icon>
            </v-btn>
          </template>
          <v-btn fab dark small color="green">
            <v-icon>mdi-pencil</v-icon>
          </v-btn>
          <v-btn fab dark small color="indigo">
            <v-icon>mdi-plus</v-icon>
          </v-btn>
          <v-btn fab dark small color="red">
            <v-icon>mdi-delete</v-icon>
          </v-btn>
        </v-speed-dial>
      </v-container>
    </v-card>
  </v-app>
</div>

Experiment with different rotation values to customize the spinning effect of the icon. Values ending in .25, .5, .75, or .0 are recommended for x symmetry, while values ending in .125, .375, .625, or .875 work well for + symmetry.

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

Trouble with ASP.NET Master Page CSS Rendering Incorrectly

My CSS seems to be causing some trouble as the DIVs are not aligning as they should. Instead, they are just wrapping around the text and not adjusting the page layout properly. Here is an example of my CSS: body { height: 95%; width: 100%; ma ...

Mobile device causing issues with sticky footer functionality

Can anyone help me troubleshoot an issue with my sticky/floating bottom footer on a calorie calculator? It works fine on desktop but not on mobile. Any ideas what might be causing the problem? HTML: <footer class="footer"> <div class="summar ...

Unable to load CSS background image

As I develop a website for a fictional company to enhance my skills in HTML, CSS, and JavaScript, I am encountering an issue with loading my background image. If someone could review my code to identify the problem, I would greatly appreciate it. Check ou ...

VueJs Ellipsis Filter: Enhance Your Texts with

Using Vue.JS, I am dynamically injecting text content into a DOM element. <article>{{ movie.summary }}</article> My goal is to implement an auto-ellipsis filter. Essentially, the code would look like this: <article>{{ movie.summary | e ...

Tips for building a versatile client-server application with separate codebases for the JavaScript components

We are embarking on the process of rebuilding our CMS and leveraging our expertise with VueJS. Despite our familiarity with VueJS, we won't be able to create a full single-page application due to the presence of server-side rendering files (JSP). The ...

What is the best way to update the v-model of an element that has been modified programmatically?

I am currently utilizing a JavaScript plugin for Checkbox functionality. This particular plugin creates a switch button that mirrors the state of the checkbox. When the switch button is toggled, it updates the checked value of the checkbox. <input t ...

Could you provide suggestions on how to update the content of an HTML tag within a Vue component?

I am new to Vue.js and struggling to grasp its concepts. I am interested in finding a way for my custom Vue component (UnorderedList) to manipulate the content within it. For example, if I have <p> tags inside my component like this : <UnorderedL ...

Does anyone know how to begin implementing Opentelemetry browser instrumentation for a vue.js application?

import { WebTracerProvider, BatchSpanProcessor, ConsoleSpanExporter, SimpleSpanProcessor } from '@opentelemetry/sdk-trace-web'; import { ZoneContextManager } from '@opentelemetry/context-zone'; import { Resource } from '@opentelem ...

Injecting HTML into Vue component

Currently, I am passing some parameters into a Vue component <Slider :images= "['/img/work/slide2.png', '/img/work/slide2.png', '/img/work/slide3.png']" :html="['<div>hello</div>', ' ...

The content will be visible when the masonry element is in the active state

I have been working on creating a unique image gallery effect using Masonry layout where the images start at 0.2 opacity and change to full opacity of 1 when hovered over. Additionally, I want each image to fade to 0.7 opacity with text "Petra, Jordan" app ...

Is it possible that the images are unable to load on the page

The frontend code successfully retrieves the image links sent by the backend but encounters issues displaying them. Despite confirming that the imgUrl data is successfully fetched without any hotlink protection problems, the images are still not appearing ...

npm installs a multitude of dependencies

Recently, I purchased an HTML template that includes various plugins stored in a directory named bower_components, along with a package.js file. While trying to add a new package that caught my interest, I opted to utilize npm for the task. Upon entering ...

The entire image is unable to be shown within the div

When adding images to a carousel, I encountered an issue where only the top half of the image is displayed on the page. It seems that the image is not adjusting itself to fit the div container properly, resulting in only a portion of it being visible behin ...

Make the text in the SCSS file placeholder bold

Within my Angular front end application, there is a form containing a textarea: <mat-form-field class="full-width"> <textarea class="left-aligned" formcontrolname="x1" matInput placeholder="some text"/> </mat-form-field> In the co ...

Brainstorm: Creative ways to showcase excess content within a div

I'm struggling to find a suitable title for this issue. Essentially, I have a box-shaped div that expands into a rectangle and reveals content when clicked. The problem arises when I animate the div's width during expansion. Instead of positioni ...

CSS table row border displaying irregularly in Chrome and Internet Explorer

I recently created a basic table with bottom row borders. Surprisingly, the borders display perfectly in Firefox but only partially in Chrome and IE 10: <div style="display:table; border-collapse: collapse; width: 100%"> <div style="display:table ...

An application built with Vue.js featuring various layouts such as a login interface, a page layout, and a sign-up screen

After generating a project using vue-cli, I noticed that the project comes with an App.vue file which serves as the main layout of the app. However, I need a completely different layout for the login page, with different wrappers and body classes. The prob ...

Looking to alter the CSS of an ID element when hovering over a link on your website?

Irrespective of the positioning of the links in the html, a simple hover effect can trigger changes like switching images or altering backgrounds anywhere on the website. The ideal solution would involve a straightforward method without the need for Javas ...

The SVG path is not aligned properly with the container's viewbox dimensions

Recently, I came across an icon provided by a plugin I am using called calendar. However, I wanted to enhance my icons set with a new addition - the twitter icon. svg { display: inline-block; height: 16px; width: 16px; margin: 2px 0; ...

"Interactive feature allowing users to edit and view the most recently inserted HTML

My approach involves using a contenteditable div as an input field for entering text and inserting icons through a button that adds small HTML pictures within the text. Everything works fine when the text is narrower than the contenteditable field. Howev ...