VUE实现大小缩放轮播图

news2024/12/22 23:00:16

效果图

<template>
    <view class="swiper-container" ref="root" @touchstart="onTouchStart" @touchend="onTouchEnd">
        <view @click="evtChangeIndex(index)" class="side" v-for="(item, index) in state.source" :key="index"
            :style="item.sty" :class="item.className">
            <img :src="item?.img" alt="">
        </view>
    </view>
</template>

<script>

import { ref, computed, reactive, watch, onMounted } from 'vue';

export default {
    props: {

        /**
         * 轮播数据来源
         */
        source: {
            type: Array,
            default: () => [
                { img: require('@/assets/imgs/test/1.png') },
                { img: require('@/assets/imgs/test/1.png') },
                { img: require('@/assets/imgs/test/1.png') },
                { img: require('@/assets/imgs/test/1.png') },
                { img: require('@/assets/imgs/test/1.png') },
            ],
        },
        /**
         * 初始激活的索引
         */
        initial: {
            type: Boolean,
            default: 0
        },
        /**
         * 自动播放时间
         */
        interval: {
            type: Number,
            default: 3500
        },

    },
    emits: ['update:active'],
    setup(props, { emit }) {

        /**
         * 轮播数据源
         */
        let source = props.source;

        /**
         * 轮播数据源长度差
         */
        let diff = source.length - 5;

        // 不足5个数据,补全
        if (diff < 0) {
            //缺几个补几个
            diff = Math.abs(diff);
            source.slice(0, diff).forEach(item => {
                source.push(item);
            })
        }

        /**
         * 处理每一项的样式
         * @param {*} initial 当前项 
         * @param {*} source  数据源
         */
        const computed = (initial, source) => {
            // 当前项的索引
            let len = source.length;

            //先处理中间值
            initial = initial < 0 ? 0 : (initial >= len ? len - 1 : initial);

            //5个项的temp
            let temp1 = initial - 2;
            let temp2 = initial - 1;
            let temp3 = initial;
            let temp4 = initial + 1;
            let temp5 = initial + 2;

            //处理边界值
            temp1 = temp1 < 0 ? len + temp1 : temp1;
            temp2 = temp2 < 0 ? len + temp2 : temp2;

            //超界行为
            temp4 = temp4 >= len ? temp4 - len : temp4;
            temp5 = temp5 >= len ? temp5 - len : temp5;

            //计算每一项样式
            return source.map((item, index) => {
                let transform = 'translate(-50%, -50%) scale(0.55)',
                    zIndex = 0,
                    className = 'side';

                switch (index) {
                    //中间的
                    case temp3:
                        zIndex = 3;
                        className = 'side active';
                        transform = 'translate(-50%, -50%) scale(1)';
                        break;
                    case temp1:
                        zIndex = 1;
                        className = 'side active';
                        transform = 'translate(-160%, -50%) scale(0.8)';
                        break;
                    case temp2:
                        zIndex = 2;
                        className = 'side active';
                        transform = 'translate(-110%, -50%) scale(0.9)';
                        break;
                    case temp4:
                        zIndex = 2;
                        className = 'side active';
                        transform = 'translate(10%, -50%) scale(0.9)';
                        break;
                    case temp5:
                        zIndex = 1;
                        className = 'side active';
                        transform = 'translate(60%, -50%) scale(0.8)';
                        break;
                }

                item.sty = {
                    zIndex,
                    transform
                }
                item.className = className;
                return item;
            })
        }

        source = computed(props.initial, source);

        /**
         * 构建响应式
         */
        const state = reactive({
            initial: props.initial,
            source
        })


        let autoTimer = null;

        /**
         * 监听激活数据变化
         */
        watch(() => state.initial, (initial, preInitial) => {
            state.source = computed(initial, state.source);
        })

        /**
         * 自动轮播
         */
        const autoPlay = () => {
            autoTimer = setInterval(() => {
                state.initial++;
                //边界处理
                if (state.initial >= state.source.length) {
                    state.initial = 0;
                }
            }, props.interval);
        }

        /**
     * 手势处理逻辑
     */
        let startX = 0;
        let endX = 0;
        const onTouchStart = (e) => {
            startX = e.touches[0].clientX;
            //手势关闭自动滚动
            stopAutoPlay();
        };
        const onTouchEnd = (e) => {
            endX = e.changedTouches[0].clientX;
            if (startX > endX + 50) {
                // 左滑
                change('right');
            } else if (startX < endX - 50) {
                // 右滑
                change('left');
            }
            //手势识别后重启
            autoPlay();
        };

        /**
         * 停止自动播放
         */
        const stopAutoPlay = () => {
            clearInterval(autoTimer);
        }

        let root = ref(null);

        //开启自动轮播
        onMounted(() => {
            //开启自动轮播
            autoPlay();
            let box = root.value;

            // box.onmouseenter = function () {
            //     clearInterval(autoPlay);
            // }
            // box.onmouseleave = function () {
            //     autoPlay();
            // }
        })

        /**
         * 切换
         * @param dir left:上一张,right:下一张
         */
        const change = (dir) => {
            if (dir == 'left') {
                state.initial--;
                if (state.initial < 0) {
                    state.initial = state.source.length - 1;
                }
            }
            if (dir == 'right') {
                state.initial++;
                //超出边界定向到0
                if (state.initial >= state.source.length) {
                    state.initial = 0;
                }
            }
        }


        /**
         * 轮播切换 具体值
         */
        const evtChangeIndex = (index) => {
            state.initial = index;
            //重启定时
            stopAutoPlay();
            autoPlay();
        }

        return {
            state,
            root,
            change,
            evtChangeIndex,
            onTouchStart,
            onTouchEnd
        }

    },
};
</script>

<style lang="scss">
.swiper-container {
    width: 360px;
    display: flex;
    height: 200px;
    justify-content: center;
    /* 水平方向居中 */
    align-items: center;
    /* 垂直方向居中 */
    position: relative;
    background: transparent;
    overflow: hidden;

    /* 隐藏超出部分 */
    .side {
        position: absolute;
        width: 35%;
        height: 200px;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%) scale(1);
        transition: 0.5s linear;
        border-radius: 3px;
        overflow: hidden;

        img {
            height: 100%;
            width: 100%;
        }
    }
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2109708.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AC访问规则--- 设备执行环境

两种设备执行环境&#xff1a; 1.支持使用应用提供商密钥签名的设备应用的设备执行环境。在这种情况下&#xff0c;设备应用&#xff08;即在应用容器中&#xff09;会提供应用提供商的证书。该证书由执行环境的应用安装程序进行验证。访问控制执行器将把此证书用作应用标识符&…

Python异步监控模块,让你的异步应用更智能!

在现代编程中&#xff0c;异步编程变得越来越流行。它让我们可以同时处理多个任务&#xff0c;提高效率。 然而&#xff0c;异步编程也带来了新的挑战&#xff0c;尤其是在调试和监控方面。 今天&#xff0c;我要向大家介绍一个Python异步监控模块—aiomonitor&#xff0c;它…

`GLIBCXX_3.4.29‘ not found,升级至libstdc++.so.6.0.29解决问题,欧拉服务器

背景&#xff1a;openGemini1.2升级为1.3&#xff0c;启动报错/usr/lib64/libstdc.so.6: version GLIBCXX_3.4.29’ not found &#xff0c;所以需要升级一下。 第一步&#xff1a; 执行命令&#xff1a; strings /usr/lib64/libstdc.so.6 | grep GLIBCXX先查看一下自己的GLIB…

06_TensorFlow2数学计算大揭秘:让AI也学会‘加减乘除’,笑料不断,干货满满!

1. 科学计算 Tensorflow2 重新组织了数学计算模块&#xff0c;其提供了数学计算、数值处理的全维度接口&#xff0c;方便了使用者对数据的处理。 2. tf.math 模块常用函数列表 Tensorflow 提供了丰富的数学计算函数&#xff0c;并将这些函数统一到了 tf.math 模块中&#xf…

一文讲清数字化转型规划业务架构、数据架构、技术架构、应用架构

什么是数字化转型的4A架构 数字化转型的4A架构规划是指企业在推进数字化进程中&#xff0c;通过构建业务架构&#xff08;Business Architecture&#xff09;、应用架构&#xff08;Application Architecture&#xff09;、数据架构&#xff08;Data Architecture&#xff09;…

记一次MES项目上线失败总结--数据库层面+代码层面优化方案

难熬三个夜晚&#xff01;&#xff01;&#xff01;按原计划将ERP的生产订单、排程单、牌卡计划、小包装、装箱单等生产数据通过接口的形式同步到MES系统&#xff0c;其中生产订单、排程单和小包装、装箱单的数据量相对较少&#xff0c;合计大概50w条左右的数据&#xff0c;同步…

2024年实体门店和企业怎么做短视频矩阵获客?为什么要做短视频矩阵?一文告诉你短视频矩阵源码系统搭建

短视频矩阵获客是一种基于多个短视频账号&#xff0c;通过不同职能划分和策略组合&#xff0c;实现更高效、更精准的客户获取方式。 一、短视频矩阵是什么&#xff1f; 短视频矩阵是指由多个短视频平台通过某种方式连接在一起&#xff0c;形成一个统一的短视频发布、分享和观…

TriforceAFL部署、使用与原理分析

文章目录 前言1、概述1.1、工作原理1.2、工作流程1.2.1、编译TriforceAFL1.2.2、编译TriforceLinuxSyscallFuzzer1.2.3、初始化资源1.2.3.1、种子初始化1.2.3.2、GuestOS初始化 1.2.4、afl-fuzz调度1.2.5、启动待Fuzz目标 2、安装与使用2.1、安装方法2.1.1、部署系统依赖组件2.…

fpga入门名词(1)

这是第一代FPGA ,在 FPGA&#xff08;现场可编程门阵列&#xff09;设计中&#xff0c;LCA&#xff08;逻辑单元阵列&#xff09;通常由几个关键组件构成&#xff0c;包括 IOB、CLB 和 Interconnect。以下是这些组件的简要说明&#xff1a; 1. IOB&#xff08;Input/Output B…

六款好用的企业防泄密软件推荐|文件防泄密软件哪个好

在当今信息化高速发展的时代&#xff0c;企业数据的安全与防泄密已成为每个企业不可忽视的重要议题。随着业务数据的不断增加和传输渠道的多样化&#xff0c;如何有效防止敏感信息泄露&#xff0c;成为企业管理者面临的一大挑战。幸运的是&#xff0c;市场上涌现出众多优秀的企…

6.1图的基本定义

1.有向图 2.无向图 3.完全图 无向完全图:任意两个顶点都存在边,n个顶点有n(n-1)/2条边 有向完全图:任意两个顶点间都存在方向相反的两条弧,有n(n-1)条边. 4.连通,连通图,连通分量--无向图 连通:顶点v到顶点w有路径存在 连通图:任意两点间都存在路径 连通分量/极大连通子图…

Kafka【十二】消费者拉取主题分区的分配策略

【1】消费者组、leader和follower 消费者想要拉取主题分区的数据&#xff0c;首先必须要加入到一个组中。 但是一个组中有多个消费者的话&#xff0c;那么每一个消费者该如何消费呢&#xff0c;是不是像图中一样的消费策略呢&#xff1f;如果是的话&#xff0c;那假设消费者组…

C++11,可变参数模板,lambda表达式,包装器

可变参数模板 在C11中模板也可以接收多个不定参数&#xff0c;就和int printf(const char *format, ...);函数一般模板也可以接收多个参数&#xff1b; // 可变参数模板 template<class ...Args> void testArgs(Args... args) { } int main() {testArgs(123…

【简单】 猿人学web第一届 第19题 乌拉乌拉

数据接口分析 数据接口为 https://match.yuanrenxue.cn/api/match/19 请求参数只需要携带 页码 cookie 只需要携带 sessionid 请求参数 和 cookie 都没有加密字段&#xff0c;直接用 python 请求 请求失败了 查看协议是 h2 的&#xff0c;再试试 httpx 请求 还是一样的结果…

Creating OpenAI Gym Environment from Map Data

题意&#xff1a;从地图数据创建 OpenAI Gym 环境 问题背景&#xff1a; I am just starting out with reinforcement learning and trying to create a custom environment with OpenAI gym. However, I am stumped with trying to create an environment (with roads and in…

【论文速读】| SEAS:大语言模型的自进化对抗性安全优化

本次分享论文&#xff1a;SEAS: Self-Evolving Adversarial Safety Optimization for Large Language Models 基本信息 原文作者: Muxi Diao, Rumei Li, Shiyang Liu, Guogang Liao, Jingang Wang, Xunliang Cai, Weiran Xu 作者单位: 北京邮电大学, 美团 关键词: 大语言模…

Python 全栈系列267 telegraf、influxdb和grafana

说明 没想到如此丝滑 本来是因为想稍微了解一下influxdb&#xff0c;然后发现和telegraf配套能干监控&#xff0c;然后正好之前又起了grafana,然后瞬间就通了。 内容 1 telegraf Telegraf 是一个开源的服务器代理&#xff0c;用于收集、处理和发送数据。它是 InfluxData 公司…

cowrie部署中遇到的坑

首先&#xff0c;这个cowrie已经比较老了&#xff0c;没有好看的展示界面&#xff0c;当前跟mhn结合使用的只能是2.2版本&#xff0c;不是迫切需要的话不建议布。 mhn也比较老了&#xff0c;界面太过简洁&#xff0c;推荐hfish&#xff0c;部署方便&#xff0c;好看。 坑1&…

STM32重定义printf,实现串口打印

在“usart.c”文件中加入以下代码 #ifdef __GNUC__#define PUTCHAR_PROTOTYPE int __io_putchar(int ch) #else#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) #endifPUTCHAR_PROTOTYPE{HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);return ch; }…

鸿蒙图表MPChart自定义样式(五)左y轴显示数值,右y轴显示百分比

左y轴数值不变&#xff0c;右y轴改成百分比&#xff0c;需要通过自定义RightAxisFormatter实现IAxisValueFormatter接口&#xff0c;将右y轴的数值改成百分比文本&#xff0c;RightAxisFormatter类如下&#xff1a; class RightAxisFormatter implements IAxisValueFormatter …