Media Manager with SVG preview (#4011)

This commit is contained in:
Rike-cz 2019-05-25 14:51:50 +02:00 committed by Denis Denisov
parent a9e198c8b4
commit 83e48c9625
3 changed files with 99 additions and 53 deletions

View File

@ -209,7 +209,7 @@ class MediaManager extends WidgetBase
$thumbnailInfo['lastModified'] = $lastModified;
$thumbnailInfo['id'] = 'sidebar-thumbnail';
return $this->generateThumbnail($thumbnailInfo, $thumbnailParams, true);
return $this->generateThumbnail($thumbnailInfo, $thumbnailParams);
}
/**
@ -1156,8 +1156,7 @@ class MediaManager extends WidgetBase
protected function getThumbnailParams($viewMode = null)
{
$result = [
'mode' => 'crop',
'ext' => 'png'
'mode' => 'crop'
];
if ($viewMode) {
@ -1190,13 +1189,29 @@ class MediaManager extends WidgetBase
$thumbnailParams['width'] . 'x' .
$thumbnailParams['height'] . '_' .
$thumbnailParams['mode'] . '.' .
$thumbnailParams['ext'];
$this->getThumbnailImageExtension($itemPath);
$partition = implode('/', array_slice(str_split($itemSignature, 3), 0, 3)) . '/';
return $this->getThumbnailDirectory().$partition.$thumbFile;
}
/**
* Preferred thumbnail image extension
* @param string $itemPath
* @return string
*/
protected function getThumbnailImageExtension($itemPath)
{
$extension = pathinfo($itemPath, PATHINFO_EXTENSION);
if (in_array($extension, ['png', 'gif', 'webp'])) {
return $extension;
}
return 'jpg';
}
/**
* Returns the URL to a thumbnail
* @param string $imagePath
@ -1296,52 +1311,59 @@ class MediaManager extends WidgetBase
$markup = null;
try {
/*
* Get and validate input data
*/
$path = $thumbnailInfo['path'];
$width = $thumbnailInfo['width'];
$height = $thumbnailInfo['height'];
$lastModified = $thumbnailInfo['lastModified'];
if (!is_numeric($width) || !is_numeric($height) || !is_numeric($lastModified)) {
throw new ApplicationException('Invalid input data');
if ($this->isVector($path)) {
$markup = $this->makePartial('thumbnail-image', [
'isError' => false,
'imageUrl' => Url::to(config('cms.storage.media.path') . $thumbnailInfo['path'])
]);
} else {
/*
* Get and validate input data
*/
$width = $thumbnailInfo['width'];
$height = $thumbnailInfo['height'];
$lastModified = $thumbnailInfo['lastModified'];
if (!is_numeric($width) || !is_numeric($height) || !is_numeric($lastModified)) {
throw new ApplicationException('Invalid input data');
}
if (!$thumbnailParams) {
$thumbnailParams = $this->getThumbnailParams();
$thumbnailParams['width'] = $width;
$thumbnailParams['height'] = $height;
}
$thumbnailPath = $this->getThumbnailImagePath($thumbnailParams, $path, $lastModified);
$fullThumbnailPath = temp_path(ltrim($thumbnailPath, '/'));
/*
* Save the file locally
*/
$library = MediaLibrary::instance();
$tempFilePath = $this->getLocalTempFilePath($path);
if (!@File::put($tempFilePath, $library->get($path))) {
throw new SystemException('Error saving remote file to a temporary location');
}
/*
* Resize the thumbnail and save to the thumbnails directory
*/
$this->resizeImage($fullThumbnailPath, $thumbnailParams, $tempFilePath);
/*
* Delete the temporary file
*/
File::delete($tempFilePath);
$markup = $this->makePartial('thumbnail-image', [
'isError' => false,
'imageUrl' => $this->getThumbnailImageUrl($thumbnailPath)
]);
}
if (!$thumbnailParams) {
$thumbnailParams = $this->getThumbnailParams();
$thumbnailParams['width'] = $width;
$thumbnailParams['height'] = $height;
}
$thumbnailPath = $this->getThumbnailImagePath($thumbnailParams, $path, $lastModified);
$fullThumbnailPath = temp_path(ltrim($thumbnailPath, '/'));
/*
* Save the file locally
*/
$library = MediaLibrary::instance();
$tempFilePath = $this->getLocalTempFilePath($path);
if (!@File::put($tempFilePath, $library->get($path))) {
throw new SystemException('Error saving remote file to a temporary location');
}
/*
* Resize the thumbnail and save to the thumbnails directory
*/
$this->resizeImage($fullThumbnailPath, $thumbnailParams, $tempFilePath);
/*
* Delete the temporary file
*/
File::delete($tempFilePath);
$markup = $this->makePartial('thumbnail-image', [
'isError' => false,
'imageUrl' => $this->getThumbnailImageUrl($thumbnailPath)
]);
}
catch (Exception $ex) {
} catch (Exception $ex) {
if ($tempFilePath) {
File::delete($tempFilePath);
}
@ -1852,4 +1874,14 @@ class MediaManager extends WidgetBase
'folder' => $targetFolder
];
}
/**
* Detect if image is vector graphic (SVG)
* @param string $path
* @return boolean
*/
protected function isVector($path)
{
return (pathinfo($path, PATHINFO_EXTENSION) == 'svg');
}
}

View File

@ -23,8 +23,9 @@ div[data-control="media-manager"] .media-list li .image-placeholder[data-loading
div[data-control="media-manager"] .media-list li .image-placeholder[data-loading]:after {background-image:url('../../../../../../modules/system/assets/ui/images/loader-transparent.svg');background-position:50% 50%;content:' ';-webkit-animation:spin 1s linear infinite;animation:spin 1s linear infinite;background-size:28px 28px;position:absolute;width:28px;height:28px;top:50%;left:50%;margin-top:-14px;margin-left:-14px}
div[data-control="media-manager"] .media-list li i.icon-chain-broken {padding:0;color:#bdc3c7}
div[data-control="media-manager"] .media-list li[data-item-type=folder] i {color:#4ea5e0}
div[data-control="media-manager"] .media-list.list li {height:75px;width:260px;border:1px solid #ecf0f1;background:#f6f8f9}
div[data-control="media-manager"] .media-list.list li {height:75px;width:260px;border:1px solid #ecf0f1;background:#f6f8f9;box-sizing:content-box}
div[data-control="media-manager"] .media-list.list li .icon-container {border-right:1px solid #f6f8f9;width:75px;height:75px;float:left}
div[data-control="media-manager"] .media-list.list li .icon-container img {max-height:75px}
div[data-control="media-manager"] .media-list.list li .icon-container i {font-size:35px}
div[data-control="media-manager"] .media-list.list li .icon-container.image {border-right:1px solid #ecf0f1!important}
div[data-control="media-manager"] .media-list.list li .icon-container p.thumbnail-error-message {display:none}
@ -43,7 +44,8 @@ div[data-control="media-manager"] .media-list.tiles li {width:167px;margin-botto
div[data-control="media-manager"] .media-list.tiles .icon-wrapper {width:167px}
div[data-control="media-manager"] .media-list.tiles li .image-placeholder {width:165px;height:165px}
div[data-control="media-manager"] .media-list.tiles li .image-placeholder[data-loading]:after {background-image:url('../../../../../../modules/system/assets/ui/images/loader-transparent.svg');background-position:50% 50%;content:' ';-webkit-animation:spin 1s linear infinite;animation:spin 1s linear infinite;background-size:55px 55px;position:absolute;width:55px;height:55px;top:50%;left:50%;margin-top:-27.5px;margin-left:-27.5px}
div[data-control="media-manager"] .media-list.tiles li .icon-container {width:167px;height:167px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;border:1px solid #ecf0f1;overflow:hidden;background:#f6f8f9}
div[data-control="media-manager"] .media-list.tiles li .icon-container {width:165px;height:165px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;border:1px solid #ecf0f1;overflow:hidden;background:#f6f8f9;box-sizing:content-box}
div[data-control="media-manager"] .media-list.tiles li .icon-container img {max-height:165px}
div[data-control="media-manager"] .media-list.tiles li .icon-container i {font-size:55px}
div[data-control="media-manager"] .media-list.tiles li .icon-container p {font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"}
div[data-control="media-manager"] .media-list.tiles li.selected .icon-container {background:#4ea5e0 !important;border-color:#2581b8}
@ -55,7 +57,7 @@ div[data-control="media-manager"] .media-list.tiles p.size {margin-bottom:0}
div[data-control="media-manager"] [data-control="sidebar-labels"] {word-wrap:break-word}
div[data-control="media-manager"] .sidebar-group {margin-bottom:20px}
div[data-control="media-manager"] .sidebar-image-placeholder-container {display:table;width:100%}
div[data-control="media-manager"] .sidebar-image-placeholder {display:table-cell;height:225px;position:relative;vertical-align:middle;text-align:center;border-bottom:1px solid #ecf0f1}
div[data-control="media-manager"] .sidebar-image-placeholder {display:table-cell;height:225px;position:relative;vertical-align:middle;text-align:center;border-bottom:1px solid #ecf0f1;box-sizing:content-box}
div[data-control="media-manager"] .sidebar-image-placeholder[data-loading] {background:#ecf0f1}
div[data-control="media-manager"] .sidebar-image-placeholder[data-loading]:after {background-image:url('../../../../../../modules/system/assets/ui/images/loader-transparent.svg');background-position:50% 50%;content:' ';-webkit-animation:spin 1s linear infinite;animation:spin 1s linear infinite;background-size:62px 62px;position:absolute;width:62px;height:62px;top:50%;left:50%;margin-top:-31px;margin-left:-31px}
div[data-control="media-manager"] .sidebar-image-placeholder i.icon-chain-broken,
@ -64,7 +66,7 @@ div[data-control="media-manager"] .sidebar-image-placeholder i.icon-asterisk,
div[data-control="media-manager"] .sidebar-image-placeholder i.icon-level-up {color:#bdc3c7;font-size:55px}
div[data-control="media-manager"] .sidebar-image-placeholder.no-border {border-bottom:none}
div[data-control="media-manager"] .sidebar-image-placeholder p {font-size:12px;margin:10px;line-height:160%;color:#bdc3c7;margin-top:25px}
div[data-control="media-manager"] .sidebar-image-placeholder img {max-width:100%}
div[data-control="media-manager"] .sidebar-image-placeholder img {max-width:100%;max-height:225px}
div[data-control="media-manager"] .list-container {position:relative;z-index:100}
div[data-control="media-manager"] .list-container .no-data {font-size:13px}
div[data-control="media-manager"] .list-container p.no-data {padding:0 20px 20px 20px}

View File

@ -198,6 +198,7 @@ div[data-control="media-manager"] {
width: 260px;
border: 1px solid #ecf0f1;
background: #f6f8f9;
box-sizing: content-box;
}
li .icon-container {
@ -206,6 +207,10 @@ div[data-control="media-manager"] {
height: 75px;
float: left;
img {
max-height: 75px;
}
i {
font-size: 35px;
}
@ -269,12 +274,17 @@ div[data-control="media-manager"] {
}
li .icon-container {
width: 167px;
height: 167px;
width: 165px;
height: 165px;
.border-radius(3px);
border: 1px solid #ecf0f1;
overflow: hidden;
background: #f6f8f9;
box-sizing: content-box;
img {
max-height: 165px;
}
i {
font-size: 55px;
@ -319,6 +329,7 @@ div[data-control="media-manager"] {
vertical-align: middle;
text-align: center;
border-bottom: 1px solid #ecf0f1;
box-sizing: content-box;
&[data-loading] {
background: #ecf0f1;
@ -343,6 +354,7 @@ div[data-control="media-manager"] {
img {
max-width: 100%;
max-height: 225px;
}
}