Skip to content

Commit

Permalink
Add improved fotorama + swatches support
Browse files Browse the repository at this point in the history
  • Loading branch information
jissereitsma committed Jan 28, 2021
1 parent f946376 commit 83e9487
Show file tree
Hide file tree
Showing 10 changed files with 262 additions and 55 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.10.0] - 28 January 2021
### Added
- Improved support on product detail page (configurable swatches + fotorama)

## [0.9.6] - 22 January 2021
### Fixed
- When no .webp file is available, the source tag will be removed to prevent old image being shown on the frontend (@ar-vie)
Expand Down
83 changes: 83 additions & 0 deletions Plugin/AddWebpToConfigurableJsonConfig.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<?php declare(strict_types=1);

namespace Yireo\Webp2\Plugin;

use Magento\ConfigurableProduct\Block\Product\View\Type\Configurable;
use Magento\Framework\Serialize\SerializerInterface;
use Yireo\NextGenImages\Exception\ConvertorException;
use Yireo\Webp2\Convertor\Convertor;

class AddWebpToConfigurableJsonConfig
{
/**
* @var SerializerInterface
*/
private $serializer;

/**
* @var Convertor
*/
private $convertor;

/**
* AddImagesToConfigurableJsonConfig constructor.
* @param SerializerInterface $serializer
* @param Convertor $convertor
*/
public function __construct(
SerializerInterface $serializer,
Convertor $convertor
) {
$this->serializer = $serializer;
$this->convertor = $convertor;
}

/**
* @param Configurable $subject
* @param string $jsonConfig
* @return string
* @throws ConvertorException
*/
public function afterGetJsonConfig(Configurable $subject, string $jsonConfig): string
{
$jsonData = $this->serializer->unserialize($jsonConfig);

if (isset($jsonData['images'])) {
$jsonData['images'] = $this->appendImages($jsonData['images']);
}

$jsonConfig = $this->serializer->serialize($jsonData);
return $jsonConfig;
}

/**
* @param array $images
* @return array
* @throws ConvertorException
*/
private function appendImages(array $images): array
{
foreach ($images as $id => $imagesData) {
foreach ($imagesData as $imageDataIndex => $imageData) {
$imageData['thumb_webp'] = $this->getWebpUrl($imageData['thumb']);
$imageData['img_webp'] = $this->getWebpUrl($imageData['img']);
$imageData['full_webp'] = $this->getWebpUrl($imageData['full']);
$imagesData[$imageDataIndex] = $imageData;
}

$images[$id] = $imagesData;
}

return $images;
}

/**
* @param string $url
* @return string
* @throws ConvertorException
*/
private function getWebpUrl(string $url): string
{
return $this->convertor->getSourceImage($url)->getUrl();
}
}
75 changes: 75 additions & 0 deletions Plugin/AddWebpToGalleryImagesJson.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php declare(strict_types=1);

namespace Yireo\Webp2\Plugin;

use Magento\Catalog\Block\Product\View\Gallery;
use Magento\Framework\Serialize\SerializerInterface;
use Yireo\NextGenImages\Exception\ConvertorException;
use Yireo\Webp2\Convertor\Convertor;

class AddWebpToGalleryImagesJson
{
/**
* @var SerializerInterface
*/
private $serializer;

/**
* @var Convertor
*/
private $convertor;

/**
* AddImagesToConfigurableJsonConfig constructor.
* @param SerializerInterface $serializer
* @param Convertor $convertor
*/
public function __construct(
SerializerInterface $serializer,
Convertor $convertor
) {
$this->serializer = $serializer;
$this->convertor = $convertor;
}

/**
* @param Gallery $subject
* @param string $galleryImagesJson
* @return string
* @throws ConvertorException
*/
public function afterGetGalleryImagesJson(Gallery $subject, string $galleryImagesJson): string
{
$jsonData = $this->serializer->unserialize($galleryImagesJson);
$jsonData = $this->appendImages($jsonData);
$jsonConfig = $this->serializer->serialize($jsonData);
return $jsonConfig;
}

/**
* @param array $images
* @return array
* @throws ConvertorException
*/
private function appendImages(array $images): array
{
foreach ($images as $id => $imageData) {
$imageData['thumb_webp'] = $this->getWebpUrl($imageData['thumb']);
$imageData['img_webp'] = $this->getWebpUrl($imageData['img']);
$imageData['full_webp'] = $this->getWebpUrl($imageData['full']);
$images[$id] = $imageData;
}

return $images;
}

/**
* @param string $url
* @return string
* @throws ConvertorException
*/
private function getWebpUrl(string $url): string
{
return $this->convertor->getSourceImage($url)->getUrl();
}
}
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "yireo/magento2-webp2",
"license": "OSL-3.0",
"version": "0.9.6",
"version": "0.10.0",
"type": "magento2-module",
"homepage": "https://www.yireo.com/software/magento-extensions/webp2",
"description": "Magento 2 module to add WebP support to the Magento frontend",
Expand Down
11 changes: 11 additions & 0 deletions etc/frontend/di.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\ConfigurableProduct\Block\Product\View\Type\Configurable">
<plugin name="Yireo_Webp2::addWebpToConfigurableJsonConfig" type="Yireo\Webp2\Plugin\AddWebpToConfigurableJsonConfig"/>
</type>

<type name="Magento\Catalog\Block\Product\View\Gallery">
<plugin name="Yireo_Webp2::addWebpToGalleryImagesJson" type="Yireo\Webp2\Plugin\AddWebpToGalleryImagesJson"/>
</type>
</config>
5 changes: 4 additions & 1 deletion view/frontend/requirejs-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ var config = {
config: {
mixins: {
'Magento_Swatches/js/swatch-renderer': {
'Yireo_Webp2/js/swatch-renderer': true
'Yireo_Webp2/js/swatch-renderer-mixin': true
},
'mage/gallery/gallery': {
'Yireo_Webp2/js/gallery-mixin': true
}
}
}
};
32 changes: 32 additions & 0 deletions view/frontend/web/js/gallery-mixin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
define([
'jquery',
'./has-webp',
"domReady!"
], function ($, hasWebP) {
'use strict';

var mixin = {
initialize: function (config, element) {
if (hasWebP()) {
this._replaceImageDataWithWebp(config.data);
}
this._super(config, element);
},

_replaceImageDataWithWebp: function (imagesData) {
if (_.isEmpty(imagesData)) {
return;
}

$.each(imagesData, function (key, imageData) {
imageData['full'] = imageData['full_webp'];
imageData['img'] = imageData['img_webp'];
imageData['thumb'] = imageData['thumb_webp'];
});
}
};

return function (target) {
return target.extend(mixin);
}
});
18 changes: 18 additions & 0 deletions view/frontend/web/js/has-webp.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
define([], function () {
'use strict';

const createWebPImage = function () {
return new Promise((resolve, reject) => {
var webP = new Image();
webP.onload = () => {
webP.height === 2 ? resolve() : reject()
}
webP.onerror = reject
webP.src = 'data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA';
});
}

return async function hasWebP() {
return await createWebPImage();
}
});
34 changes: 34 additions & 0 deletions view/frontend/web/js/swatch-renderer-mixin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
define([
'jquery',
'./has-webp',
"domReady!"
], function ($, hasWebP) {
'use strict';

return function (widget) {
$.widget('mage.SwatchRenderer', widget, {
_init: function () {
if (hasWebP()) {
this._replaceImageDataWithWebp();
}
this._super();
},

_replaceImageDataWithWebp: function () {
if (_.isEmpty(this.options.jsonConfig.images)) {
return;
}

$.each(this.options.jsonConfig.images, function (key, imagesData) {
$.each(imagesData, function (key, imageData) {
imageData['full'] = imageData['full_webp'];
imageData['img'] = imageData['img_webp'];
imageData['thumb'] = imageData['thumb_webp'];
});
});
}
});

return $.mage.SwatchRenderer;
}
});
53 changes: 0 additions & 53 deletions view/frontend/web/js/swatch-renderer.js

This file was deleted.

0 comments on commit 83e9487

Please sign in to comment.