imported masonry into project
This commit is contained in:
parent
f5de1f4c0f
commit
14ed7959f4
191
Masonry.php
Normal file
191
Masonry.php
Normal 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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"require": {
|
|
||||||
"hongaar/php-masonry": "^0.1.0"
|
|
||||||
}
|
|
||||||
}
|
|
22
masonry.php
22
masonry.php
|
@ -11,6 +11,8 @@ Version: 1.0
|
||||||
Author URI: https://en.oreolek.ru/
|
Author URI: https://en.oreolek.ru/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
require_once('Masonry.php');
|
||||||
|
|
||||||
add_action('admin_menu', 'masonryslides_menu');
|
add_action('admin_menu', 'masonryslides_menu');
|
||||||
|
|
||||||
function masonryslides_menu() {
|
function masonryslides_menu() {
|
||||||
|
@ -28,4 +30,24 @@ function masonryslides_newslide() {
|
||||||
?>
|
?>
|
||||||
<h1>New slide</h1>
|
<h1>New slide</h1>
|
||||||
<?php
|
<?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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue