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.
106 lines
3.3 KiB
PHP
106 lines
3.3 KiB
PHP
<?php
|
|
namespace Isekai\Widgets;
|
|
|
|
use MediaWiki\Parser\Parser;
|
|
use MediaWiki\Html\Html;
|
|
use PPFrame;
|
|
|
|
class MasonryWidget {
|
|
public static $breakpoints = [
|
|
'xs' => 576,
|
|
'sm' => 768,
|
|
'md' => 992,
|
|
'lg' => 1200,
|
|
'xl' => 1400,
|
|
];
|
|
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']);
|
|
$halfGutter = round($gutter / 2, 6);
|
|
$maxCol = max(1, $params['cols']);
|
|
$colWidth = round(100 / $maxCol, 6);
|
|
$css = ".isekai-masonry.max-col-{$maxCol} { --masonry-col-width: {$colWidth}%; --masonry-gutter: {$gutter}px; --masonry-gutter-half: {$halfGutter}px; }";
|
|
|
|
if (isset($params['xs-cols'])) {
|
|
$maxCol = max(1, $params['xs-cols']);
|
|
$colWidth = round(100 / $maxCol, 6);
|
|
$css = ".isekai-masonry.max-col-xs-{$maxCol} { --masonry-col-width: {$colWidth}% }";
|
|
}
|
|
|
|
foreach (self::$breakpoints as $breakpoint => $width) {
|
|
$paramKey = "{$breakpoint}-cols";
|
|
if (!isset($params[$paramKey])) {
|
|
continue;
|
|
}
|
|
|
|
$value = intval($params[$paramKey]);
|
|
$maxCol = max(1, $value);
|
|
$colWidth = round(100 / $maxCol, 6);
|
|
|
|
$css .= "@media (min-width: {$width}px) { .isekai-masonry.max-col-{$breakpoint}-{$maxCol} { --masonry-col-width: {$colWidth}%; } }";
|
|
}
|
|
|
|
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['gutter'] = intval($params['gutter'] ?? 10);
|
|
|
|
$className = [
|
|
'isekai-masonry',
|
|
"max-col-{$params['cols']}",
|
|
];
|
|
|
|
foreach (self::$breakpoints as $breakpoint => $_) {
|
|
$paramKey = "{$breakpoint}-cols";
|
|
if (isset($params[$paramKey])) {
|
|
$className[] = "max-col-{$breakpoint}-{$params[$paramKey]}";
|
|
}
|
|
}
|
|
|
|
self::$paramsStack[] = $params;
|
|
$text = trim($text);
|
|
$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'
|
|
];
|
|
}
|
|
} |