diff --git a/Masonry.php b/Masonry.php new file mode 100644 index 0000000..f1420bc --- /dev/null +++ b/Masonry.php @@ -0,0 +1,191 @@ +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 . '
'; + } + } 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 . '
'; + } + } + } + + // 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] . ']
'; + } + + // 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 '
'.$this->matrix->toString('%3.0f').'
'; + 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 + ); + } +} \ No newline at end of file diff --git a/composer.json b/composer.json deleted file mode 100644 index 7d6be35..0000000 --- a/composer.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "require": { - "hongaar/php-masonry": "^0.1.0" - } -} diff --git a/masonry.php b/masonry.php index 184ec96..5621cb6 100644 --- a/masonry.php +++ b/masonry.php @@ -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() { ?>

New slide

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) : ?> +
%; left: %; width: %; height: %; background-image: url();'>
+