#||
||
Compatible with: !!(green)**R6.1**!!
Current version: 0.9
Credits: ((user:WikiAdmin WikiAdmin))
| {{toc numerate=1}} ||
||#
Repo: ((source:master/community/action/imageslider.php action/imageslider.php))
CSS image slider
##~{{imageslider}}##
**~action/imageslider.php**
%%(php)
<?php
if (!defined('IN_WACKO'))
{
exit;
}
/*
images as slider
The sole condition is that all the images must be exactly the same size.
version: 0.9
https://wackowiki.org/doc/Dev/PatchesHacks/ImageSlider
*/
$info = <<<EOD
Description:
Showing images as slider for uploaded files.
Usage:
{{imageslider}}
Options:
[page="PageName" or global=1]
[order="time|name_desc|size|size_desc|ext"]
[owner="UserName"]
[media=1]
[max=number]
EOD;
// set defaults
$global ??= 0;
$help ??= 0;
$max ??= null;
$media ??= 1;
$order ??= '';
$owner ??= '';
$page ??= '';
$track ??= 0;
if ($help)
{
$tpl->help = $this->help($info, 'imageslider');
return;
}
if ($max)
{
$limit = $max;
}
else
{
$limit = 50;
}
$order_by = match($order) {
'ext' => 'file_ext ASC',
'name_desc' => 'file_name DESC',
'size' => 'file_size ASC',
'size_desc' => 'file_size DESC',
'time' => 'created ASC',
'time_desc' => 'created DESC',
default => 'file_name ASC',
};
$width_settings = '100%'; // 100%, 300px, etc.
$files = [];
$page_id = null;
// default options for slider
$time_on_slide = 6;
$time_between_slides = 1;
$animation_timing = 'ease';
$slidy_direction = 'left';
$css_animation_name = 'slidy';
// options: data-caption, alt, none
$caption_source = 'data-caption';
$caption_background = 'rgba(0,0,0,0.3)';
$caption_color = '#fff';
$caption_font = 'Avenir, Avenir Next, Droid Sans, DroidSansRegular, Corbel, Tahoma, Geneva, sans-serif';
// options: top, bottom
$caption_position = 'bottom';
// options: slide, perm, fade
$caption_appear = 'slide';
$caption_size = '1.6rem';
// same units
$caption_padding = '.6rem';
if (!$global)
{
if ($page == '')
{
$tag = $this->tag;
$page_id = $this->page['page_id'];
}
else
{
$tag = $this->unwrap_link($page);
if ($_page_id = $this->get_page_id($tag))
{
$page_id = $_page_id;
}
}
$can_view = $this->has_access('read', $page_id) || $this->is_admin() || $this->is_owner($page_id);
}
else
{
$can_view = true;
$tag = $this->tag;
}
if ($can_view)
{
if ($global || ($tag == $this->tag))
{
$filepage = $this->page;
}
else
{
$filepage = $this->load_page($tag, 0, null, LOAD_CACHE, LOAD_META);
}
if (!$global && !isset($filepage['page_id']))
{
return;
}
$selector =
"FROM " . $this->prefix . "file f " .
"INNER JOIN " . $this->prefix . "user u ON (f.user_id = u.user_id) " .
"WHERE f.page_id = " . ($global ? 0 : (int) $filepage['page_id']) . " " .
"AND f.picture_w <> 0 " .
($owner
? "AND u.user_name = " . $this->db->q($owner) . " "
: '') .
"AND f.deleted <> 1 ";
$count = $this->db->load_single(
"SELECT COUNT(f.file_id) AS n " .
$selector, true);
$pagination = $this->pagination($count['n'], $limit, 'f');
// load files list
$files = $this->db->load_all(
"SELECT f.file_id, f.page_id, f.user_id, f.file_size, f.picture_w, f.picture_h, f.file_ext, f.file_lang, f.file_name, f.file_description, f.created, u.user_name AS user " .
$selector .
"ORDER BY f." . $order_by . " " .
"LIMIT {$pagination['offset']}, {$limit}", true);
// display
if (!$global)
{
$path2 = 'file:/' . $tag . '/';
}
else
{
$path2 = 'file:/';
}
if ($factor = count($files))
{
// calculate data for image slider CSS
// count the number of images in the slide, including the new cloned element
$img_count = $factor + 1;
// calculate the total length of the animation by multiplying the number of _actual_ images by the amount of time for both static display of each image and motion between them
$total_time = ($time_on_slide + $time_between_slides) * ($img_count - 1);
// determine the percentage of time an individual image is held static during the animation
$slide_ratio = ($time_on_slide / $total_time) * 100;
// determine the percentage of time for an individual movement
$move_ratio = ($time_between_slides / $total_time) * 100;
// work out how wide each image should be in the slidy, as a percentage.
$base_percentage = 100 / $img_count;
// set the initial position of the slidy element
$position = 0;
$img_width = $img_count * 100;
$slidy = '';
if ($slidy_direction == 'right')
{
$slidy .= "0% \t{ left: -" . (($img_count - 1) * 100) . "%; }\n";
for ($i = $img_count - 1; $i > 0; $i--)
{
$position += $slide_ratio;
// make the keyframe the position of the image
$slidy .= "\t\t" . $position . "% \t{ left: -" . ($i * 100) . "%; }\n";
$position += $move_ratio;
// make the postion for the _next_ slide
$slidy .= "\t\t" . $position . "% \t{ left: -" . (($i - 1) * 100) . "%; }\n";
}
}
else
{
$slidy .= "0% \t{ left: 0%; }\n";
// the slider is moving to the left
for ($i = 0; $i < ($img_count - 1); $i++)
{
$position += $slide_ratio;
// make the keyframe the position of the image
$slidy .= "\t\t" . $position . "% \t{ left: -" . ($i * 100) . "%; }\n";
$position += $move_ratio;
// make the postion for the _next_ slide
$slidy .= "\t\t" . $position . "% \t{ left: -" . (($i + 1) * 100) . "%; }\n";
}
}
$tpl->css = <<<EOD
<style>
div#captioned-gallery {
width: 100%;
overflow: hidden;
}
figure {
margin: 0;
}
figure.slider {
position: relative;
width: {$img_width}%;
font-size: 0;
animation: {$total_time}s {$animation_timing} slidy infinite;
}
figure.slider:hover {
/* animation: animation 1s 16 ease; */
animation-play-state: paused;
}
figure.slider figure {
width: {$base_percentage}%;
height: auto;
display: inline-block;
position: inherit;
}
figure.slider img {
width: {$width_settings};
height: auto;
}
figure.slider figure figcaption {
position: absolute;
bottom: 0;
background: rgba(0,0,0,0.3);
color: #fff;
width: 100%;
font-size: 1rem;
padding: .6rem;
}
div#slider figure {
position: relative;
width: {$img_width}%;
margin: 0;
padding: 0;
font-size: 0;
left: 0;
text-align: left;
animation: {$total_time}s {$animation_timing} slidy infinite;
}
@media screen and (max-width: 500px) {
figure.slider figure figcaption {
font-size: 1.2rem;
}
}
/* figure.slider figure figcaption {
position: absolute;
bottom: -3.5rem;
background: rgba(0,0,0,0.3);
color: #fff;
width: 100%;
font-size: 2rem;
padding: .6rem;
transition: .5s bottom;
}
figure.slider figure:hover figcaption {
bottom: 0;
}
figure.slider figure:hover + figure figcaption {
bottom: 0;
} */
@keyframes slidy {
{$slidy}
}
</style>
EOD;
// adding at the end a clone of the first array for transition loop
$files[] = $files[0];
$n = 0;
$tpl->enter('n_');
foreach($files as $file)
{
if ($file['picture_h']) // missing: svg!
{
$n++;
$this->file_cache[$file['page_id']][$file['file_name']] = $file;
$desc = $this->format($file['file_description'], 'typografica', ['lang' => $file['file_lang']]);
if ($desc == '')
{
$desc = NBSP; // No-Break Space
}
$file_name = $file['file_name'];
$text = $media ? '' : $file_name;
$tpl->image = $this->link($path2 . $file_name, '', $text, '', $track);
$tpl->n = $n;
$tpl->count = $count['n'];
$tpl->desc = $desc;
}
}
$tpl->leave(); // n
}
else
{
$tpl->nofile = $this->_t('FileNotFound');
}
unset($files);
}
else
{
$tpl->noaccess = true;
}
%%
**~action/template/imageslider.tpl**
%%
[ === main === ]
[ ' help ' ]
[ ' css ' ][ ' nofile ' ]
<div id="captioned-gallery">
<figure class="slider">
[= n _ =
<figure>
[ ' image ' ]
<figcaption>[ ' n ' ]/[ ' count ' ] [ ' desc ' ]</figcaption>
</figure>
=]
</figure>
</div>
[= noaccess _ =
[ ' _t: ActionDenied ' ]
=]
%%
===Documentation===
The sole condition is that all the images must be exactly the same size.
===How to===
%%(wacko wrapper=page wrapper_width=600)
{{imageslider}}
%%
##""%%(wacko wrapper=page wrapper_width=600)
{{imageslider}}
%%""##
====local usage of repository====
symlink the gallery action from community action folder in **wacko/action** and **wacko/action/template** folder in repo
##ln -s ../../community/action/imageslider.php imageslider.php##
##ln -s ../../../community/action/template/imageslider.tpl imageslider.tpl##
===Changelog===
0.1 Initial version
0.7 Updated to work with R.6.1 (PHP 8.0, Null coalescing assignment operator)
0.8 added ##order="name_desc"## and changed time field names
0.9 added template
===To Do===
* make parameters like direction, size, time and caption accessible for action
* modify the action for your purpose
{{backlinks}}