I have this problem with a simple cms I'm working on:
I have a simple php function getting image elements from a specified directory, and printing them to the html
<?php if($row["imgs"] == TRUE){ ?>
<div class="imrow">
<?php
$dir = $row["folder"];
$img = glob($dir."*.{jpg,jpeg,png}", GLOB_BRACE);
$tabing = 3;
$scale = sizeof($img);
for ($i = 0; $i < $tabing; $i++) {
echo '<img src="'.$img[$i].'" alt="image" />';
}
?>
</div><?php }//closing the first if of images ?>
(...)
<?php if($row["imgs"] == TRUE) { ?>
<div class="imrow">
<?php
for ($i = $tabing; $i < $scale; $i++) {
if(!($i % $tabing) && ($i!=0)){echo '</div><div class="imrow">';}
echo '<img src="'.$img[$i].'" alt="image" />';
}
?>
</div>
<?php }//second if closing ?>
The style for images and rows:
.imrow {
display: block;
}
.imrow img {
z-index: 10;
float: left;
height: 100%;
cursor: pointer;
transition: transform .5s ease;
box-shadow: 1px 1px 12px rgb(200, 200, 200);
}
And are laid out using a simple jQuery function
$(".imrow").each(function () { // for every row
var row = $(this); //it gives it a name
var rowW = row.width(); //it seals it's width
var imgW = 0; //it sets a image width variable
var fixH = 600; //and get a fixed amount
row.children().each(function () {
$(this).css("height", fixH); //apply fixed height to element in order to get ratio
imgW += $(this).width(); //get the width of this and
$(this).css("height", "100%");
arr.push($(this).attr("src")); // restore
});
row.css("height", rowW / (imgW / fixH) - 2);
});
The problem here is the fact that some of the added Vertical images, turn out horizontal
Here's how it looks in a folder
And how it turns out in the website:
EDIT: This is a php only issue from what I see, because when I analyze the elements in chrome, the images are flipped by default inside, as you all can see here:
So my first bet goes on glob doing something wrong.
Has anyone experienced it, or knows a way to make glob get everything properly?
Bare in mind that this issue only happens to some of the images, and is not depended on the format of the displayed image.
Any help would be extremely useful
It appears the problem was metadata stored in the images that describe the correct orientation.
There is a image-orientation css property that is supposed to be used to display the image in the correct orientation, but it doesn't seem to be supported in all browsers.
The only other solution at the moment is to edit the image's metadata with a metadata editor or, as you have, to open the images in photoshop and save them.
Related
Is there a gallery that have three features:
displays pictures in a lightbox
allows to import tens or hundreds of images at once from a folder
takes descriptions from file names
I have to make it on yesterday :)
I've made my own script together with original Lightbox
http://lokeshdhakar.com/projects/lightbox2/
Decided it will be much faster that way:
<?php
echo str_replace(array('<','>'), array('<','>'),'<table id="galx"><tr>');
$source_dir = 'images/taken/from/here';
$mini_dir = 'mini';
$target_dir = 'imagies/copied/to/there';
$i=0;
$images = array_diff(scandir($source_dir), array('..', '.',$mini_dir));
foreach($images as $image)
{
$filename = pathinfo($image, PATHINFO_FILENAME);
$title = mb_strtoupper(trim(str_replace('_',' ',$filename)));
$s = "<td><a href='$target_dir/$image' data-lightbox='galx' data-title='$title' >"
. "<img src='$target_dir/$mini_dir/$filename.jpg' /><br/>"
. "$title<a/></td>"; //gallery with titles
/*$s = "<td><a href='$target_dir/$image' data-lightbox='galx' >"
. "<img src='$target_dir/$mini_dir/$filename.jpg' />"
. "<a/></td>";*/ //gallery without titles
if (++$i % 5 == 0)
$s .= '</tr><tr>';
$s = str_replace(array('<','>'), array('<','>'), $s); //comment this line if want to paste it as php code
echo $s;
}
echo str_replace(array('<','>'), array('<','>'),'</tr></table>');
?>
Some basic css:
#galx {
width: 650px;
}
#galx td {
text-align: center;
}
#galx a {
display: block;
width: 120px;
font-size: 0.8em;
margin:1px auto;
text-decoration: none;
color: black;
text-align: center;
}
I've used FastStone Image Viewer to batch resize images at once and create miniatures. In app just press F3 to open advanced processing tool.
It just won't work with non-english letters on Windows - PHP bug. It still spoils first non-english letter of file name on Linux, so need to prefix '_' in such cases.
Overall good result - i've hided script somewhere on website and in 1,5 hours generated 6 galleries with ~1,5k pictures, and most of the time was consumed by file processing and copying. Not elegant but effective.
I am using php to loop through and display all images from a directory. This works, however I want to add the image name underneath each of the images. I am struggling to get the text to center underneath it, as it seems to just place it next to it and appears to be in its own column separate to the image.
How do I go about fixing this? From research I've done the general solution seems to be placing them in a div together, I haven't done much php before but am I able to just stick the two echo statements inside of a div tag?
<div id="contentClothing">
<?php
function hoodie() {
$dir = 'images/clothing/hoodies/small/';
$files = scandir($dir);
$images = array();
foreach($files as $file) {
if(fnmatch('*.png',$file)) {
$images[] = $file;
}
if(fnmatch('*.jpg',$file)) {
$images[] = $file;
}
}
foreach($images as $image) {
echo '<img src="images/clothing/hoodies/small/'.$image.'"width=15% height=20% hspace=2% vspace=2% data-big="images/clothing/hoodies/large/'.$image.'" />';
echo '<span>'.$image.'</span>';
}
}
?>
</div>
Here is the css
#contentClothing {
padding-bottom: 5%; /* Height of the footer element */
margin-left: 15%;
}
span {
text-align: center;
}
This is how it looks http://puu.sh/m8Zh0/6b0da6ec03.png
Instead of <span>, use <p> tag. Wrap the whole image and text inside <div> tag and apply your styles to it.
// your code
foreach($images as $image){
echo '<div style="text-align:center; float:left; clear:right;">';
echo '<img src="images/clothing/hoodies/small/'.$image.'"width=15% height=20% hspace=2% vspace=2% data-big="images/clothing/hoodies/large/'.$image.'" />';
echo '<p>'.$image.'</p>';
echo '</div>';
}
// your code
I have a menu that is image based (one yellow and one blue, for example). I designed the buttons in Illustrator and then converted to PNG files. Right now, I'm using CSS for hovering affects.
So when I hover over the image, it changes. So this is good (because it works), but its far from perfect (that's why I'm here)... One of my buttons in CSS looks like this:
.home_menu, .about_menu, .video_menu, .demo_menu, .contact_menu {
float: left;
margin-bottom: 10px;
margin-top: 10px;
margin-left: 10px;
width: 100px;
height: 34px;
display: block;
}
.home_menu {
background: transparent url('../images/buttons/home_but.png');
}
.home_menu:hover {
background-image: url('../images/buttons/home_but_hov.png');
}
The HTML is like started out like so:
<div id="main_menu">
</div>
So basically I'm changing the CSS background image for each class.
Two questions. First, I'm trying to get each menu to be the blue version when on that page. So I wrote a PHP function to do this (in a class), just in case I want to avoid JavaScript. It looks like this:
// Display table and loop through links and images from array
public function print_navigation($image_dir, $ds, $page_nav, $page_nav_alt, $menu) {
$current_file = explode('/', $_SERVER['PHP_SELF']);
$current_page = $current_file[count($current_file) - 1];
$current_page;
//$i = 0;
foreach ($page_nav as $key => $value) {
$menu_output .= '<a href="';
$menu_output .= $key;
$menu_output .= '" id="';
$menu_output .= $menu[$key];
$menu_output .= '" style="background: transparent url(';
if ($current_page == $key) {
$menu_output .= $image_dir . $ds . $page_nav_alt[$key];
}
else {
$menu_output .= $image_dir . $ds . $page_nav[$key];
}
$menu_output .= ');"';
$menu_output .= '></a>';
$i++;
}
echo $menu_output;
}
It seems to work for the Home page ($home variable), but not for the others. I have variables like this (arrays and variables in another file, truncated for brevity):
$menu = array(
$home => 'home_menu',
...);
$page_nav_ylw = array(
$home => $home_but_ylw,
...);
$page_nav_blu = array(
$home => $home_but_blu,
...);
Then I have all the images in variables, referenced to in the arrays, eg, $home_but_ylw refers to the PNG for that button.
The PHP function is a bit odd, because I use the $key for two arrays, which I'm sure is bad. But I'm having a hard time getting it to work otherwise.
Second question is: is there any reason I can't add JavaScript (like jQuery) right on top of this to get me the hover effects so that I can remove it from the CSS? Ideally I'd like to display the buttons with a PHP loop that also handles current page and then do the hover affects with jQuery.
Sorry for the long post. Hope it makes sense.
Thanks in advance!
If you were planning on serving your pages dynamically then I think jQuery would be a much better option. However, if your links are going to separate pages then try something this:
function printNav($Page = "home"){
$HTML = "";
$HTML .= "";
$HTML .= "";
$HTML .= "";
$HTML .= "";
echo $HTML;
}
On each separate page:
<div id="main_menu">
<?php printNav("home"); ?>
</div>
CSS:
.ActiveNav {
background-image: url('../images/buttons/blue_bg.png');
}
.MenuItem {
float: left;
margin-bottom: 10px;
margin-top: 10px;
margin-left: 10px;
width: 100px;
height: 34px;
display: block;
}
.HomeMenuItem {
background: transparent url('../images/buttons/home_but.png');
}
.HomeMenuItem:hover {
background-image: url('../images/buttons/home_but_hov.png');
}
EDIT: If you wanted a different image for each button - I would suggest using a generic button background and hover and putting the text and icons on top of it.
Based on this answer, I was able to find a work around to my problem:
PHP menu navigation
Basically, I used the GET method to get the selected class. This worked nicely. I consolidated my CSS, and was able to get this thing working.
Here is what it turned out like, for one link:
<?php $class = $_GET['selected_tab']; ?>
<div id="main_menu">
<a href="index.php/?selected_tab=home" id="home_menu" title="Home"
class="<?php if(strcmp($class, 'home') == 0) {echo 'selected';} ?>"></a>
CSS like so:
#home_menu {
background: transparent url('../images/buttons/home_but.png');
}
#home_menu:hover, #home_menu.selected {
background-image: url('../images/buttons/home_but_hov.png');
}
Next step is to convert to jQuery.
Thanks Mike GB for your help but it wasn't quite what I was looking for.
I want to generate tooltip based on a dynamically changing background image in css.
This is my my_css.php file.
<?php
header('content-type: text/css');
$i = $_GET['index'];
if($i == 0)
$bg_image_path = "../bg_red.jpg";
elseif ($i == 1)
$bg_image_path = "../bg_yellow.jpg";
elseif ($i == 2)
$bg_image_path = "../bg_green.jpg";
elseif ($i == 3)
$bg_image_path = "../bg_blue.jpg";
?>
.tooltip {
white-space: nowrap;
color:green;
font-weight:bold;
border:1px solid black;;
font-size:14px;
background-color: white;
margin: 0;
padding: 7px 4px;
border: 1px solid black;
background-image: url(<?php echo $bg_image_path; ?>);
background-repeat:repeat-x;
font-family: Helvetica,Arial,Sans-Serif;
font-family: Times New Roman,Georgia,Serif;
filter:alpha(opacity=85);
opacity:0.85;
zoom: 1;
}
In order to use this css I added
<link rel="stylesheet" href="css/my_css.php" type="text/css" media="screen" />
in my html <head> tag of javascript code. I am thinking of passing different values of 'index' so that it would generate the background image dynamically. Can anyone tell me how should I pass such values from a javascript ? I am creating the tooltip using
var tooltip = document.createElement("div");
document.getElementById("map").appendChild(tooltip);
tooltip.style.visibility="hidden";
and I think before calling this createElement, I should set background image.
You seem to be asking two completely independent questions.
First, the way to pass a parameter would be in your <link> tag:
<link rel="stylesheet" href="css/my_css.php?index=3" type="text/css" media="screen" />
When the page loads, the browser will request the css/my_css.php?index=3 page from your server and use the CSS that gets returned.
However, you're also asking about setting this value with JavaScript. That suggests that you want the CSS to change throughout the request. In that case, PHP is absolutely the wrong technology to be using.
Instead, consider adding classes like:
.tooltip-background-1 {
background-image: url(../bg_red.jpg);
}
Then you do not need any dynamic content in the CSS file. Just include all four (or more) rules at once, and use JavaScript to change which class applies to the element.
Finally, if you goal is simply to choose a random background color, you could just let PHP choose the random value, eliminating any need for a parameter or for JavaScript and PHP to interact at all.
I suggest you for improve a part of the code use that:
$bg_image_path = '../bg_';
switch($i)
{
case 0: $bg_image_path .= 'red.jpg'; break;
case 1: $bg_image_path .= 'yellow.jpg'; break;
case 2: $bg_image_path .= 'green.jpg'; break;
case 3: $bg_image_path .= 'blue.jpg'; break;
}
instead of specifying the background image in the css file, try just doing it all with JavaScript. So remove the background-image from the css file and remove all the php and remove the colour (if that is what you want to change when the background image changes), basically anything you need to change, remove from the css and change it with JavaScript.
Then use some code like this:
<html>
<head>
<script type="text/javascript">
var i = 0;
var cols = new Array(8);
cols[0] = "FFFFFF";
cols[1] = "EEEEEE";
cols[2] = "DDDDDD";
cols[3] = "CCCCCC";
cols[4] = "BBBBBB";
cols[5] = "AAAAAA";
cols[6] = "999999";
cols[7] = "888888";
cols[8] = "777777";
var imgs = new Array(8);
img[0] = "img1.jpg";
img[1] = "img2.jpg";
img[2] = "img3.jpg";
img[3] = "img4.jpg";
img[4] = "img5.jpg";
img[5] = "img6.jpg";
img[6] = "img7.jpg";
img[7] = "img8.jpg";
img[8] = "img9.jpg";
function change()
{
document.getElementById("div").bgColor = cols[i];
document.body.background = img[i];
i++;
if(i > 8)
{
i=0;
}
}
</script>
</head>
<body onLoad="setInterval('change()',1000)">
<div id="div">Tooltip</div>
</body>
</html>
This code loops through the array of colors and background images, it will change once per second. It changes the color of the divs background and the backgrounds image.
How would you go about Cutting strings short so it doesnt go to the next line in a div tag For example my message string contained the following:
We prefer questions that can be answered, not just discussed. Provide details. Write clearly and simply. If your question is about this website, ask it on meta instead.
And i want to preferably display it as
We prefer questions that can be answered, not just discussed. Provide ... Read More
Im thinking cutting the string short using PHP but then you have the following problem
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ... Read More
You can see that the above string can still be expanded a bit more. Any way to do this or Not, Thanks in Advance
How you can shorten a string is already answered, but your main question:
How would you go about Cutting strings short so it doesnt go to the next line in a div tag
this will not work in most cases.
for example:
iiiiiiiiii
wwwwwwwwww
You see the problem ?
this only works if your chars have the same width like:
iiiiiiiiii
wwwwwwwwww
Using PHP, you can use the wordwrap function to perform truncation:
function truncate_to_length($text, $length, $text_if_longer = "...")
{
if (strlen($text) > $length)
{
$text = wordwrap($text, $length);
$text = substr($text, 0, strpos($text, "\n"));
return $text . $text_if_longer;
}
return $text;
}
The following mostly works; the main issue is that the "...Read more" notice can cover up part of a letter. It also uses a bunch of presentational elements and requires JS. It makes me feel unclean.
The outermost element (of class .string) is used to set the overall size. .text holds the text to display. Between .string and .text in the descendent hierarchy is an element with a large width. This puts all the text in .text on one line. JS is used to show or hide the "...Read more" notice.
<style type="text/css">
.string {
height: 1em;
width: 25%;
position: relative; /* create containing block for children */
border: 1px solid black;
overflow: hidden;
background: white; /* or whatever, as long as it's not "transparent". */
}
.string .line {
width: 5000px; /* long enough for you? */
}
.string .notice {
position: absolute;
top: 0;
right: 0;
z-index: 1;
display: none;
background: inherit; /* so that the notice will completely cover up whatever's beneath */
}
</style>
<div class="string">
<div class="line"><span class="text">We prefer questions that can be answered,
not just discussed. Provide details. Write clearly and simply. If your
question is about this website, ask it on meta instead.</span></div>
</div>
<hr />
<div class="string">
<div class="line"><span class="text">Lorem ipsum dolor sit amet.</span></div>
</div>
<script>
function isOverflowed(elt) {
return elt.offsetWidth > elt.parentNode.parentNode.clientWidth;
}
function getNotice(textElt) {
try {
return (textElt.parentNode.parentNode.getElementsByClassName('notice'))[0];
} catch (e) {
return {style: {}};
}
}
function show(elt) {
elt.style.display = 'block';
}
function hide(elt) {
elt.style.display = 'none';
}
function showReadMoreNotices() {
var text=document.getElementsByClassName('text');
for (var i=0; i<text.length; ++i) {
if (isOverflowed(text[i])) {
show(getNotice(text[i]));
} else {
hide(getNotice(text[i]));
}
}
}
var strings = document.getElementsByClassName('string');
var notice = document.createElement('div');
notice.appendChild(document.createTextNode('\u2026Read more'));
notice.className = 'notice';
for (var i=0; i<strings.length; ++i) {
strings[i].appendChild(notice.cloneNode(true));
}
showReadMoreNotices();
/* use your favorite event registration method here. Not that the traditional
* model is my favorite, it's just simple.
*/
window.onresize = showReadMoreNotices;
</script>
Check the size, if the size is greater than your maximum, take the leftmost characters.
Leftmost # = Total size - size("... read more").
Then append the read more to the left most characters.
Jacob
Here is an example taken from http://snippetdb.com/php/truncate-string:
function Truncate ($str, $length=10, $trailing='...')
{
// take off chars for the trailing
$length-=strlen($trailing);
if (strlen($str) > $length)
{
// string exceeded length, truncate and add trailing dots
return substr($str,0,$length).$trailing;
}
else
{
// string was already short enough, return the string
$res = $str;
}
return $res;
}
Oooo i came up with something that works but not works completely... Id like to share
div.string{
height:15px;
overflow:hidden;
}
It solves the problem that it will hide the whole word that wont fit in to the end of line.., because of the overflow and the height is set to one line only. However the above still dosent do the Problem shown by Rufinus:
iiiiiiiiiiiiii
wwwwwwwwwwwwww
This is a function picked from smarty templates that shortens strings without cutting them.
function str_short($string, $length = 80, $etc = '...', $break_words = false, $middle = false) {
if ($length == 0)
return '';
if (strlen($string) > $length) {
$length -= min($length, strlen($etc));
if (!$break_words && !$middle) {
$string = preg_replace('/\s+?(\S+)?$/', '', substr($string, 0, $length+1));
}
if(!$middle) {
return substr($string, 0, $length) . $etc;
} else {
return substr($string, 0, $length/2) . $etc . substr($string, -$length/2);
}
} else {
return $string;
}
}
It all depends on the font. Of course, you can use a monospace font, but that isn't a solution. Anyway, why would you like to do this? Even if you manage to make it work on a certain font, it might be that an user doesn't have it. Then a different font will be used, and everything may break...
It would be basically impossible to do this in PHP with a non monospace font (even with a monospace font, it is difficult to tell exactly how long a string in going to be in a certain browser. The only way I can think of doing this in a browser is to put it in a and set the width of a the span to be a certain width then use overflow: hidden.
Depending on what browser you're using, this one line of CSS could do the trick:
div.string {
word-wrap: break-word;
}
If you know what true-type font the browser is using, you can use the imagettfbbox() in the GD library to calculate the width of your text. Then iterate and drop characters off of the end of the text until it fits into your div.
This may not be very efficient, I know that, but it does the job. You could fine-tune and optimize for your specific solution.
<?
$width = 280; // max. width in pixels that the text should have
$font = 'C:\Windows\Fonts\verdana.TTF';
$text = 'The quick brown fox jumps over the lazy dog';
function getWidth($text) {
list($x1, , $x2) = imagettfbbox(12, 0, $font, $text);
return $x2-$x1;
}
while (getWidth($text.'...') > $width) $text = substr($text, 0, -1);
?>
<style type='text/css'>
#my_div {
font-family: Verdana;
font-size: 12pt;
border: 1px solid black;
width: 280px;
padding: 0
}
</style>
<div id='my_div'>
<?=$text?>...
</div>