wp_back/wp-content/plugins/smart-slider-3/Nextend/SmartSlider3/Slider/Feature/SlideBackground.php
2024-05-20 15:37:46 +03:00

420 lines
15 KiB
PHP

<?php
namespace Nextend\SmartSlider3\Slider\Feature;
use Nextend\Framework\Image\ImageEdit;
use Nextend\Framework\Image\ImageManager;
use Nextend\Framework\Parser\Color;
use Nextend\Framework\ResourceTranslator\ResourceTranslator;
use Nextend\Framework\View\Html;
use Nextend\SmartSlider3\Slider\Slide;
use Nextend\SmartSlider3\Slider\Slider;
class SlideBackground {
/**
* @var Slider
*/
private $slider;
public function __construct($slider) {
$this->slider = $slider;
}
public function makeJavaScriptProperties(&$properties) {
$enabled = intval($this->slider->params->get('slide-background-parallax', 0));
if ($enabled) {
$properties['backgroundParallax'] = array(
'strength' => intval($this->slider->params->get('slide-background-parallax-strength', 50)) / 100,
'tablet' => intval($this->slider->params->get('bg-parallax-tablet', 0)),
'mobile' => intval($this->slider->params->get('bg-parallax-mobile', 0))
);
}
}
/**
* @param $slide Slide
*
* @return string
*/
public function make($slide) {
if ($slide->parameters->get('background-type') == '') {
$slide->parameters->set('background-type', 'color');
if ($slide->parameters->get('backgroundVideoMp4')) {
$slide->parameters->set('background-type', 'video');
} else if ($slide->parameters->get('backgroundImage')) {
$slide->parameters->set('background-type', 'image');
}
}
return $this->makeBackground($slide);
}
private function getBackgroundStyle($slide) {
$attributes = array();
$style = '';
$color = $slide->fill($slide->parameters->get('backgroundColor', ''));
if (empty($color)) {
$color = 'ffffff00';
}
if (strlen($color) > 0 && $color[0] == '#') {
$color = substr($color, 1);
if (strlen($color) == 6) {
$color .= 'ff';
}
}
$gradient = $slide->parameters->get('backgroundGradient', 'off');
if ($gradient != 'off') {
$colorEnd = $slide->fill($slide->parameters->get('backgroundColorEnd', 'ffffff00'));
if (empty($colorEnd)) {
$colorEnd = 'ffffff00';
}
if ($colorEnd[0] == '#') {
$colorEnd = substr($colorEnd, 1);
if (strlen($colorEnd) == 6) {
$colorEnd .= 'ff';
}
}
$startColor = Color::colorToRGBA($color);
$endColor = Color::colorToRGBA($colorEnd);
$attributes['data-gradient'] = $gradient;
$attributes['data-color-start'] = $startColor;
$attributes['data-color-end'] = $endColor;
switch ($gradient) {
case 'horizontal':
$style .= 'background:linear-gradient(to right, ' . $startColor . ' 0%,' . $endColor . ' 100%);';
break;
case 'vertical':
$style .= 'background:linear-gradient(to bottom, ' . $startColor . ' 0%,' . $endColor . ' 100%);';
break;
case 'diagonal1':
$style .= 'background:linear-gradient(45deg, ' . $startColor . ' 0%,' . $endColor . ' 100%);';
break;
case 'diagonal2':
$style .= 'background:linear-gradient(135deg, ' . $startColor . ' 0%,' . $endColor . ' 100%);';
break;
}
} else {
if (strlen($color) == 8) {
$colorRGBA = Color::colorToRGBA($color);
$style .= "background-color: " . Color::colorToRGBA($color) . ";";
$attributes['data-color'] = $colorRGBA;
}
}
$attributes['style'] = $style;
return $attributes;
}
private function makeBackground($slide) {
$backgroundType = $slide->parameters->get('background-type');
if (empty($backgroundType)) {
$backgroundVideoMp4 = $slide->parameters->get('backgroundVideoMp4', '');
$backgroundImage = $slide->parameters->get('backgroundImage', '');
if (!empty($backgroundVideoMp4)) {
$backgroundType = 'video';
} else if (!empty($backgroundImage)) {
$backgroundType = 'image';
} else {
$backgroundType = 'color';
}
}
$fillMode = $slide->parameters->get('backgroundMode', 'default');
if ($fillMode == 'default') {
$fillMode = $this->slider->params->get('backgroundMode', 'fill');
}
$backgroundElements = array();
if ($backgroundType == 'color') {
$backgroundElements[] = $this->renderColor($slide);
} else if ($backgroundType == 'video') {
$backgroundElements[] = $this->renderBackgroundVideo($slide);
$backgroundElements[] = $this->renderImage($slide, $fillMode);
$backgroundElements[] = $this->renderColor($slide);
} else if ($backgroundType == 'image') {
$backgroundElements[] = $this->renderImage($slide, $fillMode);
$backgroundElements[] = $this->renderColor($slide);
}
$html = implode('', $backgroundElements);
/* @see https://bugs.chromium.org/p/chromium/issues/detail?id=1181291
* if (!$slide->getFrontendFirst()) {
* $html = '<template>' . $html . '</template>';
* }
*/
return Html::tag('div', array(
'class' => "n2-ss-slide-background",
'data-public-id' => $slide->publicID,
'data-mode' => $fillMode
), $html);
}
private function renderColor($slide) {
$backgroundAttributes = $this->getBackgroundStyle($slide);
if (!empty($backgroundAttributes['style'])) {
$backgroundAttributes['class'] = 'n2-ss-slide-background-color';
if ($slide->parameters->get('backgroundColorOverlay', 0)) {
$backgroundAttributes['data-overlay'] = 1;
}
return Html::tag('div', $backgroundAttributes, '');
}
return '';
}
/**
* @param $slide Slide
* @param $fillMode
*
* @return string
*/
private function renderImage($slide, $fillMode) {
$rawBackgroundImage = $slide->parameters->get('backgroundImage', '');
if (empty($rawBackgroundImage)) {
return '';
}
$backgroundImageBlur = max(0, $slide->parameters->get('backgroundImageBlur', 0));
$focusX = max(0, min(100, $slide->fill($slide->parameters->get('backgroundFocusX', 50))));
$focusY = max(0, min(100, $slide->fill($slide->parameters->get('backgroundFocusY', 50))));
$backgroundImageMobile = '';
$backgroundImageTablet = '';
$backgroundImageDesktopRetina = '';
$backgroundImage = $slide->fill($rawBackgroundImage);
if (!$slide->hasGenerator()) {
$imageData = ImageManager::getImageData($backgroundImage);
$backgroundImageDesktopRetina = $imageData['desktop-retina']['image'];
$backgroundImageMobile = $imageData['mobile']['image'];
$backgroundImageTablet = $imageData['tablet']['image'];
}
$alt = $slide->fill($slide->parameters->get('backgroundAlt', ''));
$title = $slide->fill($slide->parameters->get('backgroundTitle', ''));
$opacity = min(100, max(0, $slide->parameters->get('backgroundImageOpacity', 100)));
$style = array();
if ($opacity < 100) {
$style[] = 'opacity:' . ($opacity / 100);
}
if ($focusX != '50') {
$style[] = '--ss-o-pos-x:' . $focusX . '%';
}
if ($focusY != '50') {
$style[] = '--ss-o-pos-y:' . $focusY . '%';
}
$attributes = array(
"class" => 'n2-ss-slide-background-image',
"data-blur" => $backgroundImageBlur,
"data-opacity" => $opacity,
"data-x" => $focusX,
"data-y" => $focusY,
"data-alt" => $alt,
"data-title" => $title
);
if (!empty($style)) {
$attributes['style'] = implode(';', $style);
}
$sources = array();
if ($this->slider->isAdmin) {
$src = $backgroundImage;
$attributes['data-hash'] = md5($src);
$attributes['data-src-desktop'] = $src;
$attributes['data-src-desktop-retina'] = $backgroundImageDesktopRetina;
$attributes['data-src-tablet'] = $backgroundImageTablet;
$attributes['data-src-mobile'] = $backgroundImageMobile;
} else {
if (empty($backgroundImage)) {
/**
* @todo Does it really work as expected?
*/
$src = ImageEdit::base64Transparent();
} else {
/**
* @todo this resize might have a better place
*/
$src = $backgroundImage;
if ($this->slider->params->get('optimize-scale', 0)) {
$src = ResourceTranslator::urlToResource($this->slider->features->optimize->optimizeBackground($backgroundImage, $focusX, $focusY));
}
$slide->addImage(ResourceTranslator::toUrl($src));
}
$hasDeviceSpecificImage = false;
$mediaQueries = $this->slider->features->responsive->mediaQueries;
if (!empty($backgroundImageDesktopRetina)) {
$hasDeviceSpecificImage = true;
$backgroundImageDesktopRetina = ResourceTranslator::toUrl($backgroundImageDesktopRetina);
$mediaQueryMinPixelRatio = ' and (-webkit-min-device-pixel-ratio: 1.5)';
if (!empty($mediaQueries['desktopportrait'])) {
$sources[] = HTML::tag('source', Html::addExcludeLazyLoadAttributes(array(
'srcset' => $backgroundImageDesktopRetina,
'media' => implode($mediaQueryMinPixelRatio . ',', $mediaQueries['desktopportrait']) . $mediaQueryMinPixelRatio
)), false, false);
}
if (!empty($mediaQueries['desktoplandscape'])) {
$sources[] = HTML::tag('source', Html::addExcludeLazyLoadAttributes(array(
'srcset' => $backgroundImageDesktopRetina,
'media' => implode($mediaQueryMinPixelRatio . ',', $mediaQueries['desktoplandscape']) . $mediaQueryMinPixelRatio
)), false, false);
}
}
if (!empty($backgroundImageMobile)) {
$hasDeviceSpecificImage = true;
$backgroundImageMobileUrl = ResourceTranslator::toUrl($backgroundImageMobile);
if (!empty($mediaQueries['mobileportrait'])) {
$sources[] = HTML::tag('source', Html::addExcludeLazyLoadAttributes(array(
'srcset' => $backgroundImageMobileUrl,
'media' => implode(',', $mediaQueries['mobileportrait'])
)), false, false);
}
if (!empty($mediaQueries['mobilelandscape'])) {
$sources[] = HTML::tag('source', Html::addExcludeLazyLoadAttributes(array(
'srcset' => $backgroundImageMobileUrl,
'media' => implode(',', $mediaQueries['mobilelandscape'])
)), false, false);
}
}
if (!empty($backgroundImageTablet)) {
$hasDeviceSpecificImage = true;
$backgroundImageTabletUrl = ResourceTranslator::toUrl($backgroundImageTablet);
if (!empty($mediaQueries['tabletportrait'])) {
$sources[] = HTML::tag('source', Html::addExcludeLazyLoadAttributes(array(
'srcset' => $backgroundImageTabletUrl,
'media' => implode(',', $mediaQueries['tabletportrait'])
)), false, false);
}
if (!empty($mediaQueries['tabletlandscape'])) {
$sources[] = HTML::tag('source', Html::addExcludeLazyLoadAttributes(array(
'srcset' => $backgroundImageTabletUrl,
'media' => implode(',', $mediaQueries['tabletlandscape'])
)), false, false);
}
}
}
$imageAttributes = array(
'src' => ResourceTranslator::toUrl($src),
'alt' => $alt,
'title' => $title,
'loading' => 'lazy',
'style' => ''
);
$imageAttributes = Html::addExcludeLazyLoadAttributes($imageAttributes);
$sources[] = Html::tag('img', $imageAttributes, '', false);
$picture = HTML::tag('picture', Html::addExcludeLazyLoadAttributes(), implode('', $sources));
$originalImage = Html::tag('div', $attributes, $picture);
if ($fillMode === 'blurfit') {
$slideOption = $slide->parameters->get('backgroundMode', 'default');
if ($slideOption === 'blurfit') {
$blurFit = $slide->parameters->get('backgroundBlurFit', 7);
} else {
$blurFit = $this->slider->params->get('backgroundBlurFit', 7);
$attributes['data-blurfitmode'] = 'default';
}
$picture = HTML::tag('picture', Html::addExcludeLazyLoadAttributes(array(
'style' => 'filter:blur(' . $blurFit . 'px)'
)), implode('', $sources));
$blurFitStyle = array(
'margin:-' . ($blurFit * 2) . 'px',
'padding:' . ($blurFit * 2) . 'px'
);
if (!isset($attributes['style'])) {
$attributes['style'] = '';
}
$attributes['data-globalblur'] = $this->slider->params->get('backgroundBlurFit', 7);
$attributes['data-bgblur'] = $slide->parameters->get('backgroundBlurFit', 7);
$attributes['style'] = implode(';', $blurFitStyle);
$ret = Html::tag('div', $attributes, $picture) . $originalImage;
} else {
$ret = $originalImage;
}
return $ret;
}
/**
* @param Slide $slide
*
* @return string
*/
private function renderBackgroundVideo($slide) {
return '';
}
}