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

使用方法
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;
}
}