Skip to content

Instantly share code, notes, and snippets.

@helhum
Last active April 27, 2021 20:29
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save helhum/4fbad99b41eea3ef97cccf0c007551cc to your computer and use it in GitHub Desktop.
Save helhum/4fbad99b41eea3ef97cccf0c007551cc to your computer and use it in GitHub Desktop.
Focus area View Helper
<a href="#"
class="lazyload fullscreen random-gallery"
id="js-random-image"
data-random-images="{h:homePageTeaserImages(
images: object.images,
breakPointConfiguration: {
300: '{maxWidth: \'300\', maxHeight: \'300\'}',
1000: '{maxWidth: \'1000\', maxHeight: \'1000\'}',
1900: '{maxWidth: \'1900\', maxHeight: \'1900\'}'}
) -> f:format.htmlspecialchars()}"
data-bgset=""
data-sizes="auto"
></a>
<?php
namespace Helhum\SiteDaniel\ViewHelpers;
/*
* This file is part of the Daniel Pilar website distribution.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read
* http://www.gnu.org/licenses/gpl-2.0.html
*
*/
use TYPO3\CMS\Core\Resource\Exception\ResourceDoesNotExistException;
use TYPO3\CMS\Core\Resource\FileInterface;
use TYPO3\CMS\Core\Resource\FileReference;
use TYPO3\CMS\Core\Utility\MathUtility;
use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
/**
* Class HomePageTeaserImagesViewHelper
*/
class HomePageTeaserImagesViewHelper extends AbstractViewHelper
{
/**
* @var TypoScriptFrontendController
*/
protected $typoScriptFrontendController;
/**
* @var \TYPO3\CMS\Extbase\Service\ImageService
*/
protected $imageService;
/**
* @param \TYPO3\CMS\Extbase\Service\ImageService $imageService
*/
public function injectImageService(\TYPO3\CMS\Extbase\Service\ImageService $imageService)
{
$this->imageService = $imageService;
}
/**
* HomePageTeaserImagesViewHelper constructor.
*
* @param TypoScriptFrontendController|null $typoScriptFrontendController
*/
public function __construct(TypoScriptFrontendController $typoScriptFrontendController = null)
{
$this->typoScriptFrontendController = $typoScriptFrontendController ?: $GLOBALS['TSFE'];
}
/**
* Resizes a given image (if required) and renders the respective img tag
*
* @see http://typo3.org/documentation/document-library/references/doc_core_tsref/4.2.0/view/1/5/#id4164427
* @param \TYPO3\CMS\Extbase\Persistence\ObjectStorage $images
* @param array $breakPointConfiguration Array of breakpoints and sizes
* @return string Json.
* @throws \TYPO3\CMS\Fluid\Core\ViewHelper\Exception
*/
public function render(ObjectStorage $images = null, array $breakPointConfiguration = array())
{
$returnData = array();
foreach ($this->objectStorageOrNullToArray($images) as $image) {
try {
$image = $this->imageService->getImage(null, $image, false);
$crop = $image instanceof FileReference ? $image->getProperty('crop') : null;
$imageData = array();
$imageData['isBright'] = (bool)$image->getProperty('image_is_bright');
$imageData['backgroundPosition'] = $this->calculateBackgroundPosition($image, $crop);
foreach ($breakPointConfiguration as $name => $finalProcessingInstructions) {
$processedImage = $this->imageService->applyProcessingInstructions($image, $finalProcessingInstructions);
$imageData[$name] = $this->imageService->getImageUri($processedImage);
}
$imageData['pageURI'] = $this->typoScriptFrontendController->cObj->getTypoLink_URL($image->getProperty('link'));
$returnData[] = $imageData;
} catch (ResourceDoesNotExistException $e) {
// thrown if file does not exist
} catch (\UnexpectedValueException $e) {
// thrown if a file has been replaced with a folder
} catch (\RuntimeException $e) {
// RuntimeException thrown if a file is outside of a storage
} catch (\InvalidArgumentException $e) {
// thrown if file storage does not exist
}
}
return json_encode($returnData, JSON_PRETTY_PRINT|JSON_HEX_AMP|JSON_HEX_APOS|JSON_HEX_QUOT|JSON_HEX_TAG);
}
/**
* @param FileInterface $image
* @param string $cropDefinition
* @return string
*/
protected function calculateBackgroundPosition(FileInterface $image, $cropDefinition)
{
if (empty($cropDefinition)) {
return '50% 50%';
}
$cropArea = json_decode($cropDefinition, true);
$width = $image->getProperty('width');
$height = $image->getProperty('height');
$xScale = 100 / $width;
$yScale = 100 / $height;
$yAxis = 100 * ($cropArea['y'] + ($cropArea['height'] / 2)) / $height;
$xAxis = 100 * ((($cropArea['x'] + ($cropArea['width'] / 2)) / $width));
$cxl = $cropArea['x'];
$cxr = $width - ($cropArea['x'] + $cropArea['width']);
$cyt = $cropArea['y'];
$cyb = $height - ($cropArea['y'] + $cropArea['height']);
$xAxis += ($cxl - $cxr) * $xScale;
$yAxis += ($cyt - $cyb) * $yScale;
$yAxis = MathUtility::forceIntegerInRange($yAxis, 0, 100);
$xAxis = MathUtility::forceIntegerInRange($xAxis, 0, 100);
return (int)$xAxis . '% ' . (int)$yAxis . '%';
}
/**
* @param ObjectStorage|null $value
* @return array
*/
protected function objectStorageOrNullToArray(ObjectStorage $value = null)
{
if ($value === null) {
return array();
}
return $value->toArray();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment