Skip to content

Instantly share code, notes, and snippets.

@beshur
Last active May 4, 2020 12:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save beshur/7e63f6774133b0a311c6416df3e931a6 to your computer and use it in GitHub Desktop.
Save beshur/7e63f6774133b0a311c6416df3e931a6 to your computer and use it in GitHub Desktop.
Aegea Lazy Loading

Ленивая загрузка картинок в Эгее

script.js - код, который обнаруживает, что картинка как минимум на 10% в зоне видимости, и начинает загрузку. Надо положить в /user/js и в шаблоне включить, например, в layout.tmpl.php где-то ближе к концу <?php _JS('script'); ?>

Файлы system_neasden_extensions_fotorama.php, system_neasden_extensions_picture.php нужно положить/заменить соответствующие файлы в system/neasden/extensions - fotorama.php и picture.php. Чтобы не заменять файлы полностью, достаточно заменить код возле блоков //CHANGE

  • picture.php - заменяем src на плейсхолдер (надо указать путь к вашей картинке-плейсхолдеру), а оригинальный путь переносим в атрибут data-src
  • fotorama.php - заменяем в коде картинки img на a - в фотораме есть встроенная ленивая загрузка
document.addEventListener("DOMContentLoaded", function() {
let images = [...document.querySelectorAll('img[data-src]')]
const interactSettings = {
threshold: 0.1
}
function onIntersection(imageEntites) {
imageEntites.forEach(image => {
if (image.isIntersecting) {
observer.unobserve(image.target)
image.target.src = image.target.dataset.src
image.target.onload = () => image.target.classList.add('loaded')
}
})
}
let observer = new IntersectionObserver(onIntersection, interactSettings)
images.forEach(image => observer.observe(image))
});
<?php
class NeasdenGroup_fotorama implements NeasdenGroup {
private $neasden = null;
function __construct ($neasden) {
$this->neasden = $neasden;
$neasden->require_line_class ('picture');
$neasden->define_line_class ('fotorama-settings', '\[thumbs\]|\[fotorama .*\]');
$neasden->define_group ('fotorama', '(-picture-){2,}(-fotorama-settings-)?(-p-)*');
}
function render ($group, $myconf) {
$this->neasden->require_link (@$this->neasden->config['library']. 'jquery/jquery.js');
$this->neasden->require_link (@$this->neasden->config['library']. 'fotorama/fotorama.css');
$this->neasden->require_link (@$this->neasden->config['library']. 'fotorama/fotorama.js');
$result = '<div class="'. $myconf['css-class'] .'">'."\n";
$p_opened = false;
$div_opened = false;
foreach ($group as $line) {
if ($line['class'] == 'picture') {
list ($filebasename, $alt) = explode (' ', $line['content'].' ', 2);
$alt = trim ($alt); // usafe
$this->neasden->resource_detected ($filebasename);
$filename = $myconf['folder'] . $filebasename;
$size = getimagesize ($filename);
list ($width, $height) = $size;
if (substr ($filebasename, strrpos ($filebasename, '.') - 3, 3) == '@2x') {
if (! ($width%2 or $height%2)) {
$width /= 2;
$height /= 2;
}
}
if ($width > $myconf['max-width']) {
$height = $height * ($myconf['max-width'] / $width);
$width = $myconf['max-width'];
}
$ratio = 0;
if ($height) $ratio = $width / $height;
// CHANGE
$image_html = (
'<a href="'. $myconf['src-prefix'] . $filebasename .'" '.
'width="'. $width .'" height="'. $height.'" '.
// 'data-caption="'. $alt.'" '.
'alt="'. $alt .'" /></a>'. "\n"
);
if (!$div_opened) {
$result .= (
'<div class="fotorama" '.
'data-width="'. $width .'" '.
'data-ratio="'. $ratio .'"'.
'>'."\n"
);
$div_opened = true;
}
$result .= $image_html;
} elseif ($line['class'] == 'fotorama-settings') {
$settings = substr ($line['content'], 1, -1);
if ($settings == 'thumbs') {
$settings = 'data-nav="thumbs"';
} else {
$settings = str_replace ('fotorama ', '', $settings);
}
$result = str_replace ('class="fotorama"', 'class="fotorama" '.$settings, $result);
} else {
if (!$p_opened) {
$p_opened = true;
if ($div_opened) {
$result .= '</div>' . "\n";
$div_opened = false;
}
$result .= '<div class="e2-text-caption">' . $line['content'];
} else {
$result .= '<br />' . "\n" . $line['content'];
}
}
}
if ($p_opened) {
$result .= '</div>'."\n";
$p_opened = false;
}
if ($div_opened) {
$result .= '</div>'."\n";
$div_opened = false;
}
$result .= '</div>'."\n";
return $result;
}
}
?>
<?php
class NeasdenGroup_picture implements NeasdenGroup {
private $neasden = null;
function __construct ($neasden) {
$this->neasden = $neasden;
$neasden->define_line_class ('picture', '.*\.(jpe?g|gif|png|svg)(?: +(.+))?');
$neasden->define_group ('picture', '(-picture-)(-p-)*');
}
function detect_line ($line, $myconf) {
list ($filebasename, ) = explode (' ', $line, 2);
return is_file ($myconf['folder'] . $filebasename);
}
function render ($group, $myconf) {
$p = false;
$result = '<div class="'. $myconf['css-class'] .'">'."\n";
foreach ($group as $line) {
@list ($filebasename, $alt) = explode (' ', $line['content'], 2);
// check if alt start with an url
@list ($link, $newalt) = explode (' ', $alt, 2);
if (preg_match ('/[a-z]+\:.+/i', $link)) { // usafe
$alt = $newalt;
} else {
$link = '';
}
if ($line['class'] == 'picture') {
$this->neasden->resource_detected ($filebasename);
$filename = $myconf['folder'] . $filebasename;
$pathinfo = pathinfo ($filename);
$width = $height = $ratio = 0;
if ($pathinfo['extension'] == 'svg') {
// echo $filename;
$xmlget = simplexml_load_string (file_get_contents ($filename));
if ($xmlget) {
$xmlattributes = $xmlget->attributes ();
list ($width, $height) = array ((string) $xmlattributes -> width, (string) $xmlattributes -> height);
if (!$width) $width = $myconf['max-width'];
if (!$height) $height = $myconf['max-width'];
}
} elseif ($size = @getimagesize ($filename)) {
list ($width, $height) = $size;
}
if (substr ($filebasename, strrpos ($filebasename, '.') - 3, 3) == '@2x') {
$width /= 2;
$height /= 2;
}
$filename_original = $filename;
$width_original = $width;
// image too wide
if ($width > $myconf['max-width']) {
$height = $height * ($myconf['max-width'] / $width);
$width = $myconf['max-width'];
}
if ($width) $ratio = $height / $width;
// CHANGE
// Replace /clear.gif with the path to your placeholder image
$image_html = (
'<img src="/clear.gif" '.
'data-src="'. $myconf['src-prefix'] . $filebasename .'" '.
'width="'. $width .'" height="'. $height.'" '.
'alt="'. htmlspecialchars ($alt) .'" />'. "\n"
);
if (! $this->neasden->config['html.basic']) {
// wrap into upyachka fix
$image_html = (
'<div style="width: '. $width .'px; max-width: 100%">'.
'<div class="e2-text-picture-imgwrapper" style="'.
'padding-bottom: '. @round ($ratio * 100, 2).'%'.
'">'.
$image_html.
'</div>'.
'</div>'
);
}
// wrap into a link to URL if needed
$cssc_link = $myconf['css-class'] .'-link';
if ($link) {
$image_html = (
// width="'. $width_original .'"
// style="width: '. $width_original .'px"
'<a href="'. $link .'" class="'. $cssc_link .'">' ."\n".
$image_html .
'</a>'
);
}
$result .= $image_html;
} else {
if (!$p) {
$p = true;
$result .= '<div class="e2-text-caption">' . $line['content'];
} else {
$result .= '<br />' . "\n" . $line['content'];
}
}
}
if ($p) $result .= '</div>'."\n";
$result .= '</div>'."\n";
return $result;
}
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment