Delta Indicators ​
IntermediateCustom swipe indicators with dynamic opacity based on drag distance.
Demo ​
Source
vue
<script lang="ts" setup>
import { ref } from 'vue'
import { FlashCards } from 'vue3-flashcards'
import LanguageCard from './LanguageCard.vue'
import SwipeOverlay from './SwipeOverlay.vue'
interface WordCard {
word: string
translation: string
}
const cards = ref<WordCard[]>([
{ word: 'Hello', translation: 'Bonjour' },
{ word: 'World', translation: 'Monde' },
{ word: 'Thank you', translation: 'Merci' },
{ word: 'Goodbye', translation: 'Au revoir' },
{ word: 'Please', translation: 'S\'il vous plaît' },
])
</script>
<template>
<div class="w-full flex justify-center items-center py-20">
<div class="max-w-sm w-full">
<FlashCards :items="cards">
<template #default="{ item }">
<LanguageCard :item="item" />
</template>
<template #approve="{ delta }">
<SwipeOverlay :delta="Math.abs(delta)" type="approve" />
</template>
<template #reject="{ delta }">
<SwipeOverlay :delta="Math.abs(delta)" type="reject" />
</template>
</FlashCards>
</div>
</div>
</template>vue
<script setup lang="ts">
interface WordCard {
word: string
translation: string
}
defineProps<{
item: WordCard
}>()
</script>
<template>
<div class="relative overflow-hidden rounded-2xl shadow-xl h-48 bg-gradient-to-br from-indigo-500 to-purple-600 text-white transform transition-all duration-300">
<!-- Language indicator -->
<div class="absolute top-4 left-4 px-3 py-1 bg-white/20 rounded-full text-sm font-medium">
EN → FR
</div>
<!-- Book icon -->
<div class="absolute top-4 right-4 text-white/80">
📚
</div>
<!-- Content -->
<div class="p-6 h-full flex flex-col justify-center items-center gap-3 text-center">
<div class="text-3xl font-bold mb-2">
{{ item.word }}
</div>
<div class="text-xl text-indigo-100">
{{ item.translation }}
</div>
</div>
<!-- Swipe indicators -->
<div class="absolute bottom-4 left-1/2 transform -translate-x-1/2 flex gap-2">
<div class="w-2 h-2 bg-white/40 rounded-full" />
<div class="w-2 h-2 bg-white/60 rounded-full" />
<div class="w-2 h-2 bg-white rounded-full" />
</div>
</div>
</template>vue
<script setup lang="ts">
defineProps<{
delta: number
type: 'approve' | 'reject'
}>()
</script>
<template>
<div
v-if="type === 'approve'"
class="absolute inset-0 flex items-center justify-center bg-emerald-500/90 rounded-2xl font-bold text-2xl text-white backdrop-blur-sm"
:style="{ opacity: delta }"
>
<div class="text-center">
<div class="text-4xl mb-2">
✅
</div>
<div>I know this!</div>
</div>
</div>
<div
v-else
class="absolute inset-0 flex items-center justify-center bg-red-500/90 rounded-2xl font-bold text-2xl text-white backdrop-blur-sm"
:style="{ opacity: delta }"
>
<div class="text-center">
<div class="text-4xl mb-2">
📚
</div>
<div>Need to review</div>
</div>
</div>
</template>Key Concepts ​
- delta prop: Value from -1 to 1 indicating drag progress
- Use for: Progressive opacity, scale, or color changes
- Calculation:
opacity = Math.abs(delta)for fade-in effect - Creates responsive visual feedback during drag