You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

103 lines
3.2 KiB
PHTML

<?php
namespace Isekai\Widgets;
use Html;
class MasonryWidget {
public static $paramsStack = [];
/**
* 瀑布流子项可以通过此方法获取父级瀑布流参数
*/
public static function getMasonryParams() {
if (empty(self::$paramsStack)) {
return null;
}
return self::$paramsStack[count(self::$paramsStack) - 1];
}
public static function getStyle($params) {
$gutter = max(0, $params['gutter']);
$maxCol = max(1, $params['cols']);
$colWidth = round(100 / $maxCol, 6);
$css = <<<CSS
.isekai-masonry.max-col-{$maxCol} { --masonry-col-width: {$colWidth}%; --masonry-gutter: {$gutter}px; }
CSS;
$breakpoints = [
'xs' => 576,
'sm' => 768,
'md' => 992,
'lg' => 1200,
'xl' => 1400,
];
foreach ($breakpoints as $breakpoint => $width) {
$paramKey = "{$breakpoint}-cols";
if (!isset($params[$paramKey])) {
continue;
}
$maxCol = max(1, $params[$paramKey]);
$colWidth = round(100 / $maxCol, 6);
$css .= <<<CSS
@media (max-width: {$width}px) { .isekai-masonry.max-col-{$breakpoint}-${maxCol} { --masonry-col-width: {$colWidth}%; } }
CSS;
}
return Html::rawElement('style', [], $css);
}
/**
* @param string $text
* @param array $params
* @param \Parser $parser
* @param \PPFrame $frame
* @return string|string[]
*/
public static function create($text, $params, \Parser $parser, \PPFrame $frame) {
$parser->getOutput()->addModules(['ext.isekai.masonry']);
$params['cols'] = intval($params['cols'] ?? 2);
$params['xs-cols'] = intval($params['xs-cols'] ?? 1);
$params['sm-cols'] = intval($params['sm-cols'] ?? 1);
$params['md-cols'] = intval($params['md-cols'] ?? 2);
$params['lg-cols'] = intval($params['lg-cols'] ?? 2);
$params['xl-cols'] = intval($params['xl-cols'] ?? 3);
$params['gutter'] = intval($params['gutter'] ?? 10);
$className = [
'isekai-masonry',
"max-col-{$params['cols']}",
"max-col-xs-{$params['xs-cols']}",
"max-col-sm-{$params['sm-cols']}",
"max-col-md-{$params['md-cols']}",
"max-col-lg-{$params['lg-cols']}",
"max-col-xl-{$params['xl-cols']}",
];
self::$paramsStack[] = $params;
$content = $parser->recursiveTagParseFully($text, $frame);
array_pop(self::$paramsStack);
return [
self::getStyle($params) .
Html::openElement('div', [
'class' => implode(' ', $className),
'data-cols' => $params['cols'],
'data-gutter' => $params['gutter'],
]) .
Html::element('div', [
'class' => 'isekai-masonry-sizer',
]) .
Html::element('div', [
'class' => 'isekai-masonry-gutter-sizer',
]) .
$content .
Html::closeElement('div'),
"markerType" => 'nowiki'
];
}
}