package ONO::Lib::UI::Image;
################################################################################
# COPYRIGHT / LICENSE #
################################################################################
#
# This file is part of the ONO Software Project.
#
# Copyright (C) 2000-2025 Jos KIRPS [ www.kirps.com | jos_AT_kirps_DOT_com ]
# and The Joopita Project [ www.joopita.org | contact_AT_joopita_DOT_com ]
#
# This file, as well as other parts of the ONO Software Project or related
# elements, are FREE SOFTWARE available under the ARTISTIC LICENSE 2.0.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# For the full license, see /ono/osr/license/LICENSE.txt, or write to
# jos_AT_kirps_DOT_com or contact_AT_joopita_DOT_com.
#
################################################################################
# END OF COPYRIGHT / LICENSE, HERE COMES THE CODE ... #
################################################################################
use strict;
use ONO::IO;
###############################################################################
# image
###############################################################################
#: Display an image.
#:
#: -b border
#: -s shadow
#: -t topbar [use 'screenshot;topbar;topbar_height' as $src]
sub image {
my (
$self,
$src,
$width,
$height,
$border,
$rotate,
$flags,
) = @_;
my ($ROT1,$ROT2,$CLASS,$TOPBAR);
if ($border < 1) {
$border = 0;
}
if ($flags =~ /b/) {
$CLASS .= " bo";
}
if ($flags =~ /t/) {
my @ip = split(/;/,$src);
$src = $ip[0];
$CLASS .= " rel";
$TOPBAR = qq~<img class="block abs" src="$ip[1]" style="width:${width}px;height:$ip[2]px;top:${border}px" alt="">~;
}
if ($rotate) {
if ($border || $flags =~ /(b|s|t)/) {
$ROT2 = ";transform:rotate(${rotate}deg);-ms-transform:rotate(${rotate}deg);-webkit-transform:rotate(${rotate}deg)";
} else {
$ROT1 = ";transform:rotate(${rotate}deg);-ms-transform:rotate(${rotate}deg);-webkit-transform:rotate(${rotate}deg)";
}
}
my $IMG = qq~<img class="block" src="$src" style="width:${width}px;height:${height}px$ROT1" alt="">~;
if ($border || $flags =~ /(b|s|t)/) {
if ($flags =~ /s/) {
$CLASS .= " shadow";
}
$IMG = qq~<div class="bg_white$CLASS" style="width:${width}px;height:${height}px;padding:${border}px$ROT2">$IMG$TOPBAR</div>~;
}
return qq~$IMG~;
}
###############################################################################
# collection
###############################################################################
sub collection {
#: Display a series of images.
shift @_;
my $config = shift @_;
my @images = @_;
my ($STYLE,$COLL);
my @cp = split(/:/,$config);
my @opts = ('width','height','top','left','right',);
for (my $i = 0; $i < 5; $i++) {
# zero is a valid value for $cp!
if ($cp[1] ne "") {
$STYLE .= "$opts[$i]:$cp[$i]px;";
}
}
foreach my $img (@images) {
my @ip = split(/:/,$img);
if ($ip[0] eq "img") {
$COLL .= qq~<div class="abs" style="left:$ip[1]px;top:$ip[2]px">~;
$COLL .= &image("",$ip[3],$ip[4],$ip[5],$ip[6],$ip[7],$ip[8]);
$COLL .= qq~</div>~;
}
}
return qq~<div class="$cp[5]" style="$STYLE">$COLL</div>~;
}
###############################################################################
# slider
###############################################################################
sub slider {
#: Image slider.
my (
$self,
$id,
$SLIDES,
$width,
$height,
) = @_;
if (!$width) {
$width = 640;
}
if (!$height) {
$height = 480;
}
my $STYLE;
if ($width =~ /[0-9]/ && $width !~ /\%/) {
$width = "${width}px";
}
if ($height =~ /[0-9]/) {
$height = "${height}px";
$STYLE = qq~ style="${height}px"~;
}
my $BASE = ONO::IO->base();
return qq~<div id="slider1_container" class="rel" style="margin:0 auto;top:0px;left:0px;width:${width};height:${height};overflow:hidden">
<div data-u="loading" class="jssorl-009-spin" style="position:absolute;top:0px;left:0px;width:100%;height:100%;text-align:center;background-color:rgba(0,0,0,0.7);">
<img style="margin-top:-19px;position:relative;top:50%;width:38px;height:38px;" src="$BASE/ono/osr/javascript/slider/v28/svg/loading/static-svg/spin.svg" alt="">
</div>
<div data-u="slides" style="position: absolute; left: 0px; top: 0px; width:${width};height:${height};overflow: hidden;">
$SLIDES
</div>
<div data-u="navigator" class="jssorb051" style="position:absolute;bottom:12px;right:12px;" data-autocenter="1" data-scale="0.5" data-scale-bottom="0.75">
<div data-u="prototype" class="i" style="width:16px;height:16px;">
<svg viewBox="0 0 16000 16000" style="position:absolute;top:0;left:0;width:100%;height:100%;">
<circle class="b" cx="8000" cy="8000" r="5800"></circle>
</svg>
</div>
</div>
<style>
.jssora051 {display:block;position:absolute;cursor:pointer;}
.jssora051 .a {fill:none;stroke:#fff;stroke-width:360;stroke-miterlimit:10;}
.jssora051 .b {fill:none;stroke:#ccc;stroke-width:1000;stroke-miterlimit:100;}
.jssora051:hover {opacity:.8;}
.jssora051.jssora051dn {opacity:.5;}
.jssora051.jssora051ds {opacity:.3;pointer-events:none;}
.jssorb051 .i {position:absolute;cursor:pointer;}
.jssorb051 .i .b {fill:#fff;fill-opacity:0.5;stroke:#000;stroke-width:400;stroke-miterlimit:10;stroke-opacity:0.5;}
.jssorb051 .i:hover .b {fill-opacity:.7;}
.jssorb051 .iav .b {fill-opacity: 1;}
.jssorb051 .i.idn {opacity:.3;}
</style>
<div data-u="arrowleft" class="jssora051" style="width:55px;height:55px;top:0px;left:25px" data-autocenter="2" data-scale="0.75" data-scale-left="0.75">
<svg viewBox="0 0 16000 16000" style="position:absolute;top:0;left:0;width:100%;height:100%;">
<polyline class="b" points="11040,1920 4960,8000 11040,14080"></polyline>
<polyline class="a" points="11040,1920 4960,8000 11040,14080"></polyline>
</svg>
</div>
<div data-u="arrowright" class="jssora051" style="width:55px;height:55px;top:0px;right:25px;" data-autocenter="2" data-scale="0.75" data-scale-right="0.75">
<svg viewBox="0 0 16000 16000" style="position:absolute;top:0;left:0;width:100%;height:100%;">
<polyline class="b" points="4960,1920 11040,8000 4960,14080"></polyline>
<polyline class="a" points="4960,1920 11040,8000 4960,14080"></polyline>
</svg>
</div>
</div>
~;
}
sub slider_style {
#: Image slider CSS code, deprecated.
return "";
}
sub slider_script {
#: Image slider JS script.
my (
$self,
$interval,
$max_width,
$width_subtract,
) = @_;
if ($interval < 1) {
$interval = 3;
}
if ($width_subtract < 1) {
$width_subtract = 0;
}
my $BASE = ONO::IO->base();
my $MAX_WIDTH = "maxWidth";
if ($max_width) {
$MAX_WIDTH = "Math.min(maxWidth,$max_width)";
}
return qq~<script src="$BASE/ono/osr/javascript/slider/v28/js/jssor.slider.min.js"></script>
<script>
jssor_slider1_init = function () {
var options = {
\$AutoPlay: 1,
\$Idle:${interval}000,
\$DragOrientation: 3,
\$ArrowNavigatorOptions: {
\$Class: \$JssorArrowNavigator\$,
\$ChanceToShow: 2,
\$Steps: 1
},
\$BulletNavigatorOptions: {
\$Class: \$JssorBulletNavigator\$,
\$ChanceToShow: 2,
\$ActionMode: 1,
\$Steps: 1,
\$Rows: 1,
\$SpacingX: 0,
\$SpacingY: 10,
\$Orientation: 1
},
};
var jssor_slider1 = new \$JssorSlider\$('slider1_container', options);
function ScaleSlider() {
var parentWidth = jssor_slider1.\$Elmt.parentNode.clientWidth;
var maxWidth = parentWidth;
var bodyWidth = document.body.clientWidth;
if (bodyWidth < maxWidth) {
maxWidth = bodyWidth;
}
maxWidth = maxWidth - $width_subtract;
if (maxWidth) {jssor_slider1.\$ScaleWidth($MAX_WIDTH)} else {\$Jssor\$.\$Delay(ScaleSlider, 30)}
}
ScaleSlider();
\$Jssor\$.\$AddEvent(window, "load", ScaleSlider);
\$Jssor\$.\$AddEvent(window, "resize", ScaleSlider);
\$Jssor\$.\$AddEvent(window, "orientationchange", ScaleSlider);
};
</script>
<script>jssor_slider1_init();</script>
~;
}
###############################################################################
# end of script
###############################################################################
1;
__END__