添加Masonry组件
parent
be5ad56fe4
commit
6e6184f2b8
@ -0,0 +1,69 @@
|
||||
<?php
|
||||
namespace Isekai\Widgets;
|
||||
|
||||
use Html;
|
||||
|
||||
class MasonryItemWidget {
|
||||
/**
|
||||
* @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) {
|
||||
// 获取父级瀑布流参数
|
||||
$masonryParams = MasonryWidget::getMasonryParams();
|
||||
|
||||
$content = $text = $parser->recursiveTagParse($text, $frame);
|
||||
if (!$masonryParams) {
|
||||
return '<span class="error">' . wfMessage('isekai-masonry-item-must-in-masonry')->parse() . '</span>' . $content;
|
||||
}
|
||||
|
||||
$maxCol = $masonryParams['cols'];
|
||||
|
||||
$className = ['isekai-masonry-item'];
|
||||
|
||||
if (isset($params['col'])) {
|
||||
$value = $params['col'];
|
||||
$col = $value === 'full' ? $maxCol : min($maxCol, intval($value));
|
||||
$className[] = 'col-' . $col;
|
||||
} else {
|
||||
$className[] = 'col-1';
|
||||
}
|
||||
|
||||
if (isset($params['xs-col'])) {
|
||||
$value = $params['xs-col'];
|
||||
$col = $value === 'full' ? $maxCol : min($maxCol, intval($value));
|
||||
$className[] = 'col-xs-' . $col;
|
||||
}
|
||||
|
||||
if (isset($params['sm-col'])) {
|
||||
$value = $params['sm-col'];
|
||||
$col = $value === 'full' ? $maxCol : min($maxCol, intval($value));
|
||||
$className[] = 'col-sm-' . $col;
|
||||
}
|
||||
|
||||
if (isset($params['md-col'])) {
|
||||
$value = $params['md-col'];
|
||||
$col = $value === 'full' ? $maxCol : min($maxCol, intval($value));
|
||||
$className[] = 'col-md-' . $col;
|
||||
}
|
||||
|
||||
if (isset($params['lg-col'])) {
|
||||
$value = $params['lg-col'];
|
||||
$col = $value === 'full' ? $maxCol : min($maxCol, intval($value));
|
||||
$className[] = 'col-lg-' . $col;
|
||||
}
|
||||
|
||||
if (isset($params['xl-col'])) {
|
||||
$value = $params['xl-col'];
|
||||
$col = $value === 'full' ? $maxCol : min($maxCol, intval($value));
|
||||
$className[] = 'col-xl-' . $col;
|
||||
}
|
||||
|
||||
return Html::openElement('div', [
|
||||
'class' => implode(' ', $className),
|
||||
]) . $content . Html::closeElement('div');
|
||||
}
|
||||
}
|
@ -0,0 +1,100 @@
|
||||
<?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 (min-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'] ?? 2);
|
||||
$params['sm-cols'] = intval($params['sm-cols'] ?? 2);
|
||||
$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']}"];
|
||||
|
||||
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-xs-cols' => $params['xs-cols'],
|
||||
'data-sm-cols' => $params['sm-cols'],
|
||||
'data-md-cols' => $params['md-cols'],
|
||||
'data-lg-cols' => $params['lg-cols'],
|
||||
'data-xl-cols' => $params['xl-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'
|
||||
];
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
$(function () {
|
||||
console.log('IsekaiWidgets: Masonry extension loaded');
|
||||
new isekai.lib.Masonry('.isekai-masonry', {
|
||||
itemSelector: '.isekai-masonry-item',
|
||||
columnWidth: '.isekai-masonry-sizer',
|
||||
gutter: '.isekai-masonry-gutter-sizer',
|
||||
percentPosition: true
|
||||
});
|
||||
});
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,19 @@
|
||||
/*!
|
||||
* Masonry v4.2.2
|
||||
* Cascading grid layout library
|
||||
* https://masonry.desandro.com
|
||||
* MIT License
|
||||
* by David DeSandro
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Outlayer v2.1.1
|
||||
* the brains and guts of a layout library
|
||||
* MIT license
|
||||
*/
|
||||
|
||||
/*!
|
||||
* getSize v2.0.3
|
||||
* measure size of elements
|
||||
* MIT license
|
||||
*/
|
@ -0,0 +1,76 @@
|
||||
.isekai-masonry {
|
||||
display: block;
|
||||
width: 100%;
|
||||
--masonry-col-width: 50%;
|
||||
|
||||
.isekai-masonry-gutter-sizer {
|
||||
width: 0;
|
||||
width: ~"var(--masonry-gutter)";
|
||||
}
|
||||
|
||||
.isekai-masonry-sizer {
|
||||
width: 100%;
|
||||
width: ~"calc(var(--masonry-col-width) - var(--masonry-gutter) - 1px)";
|
||||
}
|
||||
|
||||
// Column width tools
|
||||
.col-1 {
|
||||
width: 100%; // Fallback
|
||||
width: ~"calc(var(--masonry-col-width) - var(--masonry-gutter) - 1px)";
|
||||
}
|
||||
|
||||
.col-2 {
|
||||
width: 100%;
|
||||
width: ~"min(100%, calc(var(--masonry-col-width) * 2 - var(--masonry-gutter) - 1px))";
|
||||
}
|
||||
|
||||
.col-3 {
|
||||
width: 100%;
|
||||
width: ~"min(100%, calc(var(--masonry-col-width) * 3 - var(--masonry-gutter) - 1px))";
|
||||
}
|
||||
|
||||
.col-4 {
|
||||
width: 100%;
|
||||
width: ~"min(100%, calc(var(--masonry-col-width) * 4 - var(--masonry-gutter) - 1px))";
|
||||
}
|
||||
|
||||
.col-5 {
|
||||
width: 100%;
|
||||
width: ~"min(100%, calc(var(--masonry-col-width) * 5 - var(--masonry-gutter) - 1px))";
|
||||
}
|
||||
|
||||
.col-6 {
|
||||
width: 100%;
|
||||
width: ~"min(100%, calc(var(--masonry-col-width) * 6 - var(--masonry-gutter) - 1px))";
|
||||
}
|
||||
|
||||
.col-7 {
|
||||
width: 100%;
|
||||
width: ~"min(100%, calc(var(--masonry-col-width) * 7 - var(--masonry-gutter) - 1px))";
|
||||
}
|
||||
|
||||
.col-8 {
|
||||
width: 100%;
|
||||
width: ~"min(100%, calc(var(--masonry-col-width) * 8 - var(--masonry-gutter) - 1px))";
|
||||
}
|
||||
|
||||
.col-9 {
|
||||
width: 100%;
|
||||
width: ~"min(100%, calc(var(--masonry-col-width) * 9 - var(--masonry-gutter) - 1px))";
|
||||
}
|
||||
|
||||
.col-10 {
|
||||
width: 100%;
|
||||
width: ~"min(100%, calc(var(--masonry-col-width) * 10 - var(--masonry-gutter) - 1px))";
|
||||
}
|
||||
|
||||
.col-11 {
|
||||
width: 100%;
|
||||
width: ~"min(100%, calc(var(--masonry-col-width) * 11 - var(--masonry-gutter) - 1px))";
|
||||
}
|
||||
|
||||
.col-12 {
|
||||
width: 100%;
|
||||
width: ~"min(100%, calc(var(--masonry-col-width) * 12 - var(--masonry-gutter) - 1px))";
|
||||
}
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
import Masonry from "masonry-layout";
|
||||
import { registerModule } from "../moduleRegister";
|
||||
|
||||
registerModule('lib.Masonry', Masonry);
|
Loading…
Reference in New Issue