imported masonry into project

This commit is contained in:
Alexander Yakovlev 2017-11-23 00:09:54 +07:00
parent f5de1f4c0f
commit 14ed7959f4
3 changed files with 213 additions and 5 deletions

191
Masonry.php Normal file
View file

@ -0,0 +1,191 @@
<?php
require_once 'PEAR/Math/Matrix.php';
class Masonry
{
public $multiplier = 1; // speedup
public $xsize = 100;
public $ysize = 100;
public $minWidth = 15;
public $maxWidth = 40;
public $minHeight = 30;
public $maxHeight = 75;
public $minArea = 2; // fraction of minimum possible area
public $maxArea = 0.5; // fraction of maximum possible area
public $fillTopProbability = 2;
public $fillHalfwayProbability = 3;
public $debug = false;
/**
*
* @var Math_Matrix
*/
private $matrix;
public function create($array)
{
// test conditions
// TODO: test min/max
// test area
if ( ($this->minArea * ($this->minWidth * $this->minHeight)) >= ($this->maxArea * ($this->maxWidth * $this->maxHeight))) {
throw new Exception('Min/max area overlap, please adjust settings');
}
// create matrix
$this->matrix = Math_Matrix::makeMatrix($this->ysize, $this->xsize, -1);
// variable to define whether filling is active
$fill = false;
// return array
$positions = array();
foreach($array as $k => $v) {
// get next empty space
$pos = $this->searchNextPosition();
// fill horizontal?
if ($pos[1] == 0) { // are we at the top?
if ($pos[0] != 0) { // are we not at [0,0] ?
if (rand(1, $this->fillTopProbability) == 1) { // roll a dice for top position fill
// calculate fill position
$fill = $this->searchXBoundFrom($pos[0]) + $this->minWidth;
if ($this->debug) {
echo 'fill from top x='. $fill . '<br/>';
}
} else {
$fill = false;
}
}
} elseif ($fill === false) { // fill from halfway?
if (rand(1, $this->fillHalfwayProbability) == 1) { // roll a dice halfway position fill
// calculate fill position
$fill = $this->searchXBoundFrom($pos[0]) + $this->minWidth;
if ($this->debug) {
echo 'fill x='. $fill . '<br/>';
}
}
}
// get dimensions
$rand = $this->randomDimensions();
$randWidth = $rand['width'];
$randHeight = $rand['height'];
if ($fill !== false) {
$randWidth = $fill - $pos[0];
}
// height available?
$heightAvailable = $this->availableHeightFrom($pos[0], $pos[1]);
if ($heightAvailable <= $this->minHeight) {
$height = $heightAvailable;
} else if ($heightAvailable <= $this->minHeight * 2) {
$height = $heightAvailable;
} else {
$height = min($randHeight, $heightAvailable - $this->minHeight);
}
// random width
$width = $randWidth;
// debug
if ($this->debug) {
echo $k . ': ' . $height . '(' . $heightAvailable . ')x' . $width . ' @ [' . $pos[0] . ', ' . $pos[1] . ']<br/>';
}
// set ids
for($x = $pos[0]; $x < $width + $pos[0]; $x++) {
for($y = $pos[1]; $y < $height + $pos[1]; $y++) {
$this->matrix->setElement($y, $x, $k);
}
}
// set item position
$positions[$k] = array(
'x' => $pos[0] * $this->multiplier,
'y' => $pos[1] * $this->multiplier,
'w' => $width * $this->multiplier,
'h' => $height * $this->multiplier
);
}
// debug: print matrix
if ($this->debug) {
echo '<pre>'.$this->matrix->toString('%3.0f').'</pre>';
die();
}
// return array
return $positions;
}
public function searchNextPosition() {
for($x = 0; $x < $this->xsize; $x++) {
$col = $this->matrix->getCol($x);
if (($y = array_search('-1', $col)) !== false) {
return array($x, $y);
}
}
throw new Exception('Grid X size too small, please enlarge');
}
public function searchXBoundFrom($x) {
for($i = $x; $i < $this->xsize; $i++) {
$col = $this->matrix->getCol($i);
if (max($col) == -1) {
return $i;
}
}
}
public function availableHeightFrom($x, $y) {
// get the column
$col = $this->matrix->getCol($x);
// make array start at correct y pos
for($i = 0; $i < $y; $i++) {
array_shift($col);
}
foreach($col as $k => $v) {
if ($v > -1) {
return $k;
}
}
// entire height available
return $this->ysize - $y;
}
public function randomHeight()
{
return rand($this->minHeight, $this->maxHeight);
}
public function randomWidth()
{
return rand($this->minWidth, $this->maxWidth);
}
public function randomDimensions()
{
$min = ($this->minArea * ($this->minHeight * $this->minWidth));
$max = ($this->maxArea * ($this->maxHeight * $this->maxWidth));
do {
$width = $this->randomWidth();
$height = $this->randomHeight();
$area = $width * $height;
} while ($area < $min || $area > $max);
return array(
"width" => $width,
"height" => $height
);
}
}

View file

@ -1,5 +0,0 @@
{
"require": {
"hongaar/php-masonry": "^0.1.0"
}
}

View file

@ -11,6 +11,8 @@ Version: 1.0
Author URI: https://en.oreolek.ru/
*/
require_once('Masonry.php');
add_action('admin_menu', 'masonryslides_menu');
function masonryslides_menu() {
@ -28,4 +30,24 @@ function masonryslides_newslide() {
?>
<h1>New slide</h1>
<?php
$images = glob('images/*');
shuffle($images);
$masonry = new Masonry();
$masonry->minWidth = 5;
$masonry->maxWidth = 15;
$masonry->minHeight = 10;
$masonry->maxHeight = 30;
$masonry->fillTopProbability = 5;
$masonry->fillHalfwayProbability = 2;
$masonry->xsize = count($images) * ($masonry->maxWidth / ($masonry->ysize / $masonry->maxHeight));
try {
$position = $masonry->create($images);
} catch (Exception $e) {
echo $e->getMessage();
}
foreach($images as $k => $v) : ?>
<div style='top: <?php echo $position[$k]['y']; ?>%; left: <?php echo $position[$k]['x']; ?>%; width: <?php echo $position[$k]['w']; ?>%; height: <?php echo $position[$k]['h']; ?>%; background-image: url(<?php echo $images[$k]; ?>);'></div>
<?php endforeach;
}