добиться эффекта
-
Наложение поворота
-
Сковорода
Некоторое время назад я сделал гибридное приложение. Дизайн пользовательского интерфейса требует, чтобы отображение определенной страницы достигало эффекта скользящей карусели. Выбранная карточка контента отображается в центре, а предыдущая карточка контента и следующий контент отображаются в конце обратная сторона выбранной карты в два раза больше.и с размытием по Гауссу и т.д. . Самое обидное, что эффект скольжения надо крутить и накладывать один за другим. (Осень!
В то время я использовал страницу, реализованную vue-cli-3 + ant-design-vue.Я обнаружил, что есть готовые компоненты Carousel, доступные в ant-design-vue.Из-за срочного графика я использовал это для реализовать первую версию временно.Специальные эффекты не имеют других наворотов на дисплее. Приняв первую версию, я обнаружил, что в ant-design-vue действительно много ям. . Карусель также очень негладкая на мобильной стороне. Это всегда особенно плохой опыт. На последнем дыхании все стили были написаны мной, все компоненты инкапсулированы мной, а ant-design-vue полностью удален из проекта.
Карусельная карта думает о хорошей штуке Swiper, и теперь есть vue-версия, но нет специальной документации vue-версии, и относительно мало элементов можно найти. В отчаянии я прогрыз документ Swiper4, проделал яростную операцию и нашел лючок. Потребности удовлетворены. Я просто разобрался, написал простенькое демо и записал, если оно может вам помочь, то будет лучше всего~
1. Сначала представьте Vue-Awesome-Swiper
Есть два способа представить Vue-Awesome-Swiper: один — это глобальное введение, а другой — введение компонентов. Если вам нужно использовать эту вещь только в одном месте в вашем проекте, вы можете импортировать ее на страницу, которую вы используете.Если вам это нужно в нескольких местах, то импортируйте ее глобально.
- Импортировать глобально:
// main.js
import VueAwesomeSwiper from 'vue-awesome-swiper'
import 'swiper/dist/css/swiper.css'
Vue.use(VueAwesomeSwiper, /* { default global options } */)
- Представлено в компоненте:
// xxx.vue
<script>
import 'swiper/dist/css/swiper.css'
import { swiper, swiperSlide } from 'vue-awesome-swiper'
export default {
components: {
swiper,
swiperSlide
}
}
</script>
2. Используйте на странице
<template>
<div class="swiper-content">
<swiper ref="mySwiper" :options="swiperOption" class="show-swiper">
<template v-for="(item, index) in list">
<swiper-slide :key="index">
<div class="swiper-item">
<span>{{ item }}</span>
</div>
</swiper-slide>
</template>
</swiper>
</div>
</template>
js-часть
- Наложение поворота
<script>
import { mapState } from 'vuex'
import store from '@/store'
export default {
data() {
return {
list: [1, 2, 3, 4, 5, 6],
swiperOption: {
// 设置slider容器能够同时显示的slides数量,默认为1, 'auto'则自动根据slides的宽度来设定数量
slidesPerView: 'auto',
/*
* 开启这个参数来计算每个slide的progress(进度、进程)
* 对于slide的progress属性,活动的那个为0,其他的依次减1
*/
watchSlidesProgress: true,
// 默认active slide居左,设置为true后居中
centeredSlides: true,
// 当你创建一个Swiper实例时是否立即初始化,这里我们手动初始化
init: false,
longSwipesRatio: 0.1,
touchReleaseOnEdges: true,
observer: true, // 修改swiper自己或子元素时,自动初始化swiper
observeParents: true, // 修改swiper的父元素时,自动初始化swiper
on: {
progress: function() {
for (let i = 0; i < this.slides.length; i++) {
const slide = this.slides.eq(i) // 指定匹配元素集缩减值
const slideProgress = this.slides[i].progress // 当前元素集的progress值
let modify = 0 // 偏移权重
if (parseInt(Math.abs(slideProgress)) > 0) {
modify = Math.abs(slideProgress) * 0.2 // 不一定要0.2,可自行调整
}
const translate = slideProgress * modify * 500 + 'px' // 500是swiper-slide的宽度
const scale = 1 - Math.abs(slideProgress) / 5 // 缩放权重值,随着progress由中向两边依次递减,可自行调整
const zIndex = 99 - Math.abs(Math.round(10 * slideProgress))
slide.transform(`translateX(${translate}) scale(${scale})`)
slide.css('zIndex', zIndex)
slide.css('opacity', 1) // 是否可见
if (parseInt(Math.abs(slideProgress)) > 1) { // 设置了只有选中的元素以及他两遍的显示,其他隐藏
slide.css('opacity', 0)
}
}
},
slideChange: function() {
store.commit('SET_ACTIVE_INDEX', this.activeIndex)
}
}
}
}
},
computed: {
swiper() {
return this.$refs.mySwiper.swiper
},
...mapState({
activeItemIndex: state => state.activeIndex
})
},
mounted() {
this.initSwiper()
},
methods: {
initSwiper() {
this.$nextTick(async() => {
await this.swiper.init() // 现在才初始化
await this.swiper.slideTo(this.activeItemIndex)
})
}
}
}
</script>
- Сковорода
<script>
import { mapState } from 'vuex'
import store from '@/store'
export default {
data() {
return {
list: [1, 2, 3, 4, 5, 6],
swiperOption: {
slidesPerView: 'auto',
watchSlidesProgress: true,
// 设定slide与左边框的预设偏移量(单位px)
slidesOffsetBefore: 37,
// 设置slide之间的距离(单位px)
spaceBetween: 17,
centeredSlides: true,
init: false,
longSwipesRatio: 0.1,
touchReleaseOnEdges: true,
observer: true, // 修改swiper自己或子元素时,自动初始化swiper
observeParents: true, // 修改swiper的父元素时,自动初始化swiper
on: {
progress: function() {
for (let i = 0; i < this.slides.length; i++) {
const slide = this.slides.eq(i)
const slideProgress = this.slides[i].progress
const scale = 1 - Math.abs(slideProgress) / 5 // 缩放权重值,随着progress由中向两边依次递减,可自行调整
slide.transform(`scale3d(${scale}, ${scale}, 1)`)
}
},
slideChange: function() {
store.commit('SET_ACTIVE_INDEX', this.activeIndex)
}
}
}
}
},
computed: {
swiper() {
return this.$refs.mySwiper.swiper
},
...mapState({
activeItemIndex: state => state.activeIndex
})
},
mounted() {
this.initSwiper()
},
methods: {
initSwiper() {
this.$nextTick(async() => {
await this.swiper.init() // 现在才初始化
await this.swiper.slideTo(this.activeItemIndex)
})
}
}
}
</script>
В параметрах конфигурации я установил для init значение false, я хочу использовать данные интерфейса после монтирования проекта.this.swiper.init()
Чтобы инициализировать компонент карусели, а затем я сохраняю индекс элемента активации в vuex, чтобы каждый раз, когда я возвращаюсь на эту страницу с другой страницы, я мог использоватьthis.swiper.slideTo(this.activeItemIndex)
Чтобы контролировать, на какую карточку контента я хочу настроить таргетинг в первую очередь.
3. Инициализация стиля
.swiper-content {
width: 100%;
height: 100%;
position: relative;
overflow: hidden;
margin: 0 auto;
padding: 50px 0;
.show-swiper {
width: 100%;
height: 100%;
top: 0;
left: 0;
.swiper-slide {
width: 500px;
// 表示所有属性都有动作效果,过度时间为0.4s,以慢速开始和结束的过渡效果
transition: all .4s cubic-bezier(.4, 0, .2, 1);
.swiper-item {
width: 100%;
height: 500px;
background: rgb(140, 172, 134);
border-radius: 6px;
color: orangered;
font-size: 24px;
line-height: 1.5;
border: 1px solid orangered;
}
}
}
}
потому чтоslidesPerView: 'auto'
, поэтому swiper-slide мы должны дать ему начальную ширину, чтобы он мог автоматически рассчитать ширину контейнера, а затем здесь я устанавливаю эффект анимацииtransition: all .4s cubic-bezier(.4, 0, .2, 1);
Вы можете вносить изменения в соответствии с вашими потребностями
Это, наверное, содержание, оно очень простое? Я опубликую адрес исходного кода и клонирую его для справки, если это необходимо.Я использую в проекте vue-cli3, который можно настроить под себя.