实现功能:定义宽度,高度,切换时间等 效果图:
使用方法
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; } }