1404/10/28-base
This commit is contained in:
@@ -0,0 +1,158 @@
|
||||
<template>
|
||||
<div
|
||||
:style="findPositionStyle(props.selfIndex)"
|
||||
class="card relative"
|
||||
@click="localValue = props.selfIndex"
|
||||
>
|
||||
<div class="p-3 flex flex-col items-center">
|
||||
<div class="flex justify-between w-full">
|
||||
<div class="text-white font-bold text-lg w-full">{{ props.title }}</div>
|
||||
<div
|
||||
class="text-white px-2 flex justify-center items-center rounded-lg w-5rem"
|
||||
:class="active ? 'bg-green-600' : 'bg-red-600'"
|
||||
>
|
||||
{{ active ? 'فعال' : 'غیر فعال' }}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="props.cardNumber"
|
||||
class="mt-[1.5vh] text-white w-full text-center text-xl font-bold"
|
||||
dir="ltr"
|
||||
>
|
||||
{{ useCardNumber(props.cardNumber) }}
|
||||
</div>
|
||||
<div v-if="props.shaba" class="mt-3 text-white text-lg">
|
||||
{{ useShabaNumber(props.shaba) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue'
|
||||
import { useCardNumber, useShabaNumber } from '@/utils/useCardNumber'
|
||||
|
||||
interface Prop {
|
||||
sliderIndex: number
|
||||
selfIndex: number
|
||||
title?: string
|
||||
cardNumber?: string
|
||||
shaba?: string
|
||||
color?: string
|
||||
active?: boolean
|
||||
}
|
||||
|
||||
const localValue = computed({
|
||||
get() {
|
||||
return props.sliderIndex
|
||||
},
|
||||
|
||||
set(value) {
|
||||
emits('update:sliderIndex', value)
|
||||
}
|
||||
})
|
||||
|
||||
const props = defineProps<Prop>()
|
||||
const emits = defineEmits(['update:sliderIndex'])
|
||||
|
||||
function findPositionStyle(pos: number) {
|
||||
// console.log(localValue.value)
|
||||
// console.log(pos,index)
|
||||
let debug
|
||||
if (pos === props.sliderIndex) {
|
||||
debug = `width: 100%; z-index: 100; opacity: 1;/* margin-top: -160px;*/ top: 20%; position: absolute; background-color: ${props.color};`
|
||||
} /*if (pos > index.value)*/ else {
|
||||
// debug = `w-[${100 - Math.abs(index.value-pos) * 2}%] z-${100 - Math.abs(index.value-pos)}`
|
||||
debug = `width: ${100 - Math.abs(props.sliderIndex - pos) * 10}%;
|
||||
z-index: ${100 - Math.abs(props.sliderIndex - pos)};
|
||||
position: absolute;
|
||||
top : ${
|
||||
pos > props.sliderIndex
|
||||
? checkTopLimit(topDetail(true, pos) as number)
|
||||
? 100
|
||||
: 20 +
|
||||
Math.abs((props.sliderIndex - pos) * (18 - Math.abs((props.sliderIndex - pos) * 4)))
|
||||
: checkTopLimit(topDetail(false, pos) as number)
|
||||
? 0
|
||||
: 20 - Math.abs((props.sliderIndex - pos) * (18 - Math.abs((props.sliderIndex - pos) * 4)))
|
||||
}%;
|
||||
background-color: ${props.color};`
|
||||
}
|
||||
console.log(debug, topDetail(true, pos))
|
||||
return debug
|
||||
}
|
||||
|
||||
/*
|
||||
function findPositionStyle(pos: number) {
|
||||
// console.log(localValue.value)
|
||||
// console.log(pos,index)
|
||||
let debug
|
||||
if (pos === props.sliderIndex) {
|
||||
debug = `width: 100%; z-index: 100; opacity: 1;/!* margin-top: -160px;*!/ top: 20%; position: absolute; background-color: ${props.color};`
|
||||
} else /!*if (pos > index.value)*!/{
|
||||
// debug = `w-[${100 - Math.abs(index.value-pos) * 2}%] z-${100 - Math.abs(index.value-pos)}`
|
||||
debug = `width: ${100 - Math.abs(props.sliderIndex - pos) * 10}%;
|
||||
z-index: ${100 - Math.abs(props.sliderIndex - pos)};
|
||||
/!*
|
||||
opacity: ${1 - Math.abs((props.sliderIndex - pos) * 15) / 100};
|
||||
*!/
|
||||
/!*
|
||||
margin-top: ${-160 - Math.abs((props.sliderIndex - pos) * 15)}px;
|
||||
*!/
|
||||
position: absolute;
|
||||
top : ${pos > props.sliderIndex ?
|
||||
checkTopLimit(topDetail(true, pos) as number) ? 100 :
|
||||
(20 + Math.abs((props.sliderIndex - pos) * (18 - (Math.abs((props.sliderIndex - pos) * 4))))) :
|
||||
checkTopLimit(topDetail(false, pos) as number) ? 0 :
|
||||
(20 - Math.abs((props.sliderIndex - pos) * (18 - (Math.abs((props.sliderIndex - pos) * 4)))))}%;
|
||||
background-color: ${props.color};`
|
||||
}
|
||||
console.log(debug)
|
||||
return debug
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* /!*checkTopLimit(topDetail(true, pos) as number) ? 100 :*!/ topDetail(true, pos) :
|
||||
* /!*checkTopLimit(topDetail(false, pos) as number) ? 0 :*!/ topDetail(false, pos)
|
||||
*/
|
||||
|
||||
function topDetail(isAfterIndex: boolean, pos: number) {
|
||||
/* console.log((20 - Math.abs((props.sliderIndex - pos) * (24 - (Math.abs((props.sliderIndex - pos) * 4))))), pos)
|
||||
console.log(Math.abs((props.sliderIndex - pos)) * (24 - (Math.abs((props.sliderIndex - pos) * 4))))*/
|
||||
console.log(
|
||||
20 - Math.abs((props.sliderIndex - pos) * (24 - Math.abs((props.sliderIndex - pos) * 4)))
|
||||
)
|
||||
/* if (isAfterIndex) console.log(20 + Math.abs(props.sliderIndex - pos))
|
||||
else console.log(20 - Math.abs(props.sliderIndex - pos))*/
|
||||
if (isAfterIndex)
|
||||
return 20 + Math.abs((props.sliderIndex - pos) * (18 - Math.abs((props.sliderIndex - pos) * 4)))
|
||||
else
|
||||
return 20 - Math.abs((props.sliderIndex - pos) * (18 - Math.abs((props.sliderIndex - pos) * 4)))
|
||||
}
|
||||
|
||||
/*
|
||||
function topDetail(isAfterIndex: boolean, pos: number) {
|
||||
console.log(pos, isAfterIndex, (20 + Math.abs((props.sliderIndex - pos) * (24 - (Math.abs((props.sliderIndex - pos) * 4))))))
|
||||
if (isAfterIndex) return (20 + Math.abs((props.sliderIndex - pos) * (24 - (Math.abs((props.sliderIndex - pos) * 4)))))
|
||||
else return (20 - Math.abs((props.sliderIndex - pos) * (24 - (Math.abs((props.sliderIndex - pos) * 4))))) < 0 //12*64
|
||||
}
|
||||
*/
|
||||
|
||||
function checkTopLimit(val: number) {
|
||||
return val > 100 || val < 0
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="sass" scoped>
|
||||
|
||||
.card
|
||||
height: 22vh
|
||||
width: 100%
|
||||
align-self: center
|
||||
border-radius: 24px
|
||||
transition: .5s
|
||||
|
||||
.card:first-child
|
||||
margin-top: 0 !important
|
||||
</style>
|
||||
@@ -0,0 +1,162 @@
|
||||
<template lang="pug">
|
||||
.container
|
||||
.slider
|
||||
.slide(data-slide='1' style="background-color: green")
|
||||
.slide(data-slide='2' style="background-color: red")
|
||||
.slide(data-slide='3' style="background-color: orange")
|
||||
.slide.slide--active(data-slide='4' style="background-color: blue")
|
||||
.slide(data-slide='5' style="background-color: violet")
|
||||
.slide(data-slide='5' style="background-color: primary")
|
||||
.slide(data-slide='5' style="background-color: pink")
|
||||
.slide(data-slide='5' style="background-color: teal")
|
||||
.controls
|
||||
#back Back
|
||||
#forvard Forvard
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
renderSlider('.slider');
|
||||
});
|
||||
|
||||
const nextSlide = () => {
|
||||
let activeSlide = document.querySelector('.slide--active');
|
||||
let nextSlide = activeSlide.nextElementSibling;
|
||||
if (nextSlide) {
|
||||
activeSlide.classList.remove('slide--active');
|
||||
nextSlide.classList.remove('next');
|
||||
nextSlide.classList.add('slide--active');
|
||||
renderSlides();
|
||||
renderBtns();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const renderBtns = () => {
|
||||
let nextBtn = document.querySelector('#forvard');
|
||||
let prevBtn = document.querySelector('#back');
|
||||
|
||||
let activeSlide = document.querySelector('.slide--active');
|
||||
let prevSlide = activeSlide.previousElementSibling;
|
||||
!prevSlide ? prevBtn.classList.add('disabled')
|
||||
: prevBtn.classList.remove('disabled');
|
||||
|
||||
let nextSlide = activeSlide.nextElementSibling;
|
||||
!nextSlide ? nextBtn.classList.add('disabled')
|
||||
: nextBtn.classList.remove('disabled');
|
||||
}
|
||||
|
||||
const prevSlide = () => {
|
||||
let activeSlide = document.querySelector('.slide--active');
|
||||
let prevSlide = activeSlide.previousElementSibling;
|
||||
if (prevSlide) {
|
||||
activeSlide.classList.remove('slide--active');
|
||||
prevSlide.classList.remove('prev');
|
||||
prevSlide.classList.add('slide--active');
|
||||
renderSlides();
|
||||
renderBtns();
|
||||
}
|
||||
}
|
||||
|
||||
const renderSlides = () => {
|
||||
let slides = document.querySelectorAll('.slide');
|
||||
if (!slides) {
|
||||
return;
|
||||
}
|
||||
let activeSlide = document.querySelector('.slide--active');
|
||||
if (!activeSlide) {
|
||||
activeSlide = slides.item(0);
|
||||
activeSlide.classList.add('slide--active');
|
||||
}
|
||||
[].forEach.call(slides, function (slide) {
|
||||
slide.classList.remove('prev', 'next')
|
||||
});
|
||||
|
||||
let prevSlide = activeSlide.previousElementSibling;
|
||||
prevSlide && prevSlide.classList.add('prev');
|
||||
|
||||
let nextSlide = activeSlide.nextElementSibling;
|
||||
nextSlide && nextSlide.classList.add('next');
|
||||
|
||||
}
|
||||
|
||||
const renderSlider = (element) => {
|
||||
const slider = document.querySelector(element);
|
||||
if (slider) {
|
||||
let nextButton = document.querySelector("#forvard");
|
||||
nextButton.addEventListener('click', function () {
|
||||
nextSlide();
|
||||
})
|
||||
|
||||
let prevButton = document.querySelector("#back");
|
||||
prevButton.addEventListener('click', function () {
|
||||
prevSlide();
|
||||
})
|
||||
renderSlides();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="sass" scoped>
|
||||
.container
|
||||
display: flex
|
||||
flex-flow: column
|
||||
justify-content: center
|
||||
margin: 50px auto 0
|
||||
width: 500px
|
||||
height: 300px
|
||||
|
||||
.controls
|
||||
display: flex
|
||||
justify-content: center
|
||||
|
||||
div
|
||||
padding: 12px 14px
|
||||
cursor: pointer
|
||||
border: 1px solid #fff
|
||||
color: #fff
|
||||
font-size: 16px
|
||||
font-weight: bold
|
||||
margin: 0 5px
|
||||
border-radius: 10px
|
||||
|
||||
&.disabled
|
||||
opacity: 0
|
||||
cursor: default
|
||||
|
||||
|
||||
.slider
|
||||
position: relative
|
||||
width: 100%
|
||||
height: 100%
|
||||
|
||||
.slide
|
||||
position: absolute
|
||||
top: 25%
|
||||
left: 10%
|
||||
width: 80%
|
||||
height: 50%
|
||||
background-color: red
|
||||
border: 1px solid #fff
|
||||
border-radius: 15px
|
||||
opacity: 0
|
||||
transition: all 0.7s ease-out
|
||||
|
||||
&--active
|
||||
opacity: 1
|
||||
z-index: 9
|
||||
|
||||
.prev,
|
||||
.next
|
||||
opacity: .3
|
||||
|
||||
|
||||
.prev
|
||||
transform: translate(0, -30%) scale(0.8)
|
||||
|
||||
.next
|
||||
transform: translate(0, 30%) scale(0.8)
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,259 @@
|
||||
<template>
|
||||
|
||||
<div ref="container" class=" h-[38vh] flex items-center">
|
||||
<div ref="el" class="w-full flex flex-col relative h-full test">
|
||||
<CardItem v-for="(item,i) in props?.items" :key="i" v-model:sliderIndex="index" :card-number="item?.cart_number"
|
||||
:color="colors[i%3]"
|
||||
:self-index="i" :shaba="item?.shaba_number" :title="item?.bank_name" :active="item.sts === 2"/>
|
||||
<div class="absolute bottom-15vh right-0 left-0 z-100 flex justify-center items-center opacity-70">
|
||||
<div class="flex gap-1 bg-gray-500 px-2 py-1 rounded-lg">
|
||||
<Transition name="slide-up" mode="out-in" v-for="i in items.length" :key="i">
|
||||
<div v-if="i - 1 === index" class="w-2 h-2 rounded-full bg-primary"/>
|
||||
<div v-else class="w-2 h-2 rounded-full bg-white"/>
|
||||
</Transition>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, onMounted, ref, watch } from 'vue'
|
||||
// import {usePointerSwipe} from '@vueuse/core'
|
||||
// import type {UseSwipeDirection} from '@vueuse/core'
|
||||
// import type { UseSwipeDirection } from '@vueuse/core'
|
||||
import { useSwipe } from '@vueuse/core'
|
||||
import CardItem from './CardItem.vue'
|
||||
import type { Card } from '@/models/wallet'
|
||||
|
||||
const el = ref(null)
|
||||
const container = ref<HTMLElement | null>(null)
|
||||
|
||||
interface Prop {
|
||||
items: Array<Card>
|
||||
id: number | string
|
||||
}
|
||||
|
||||
const props = defineProps<Prop>()
|
||||
const emits = defineEmits(['update:id'])
|
||||
|
||||
const localValue = computed({
|
||||
get() {
|
||||
return props.id
|
||||
},
|
||||
|
||||
set(value) {
|
||||
emits('update:id', value)
|
||||
}
|
||||
})
|
||||
// const decideSwip = ref<boolean>(false)
|
||||
|
||||
const { direction, isSwiping, lengthX, lengthY } = useSwipe(el/*, {
|
||||
onSwipeStart(){
|
||||
console.log('salam')
|
||||
},
|
||||
onSwipe(e: PointerEvent, direction: UseSwipeDirection) {
|
||||
console.log('container',direction)
|
||||
if (!decideSwip.value){
|
||||
if (direction === 'up') {
|
||||
index.value++
|
||||
} else if (direction === 'down') {
|
||||
index.value--
|
||||
}
|
||||
decideSwip.value = true
|
||||
}
|
||||
},
|
||||
onSwipeEnd(e: PointerEvent){
|
||||
console.log('container1')
|
||||
|
||||
decideSwip.value = false
|
||||
}
|
||||
}*/)
|
||||
|
||||
function getRandomColor() {
|
||||
var letters = '0123456789ABCDEF'
|
||||
var color = '#'
|
||||
for (var i = 0; i < 6; i++) {
|
||||
color += letters[Math.floor(Math.random() * 16)]
|
||||
}
|
||||
return color
|
||||
}
|
||||
|
||||
const colors = ['#4B84EB', '#889BCD', '#C9A68D']
|
||||
|
||||
watch(isSwiping, () => {
|
||||
// console.log(direction.value)
|
||||
if (isSwiping.value) {
|
||||
// console.log('salam')
|
||||
if (direction.value === 'up' && props.items.length - 1 > index.value) {
|
||||
index.value++
|
||||
} else if (direction.value === 'down' && index.value > 0) {
|
||||
index.value--
|
||||
}
|
||||
// console.log(index.value)
|
||||
}
|
||||
})
|
||||
|
||||
const index = ref<number>(props.items.length - 1)
|
||||
onMounted(()=> localValue.value = props.items[index.value]?.id)
|
||||
watch(index, (n: number)=> {
|
||||
console.log(n)
|
||||
localValue.value = props.items[n]?.id
|
||||
})
|
||||
|
||||
/*
|
||||
const items = [
|
||||
{
|
||||
title: 'بانک ملی',
|
||||
cardNumber: 6219861918606103,
|
||||
shaba: 'IR590560611828005106225701',
|
||||
color: getRandomColor()
|
||||
},
|
||||
{
|
||||
title: 'بانک ملی',
|
||||
cardNumber: 6219861918606103,
|
||||
shaba: 'IR590560611828005106225701',
|
||||
color: getRandomColor()
|
||||
},
|
||||
{
|
||||
title: 'بانک ملت',
|
||||
cardNumber: 6219861918606103,
|
||||
shaba: 'IR590560611828005106225701',
|
||||
color: getRandomColor()
|
||||
},
|
||||
{
|
||||
title: 'بانک سامان',
|
||||
cardNumber: 6219861918606103,
|
||||
shaba: 'IR590560611828005106225701',
|
||||
color: getRandomColor()
|
||||
},
|
||||
{
|
||||
title: 'بانک پاسارگاد',
|
||||
cardNumber: 6219861918606103,
|
||||
shaba: 'IR590560611828005106225701',
|
||||
color: getRandomColor()
|
||||
},
|
||||
{
|
||||
title: 'بانک صادرات',
|
||||
cardNumber: 6219861918606103,
|
||||
shaba: 'IR590560611828005106225701',
|
||||
color: getRandomColor()
|
||||
},
|
||||
{
|
||||
title: 'بانک ملی',
|
||||
cardNumber: 6219861918606103,
|
||||
shaba: 'IR590560611828005106225701',
|
||||
color: getRandomColor()
|
||||
},
|
||||
{
|
||||
title: 'بانک ملت',
|
||||
cardNumber: 6219861918606103,
|
||||
shaba: 'IR590560611828005106225701',
|
||||
color: getRandomColor()
|
||||
},
|
||||
{
|
||||
title: 'بانک سامان',
|
||||
cardNumber: 6219861918606103,
|
||||
shaba: 'IR590560611828005106225701',
|
||||
color: getRandomColor()
|
||||
},
|
||||
{
|
||||
title: 'بانک پاسارگاد',
|
||||
cardNumber: 6219861918606103,
|
||||
shaba: 'IR590560611828005106225701',
|
||||
color: getRandomColor()
|
||||
},
|
||||
]
|
||||
*/
|
||||
|
||||
// const indexCss = computed(()=> index.value)
|
||||
|
||||
// watch(index,()=>{
|
||||
// key++
|
||||
// console.log(key)
|
||||
// })
|
||||
|
||||
// let key = 0
|
||||
/*function findPosition(pos: number) {
|
||||
// console.log(pos,index)
|
||||
let debug
|
||||
if (pos === index.value){
|
||||
debug = 'w-full z-100'
|
||||
}
|
||||
else /!*if (pos > index.value)*!/{
|
||||
debug = `w-[${100 - Math.abs(index.value-pos) * 2}%] z-${100 - Math.abs(index.value-pos)}`
|
||||
}
|
||||
console.log(debug)
|
||||
return debug
|
||||
}*/
|
||||
/*
|
||||
function mouseUp() {
|
||||
index.value--
|
||||
}
|
||||
|
||||
function mouseDown() {
|
||||
console.log('salam')
|
||||
index.value++
|
||||
}
|
||||
*/
|
||||
|
||||
/*function findPositionStyle(pos: number) {
|
||||
// console.log(pos,index)
|
||||
let debug
|
||||
if (pos === index.value) {
|
||||
debug = 'width: 100; z-index: 100; opacity: 1; margin-top: -200px;'
|
||||
} else /!*if (pos > index.value)*!/{
|
||||
// debug = `w-[${100 - Math.abs(index.value-pos) * 2}%] z-${100 - Math.abs(index.value-pos)}`
|
||||
debug = `width: ${100 - Math.abs(index.value - pos) * 3}%;
|
||||
z-index: ${100 - Math.abs(index.value - pos)};
|
||||
opacity: ${1 - Math.abs((index.value - pos) * 15) / 100};
|
||||
margin-top: ${-200 - Math.abs((index.value - pos) * 4)}px;`
|
||||
}
|
||||
// console.log(debug)
|
||||
return debug
|
||||
}*/
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.slide-up-enter-active,
|
||||
.slide-up-leave-active {
|
||||
transition: all 0.25s ease-out;
|
||||
}
|
||||
|
||||
.slide-up-enter-from {
|
||||
opacity: 0;
|
||||
transform: translateY(3px);
|
||||
}
|
||||
|
||||
.slide-up-leave-to {
|
||||
opacity: 0;
|
||||
transform: translateY(-3px);
|
||||
}
|
||||
//.test .card:first-child
|
||||
// margin-top: 0 !important
|
||||
|
||||
//.card
|
||||
// height: 215px
|
||||
// width: 100%
|
||||
// align-self: center
|
||||
// border-radius: 24px
|
||||
// transition: .5s
|
||||
//
|
||||
//.card:first-child
|
||||
// margin-top: 0 !important
|
||||
|
||||
//$total-items: 30
|
||||
|
||||
//@for $i from 1 through $total-items
|
||||
// .card:nth-child(#{$i})
|
||||
// @if($i > v-bind(indexCss))
|
||||
// width: calc(percentage(100 - ($i * 4)) / 100)
|
||||
// @if($i == v-bind(indexCss))
|
||||
// width: 100%
|
||||
// @if($i < v-bind(indexCss))
|
||||
// width: calc(percentage(100 - ($i * 4)) / 100)
|
||||
|
||||
//.animate > div:nth-child(#{$i})
|
||||
// animation-delay: .08s * $i
|
||||
|
||||
</style>
|
||||
Reference in New Issue
Block a user