Skip to content

Instantly share code, notes, and snippets.

@fukata
Last active January 9, 2023 07:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fukata/e61563b887dc2f5bfee6b31c07c20b7f to your computer and use it in GitHub Desktop.
Save fukata/e61563b887dc2f5bfee6b31c07c20b7f to your computer and use it in GitHub Desktop.
<template>
<div>
<div class="speed-dial-modal-layer" v-if="isOpen"></div>
<div class="speed-dial">
<div
:class="['speed-dial-action', toggleClass, {'hide': isHideAction}]"
v-for="(action, idx) in actions"
:key="idx"
@click="onClickAction(action)"
>
<span
v-show="action.label && action.label.length > 0"
class="speed-dial-action-label"
>
{{action.label}}
</span>
<span
class="speed-dial-action-icon"
:style="{
'background-color': action.bgColor,
'color': action.iconColor
}"
>
<font-awesome-icon :icon="action.icon" />
</span>
</div>
<div
:class="['speed-dial-toggle', toggleClass]"
@click="toggleDial"
>
<span>
<font-awesome-icon icon="plus" />
</span>
</div>
</div>
</div>
</template>
<script>
export default {
name: "SpeedDial",
props: {
actions: {
type: Array,
require: true,
}
},
data() {
return {
isOpen: false,
isHideAction: true,
toggleClass: '',
}
},
methods: {
toggleDial() {
console.log('toggleDial, isOpen=%o', this.isOpen);
this.isOpen = !this.isOpen;
if (this.isOpen) {
this.toggleClass = 'opened';
this.isHideAction = false;
} else {
this.toggleClass = 'closed';
const vm = this;
setTimeout(() => {
if (vm.toggleClass === 'closed') {
vm.isHideAction = true;
}
}, 500);
}
},
onClickAction(action) {
console.log('onClickAction, action=%o', action);
this.toggleDial();
action.onClick();
}
}
}
</script>
<style scoped>
.hide { display: none; }
.speed-dial-modal-layer {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100vh;
z-index: 9999;
background-color: black;
opacity: 0.5;
}
.speed-dial {
position: fixed;
right: 0;
bottom: 0;
margin-right: 20px;
margin-bottom: 10px;
z-index: 10000;
}
.speed-dial-toggle {
text-align: center;
width: 60px;
height: 60px;
line-height: 60px;
background-color: #17a2b8;
color: white;
border-radius: 50%;
opacity: 0.8;
margin-bottom: 10px;
font-size: x-large;
filter: drop-shadow(4px 4px 4px rgba(0,0,0,0.4));
float: right;
}
.speed-dial-action {
text-align: right;
}
.speed-dial-action-icon {
display: inline-block;
text-align: center;
width: 50px;
height: 50px;
line-height: 50px;
background-color: #17a2b8;
color: white;
border-radius: 50%;
opacity: 0;
margin: 0 5px 10px 0;
font-size: large;
filter: drop-shadow(4px 4px 4px rgba(0,0,0,0.4));
}
.speed-dial-action-label {
margin-right: 10px;
color: white;
font-weight: bold;
filter: drop-shadow(4px 4px 4px rgba(0,0,0,0.4));
}
/* animation */
.speed-dial-action.opened .speed-dial-action-icon {
animation: icon-fade-in 0.3s linear;
animation-fill-mode: forwards;
}
.speed-dial-action.closed .speed-dial-action-icon {
animation: icon-fade-out 0.3s linear;
animation-fill-mode: forwards;
}
.speed-dial-action.opened .speed-dial-action-label {
animation: label-fade-in 0.3s linear;
animation-fill-mode: forwards;
}
.speed-dial-action.closed .speed-dial-action-label {
animation: label-fade-out 0.3s linear;
animation-fill-mode: forwards;
}
.speed-dial-toggle.opened {
animation: toggle-open 0.3s linear;
animation-fill-mode: forwards;
}
.speed-dial-toggle.toggle-closed {
animation: toggle-close 0.3s linear;
animation-fill-mode: forwards;
}
@keyframes icon-fade-out {
from {opacity: 1; transform: rotateZ(0); visibility: visible;}
to {opacity: 0; transform: rotateZ(0.25turn); visibility: hidden;}
}
@keyframes icon-fade-in {
from {opacity: 0; transform: rotateZ(0.25turn); visibility: hidden;}
to {opacity: 1; transform: rotateZ(0); visibility: visible;}
}
@keyframes label-fade-out {
from {opacity: 1; visibility: visible;}
to {opacity: 0; visibility: hidden;}
}
@keyframes label-fade-in {
from {opacity: 0; visibility: hidden;}
to {opacity: 1; visibility: visible;}
}
@keyframes toggle-close {
from {transform: rotateZ(-0.125turn);}
to {transform: rotateZ(0);}
}
@keyframes toggle-open {
from {transform: rotateZ(0);}
to {transform: rotateZ(-0.125turn);}
}
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment