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;
    }
} 
相关推荐
86Eric8 小时前
Laravel 实现 队列 发送邮件功能
php·laravel·队列·异步执行
亿坊电商13 小时前
PHP + Go 如何协同打造高并发微服务?
微服务·golang·php
左灯右行的爱情14 小时前
计算机网络-传输层基础概念
网络·计算机网络·php
SlientICE15 小时前
预防WIFI攻击,保证网络安全
网络·安全·php
PeakXin1 天前
🚀 Windows 下实现 PHP 多版本动态切换管理(适配 phpStudy)+ 一键切换工具源码分享
php
ALe要立志成为web糕手1 天前
PHP反序列化
web安全·网络安全·php·反序列化
hello_simon1 天前
小白工具视频转gif,支持在线gif或视频互转,批量转换,免费在线使用,无需下载
开发语言·php·音视频
友善的猴子2 天前
JetBrains PhpStorm v2024.3.1 Mac PHP开发工具
macos·php·phpstorm
2401_890666132 天前
免费送源码:Java+ssm+MySQL 校园二手书销售平台设计与实现 计算机毕业设计原创定制
java·spring boot·python·mysql·小程序·php·课程设计