Dcat-admin 轮播图组件

实现功能:定义宽度,高度,切换时间等 效果图:

使用方法

php 复制代码
public function index(Content $content)
{
    return $content
        ->header('Dashboard')
        ->description('Description...')
        ->body(function (Row $row) {
            $row->column(6, function (Column $column) {
                // 创建轮播图实例
                $carousel = new Carousel();
                // 配置轮播图
                $carousel->addImages([
                    'https://gjba.cn/img/1.jpg',
                    'https://gjba.cn/img/2.jpg',
                    'https://gjba.cn/img/3.jpg',
                    'https://gjba.cn/img/4.jpg',
                ])
                    ->width('100%')     // 设置宽度
                    ->height('400px')    // 设置高度
                    ->interval(3000);
                $column->row($carousel->render());
            });


        });
}
复制代码
Carousel
ini 复制代码
<?php

namespace App\Admin\Extensions;

use Illuminate\Contracts\Support\Renderable;

class Carousel implements Renderable
{
    protected $images = [];
    protected $height = '300px';
    protected $width = '100%';
    protected $interval = 3000;
    protected $id;

    public function __construct()
    {
        $this->id = 'carousel-' . uniqid();
    }

    /**
     * 添加图片
     * @param string $src 图片地址
     * @return $this
     */
    public function addImage($src)
    {
        $this->images[] = $src;
        return $this;
    }

    /**
     * 批量添加图片
     * @param array $images 图片地址数组
     * @return $this
     */
    public function addImages(array $images)
    {
        foreach ($images as $image) {
            $this->addImage($image);
        }
        return $this;
    }

    /**
     * 设置轮播图高度
     * @param string|int $height 高度值(支持px、%、vh等单位)
     * @return $this
     */
    public function height($height)
    {
        $this->height = $this->formatSize($height);
        return $this;
    }

    /**
     * 设置轮播图宽度
     * @param string|int $width 宽度值(支持px、%、vw等单位)
     * @return $this
     */
    public function width($width)
    {
        $this->width = $this->formatSize($width);
        return $this;
    }

    /**
     * 格式化尺寸值
     * @param string|int $size
     * @return string
     */
    protected function formatSize($size)
    {
        if (is_numeric($size)) {
            return $size . 'px';
        }
        return $size;
    }

    /**
     * 设置自动播放间隔时间(毫秒)
     * @param int $interval
     * @return $this
     */
    public function interval($interval)
    {
        $this->interval = $interval;
        return $this;
    }

    /**
     * 渲染轮播图
     * @return string
     */
    public function render()
    {
        $containerStyle = "position: relative; width: {$this->width}; height: {$this->height}; overflow: hidden; margin: 0 auto;";
        
        $html = <<<HTML
        <div class="carousel-container {$this->id}" style="{$containerStyle}">
            <div class="carousel-wrapper" style="display: flex; transition: transform 0.5s ease;">
HTML;

        foreach ($this->images as $image) {
            $html .= <<<HTML
                <img src="{$image}" style="width: 100%; height: 100%; object-fit: cover; flex-shrink: 0;">
HTML;
        }

        $html .= <<<HTML
            </div>
            <button class="carousel-prev" style="position: absolute; left: 10px; top: 50%; transform: translateY(-50%); z-index: 2; background: rgba(0,0,0,0.5); color: white; border: none; padding: 10px 15px; cursor: pointer; border-radius: 50%; font-size: 18px;">←</button>
            <button class="carousel-next" style="position: absolute; right: 10px; top: 50%; transform: translateY(-50%); z-index: 2; background: rgba(0,0,0,0.5); color: white; border: none; padding: 10px 15px; cursor: pointer; border-radius: 50%; font-size: 18px;">→</button>
            <div class="carousel-dots" style="position: absolute; bottom: 10px; left: 50%; transform: translateX(-50%); display: flex; gap: 8px;">
HTML;

        for ($i = 0; $i < count($this->images); $i++) {
            $html .= <<<HTML
                <span class="carousel-dot" data-index="{$i}" style="width: 12px; height: 12px; border-radius: 50%; background: white; cursor: pointer; transition: all 0.3s ease;"></span>
HTML;
        }

        $html .= <<<HTML
            </div>
        </div>

        <script>
        (function() {
            const container = document.querySelector('.{$this->id}');
            const wrapper = container.querySelector('.carousel-wrapper');
            const slides = wrapper.querySelectorAll('img');
            const prevBtn = container.querySelector('.carousel-prev');
            const nextBtn = container.querySelector('.carousel-next');
            const dots = container.querySelectorAll('.carousel-dot');
            let currentIndex = 0;
            const totalSlides = slides.length;

            function updateCarousel() {
                wrapper.style.transform = `translateX(-${currentIndex * 100}%)`;
                dots.forEach((dot, index) => {
                    dot.style.background = index === currentIndex ? '#007bff' : 'white';
                    dot.style.transform = index === currentIndex ? 'scale(1.2)' : 'scale(1)';
                });
            }

            function nextSlide() {
                currentIndex = (currentIndex + 1) % totalSlides;
                updateCarousel();
            }

            function prevSlide() {
                currentIndex = (currentIndex - 1 + totalSlides) % totalSlides;
                updateCarousel();
            }

            // 添加过渡动画效果
            wrapper.style.transition = 'transform 0.5s ease';

            // 事件监听
            prevBtn.addEventListener('click', prevSlide);
            nextBtn.addEventListener('click', nextSlide);

            dots.forEach((dot, index) => {
                dot.addEventListener('click', () => {
                    currentIndex = index;
                    updateCarousel();
                });
            });

            let autoplayInterval = setInterval(nextSlide, {$this->interval});

            // 鼠标悬停控制
            container.addEventListener('mouseenter', () => {
                clearInterval(autoplayInterval);
                prevBtn.style.opacity = '1';
                nextBtn.style.opacity = '1';
            });

            container.addEventListener('mouseleave', () => {
                autoplayInterval = setInterval(nextSlide, {$this->interval});
                prevBtn.style.opacity = '0.5';
                nextBtn.style.opacity = '0.5';
            });

            // 初始化显示
            updateCarousel();
            
            // 设置按钮初始透明度
            prevBtn.style.opacity = '0.5';
            nextBtn.style.opacity = '0.5';
            prevBtn.style.transition = 'opacity 0.3s ease';
            nextBtn.style.transition = 'opacity 0.3s ease';
        })();
        </script>
HTML;

        return $html;
    }
} 
相关推荐
BingoGo13 小时前
免费可商用 PHP 管理后台 CatchAdmin V5.4.0 发布,新增短信服务能力
后端·php
纯.Pure_Jin(g)1 天前
靶场PHP函数整理+防御方式
开发语言·php·ctf
神仙别闹1 天前
基于C++ WinPcap 的网络抓包软件
网络·c++·php
斑马1392 天前
Linux软件编程学习笔记(五)——线程
开发语言·php
学习星球2 天前
空天地一体化网络(NTN)深度解析:从Starlink D2C到3GPP NTN,卫星直连手机是如何实现的?
网络·人工智能·算法·智能手机·php
郑州光合科技余经理2 天前
本地生活服务系统:模块边界与结算字段怎么拆
java·开发语言·前端·后端·系统架构·uni-app·php
2601_962072502 天前
网络安全防护指南:筑牢网络安全防线(510)
安全·web安全·php
Patrick在香港2 天前
Python 拉取城巴开放数据:406 条路线,香港岛巴士网络的数字画像
网络·python·数据分析·php·数据可视化·香港·开放数据
吴声子夜歌2 天前
Java——开发中通用的方法和准则(二)
java·开发语言·php