I am building a webshop in magento.
On the product detailpage i am resizing the image in Magento itself so that it doesn't have to load the very big image.
When i click on the image it should open a lightbox with the image but this time it has to be larger.
But because i resized it the quality really is really low.
There is one other thing which i can't seem to figure out.
I also have some smaller images which should appear as main image when they are hovered over. If i hover over them my resize doesn't work anymore.
I hope someone can point out my mistakes :)
Here is my code:
HTML/PHP code for getting and resizing the image.
<p class="product-image">
<?php
$_img = '<img id="image1" src="'.$this->helper('catalog/image')->init($_product, 'image')->resize(235, 350).'" alt="'.$this->htmlEscape($this->getImageLabel()).'" title="'.$this->htmlEscape($this->getImageLabel()).'" width="235" height="350 " />';
echo $_helper->productAttribute($_product, $_img, 'image');
?>
Javascript code for switching the images on hover.
function imageswitcher(imagename){
jQuery('#image1').attr('src', imagename);
var options = {
zoomrange: [<?php echo Mage::getStoreConfig('featurezoom/zoomrange/start');?>, <?php echo Mage::getStoreConfig('featurezoom/zoomrange/end');?>],
magnifiersize: [<?php echo Mage::getStoreConfig('featurezoom/magnifiersize/height');?>,<?php echo Mage::getStoreConfig('featurezoom/magnifiersize/width');?>],
magnifierpos: '<?php echo Mage::getStoreConfig('featurezoom/general/magnifierpos');?>',
cursorshade: true,
largeimage: imagename //<-- No comma after last option!
}
jQuery('#image1').addimagezoom(options);
}
function doTimer(imageName){
myTimer=setTimeout(function(){
imageswitcher(imagename);
}, 2000);
}
Event.observe(window, 'load', function() {
jQuery('#image1').addimagezoom({
zoomrange: [<?php echo Mage::getStoreConfig('featurezoom/zoomrange/start');?>, <?php echo Mage::getStoreConfig('featurezoom/zoomrange/end');?>],
magnifiersize: [<?php echo Mage::getStoreConfig('featurezoom/magnifiersize/height');?>,<?php echo Mage::getStoreConfig('featurezoom/magnifiersize/width');?>],
magnifierpos: '<?php echo Mage::getStoreConfig('featurezoom/general/magnifierpos');?>',
cursorshade: true,
largeimage: '<?php echo $this->helper('catalog/image')->init($_product, 'image');?>' //<-- No comma after last option!
})
});
jQuery code for opening positioning and closing the lightbox.
(function(window, $, undefined) {
jQuery(function() {
/*$(window).on('click', function(e) {
console.log(e.target);
//e.preventDefault();
});*/
$('.zoomtracker').on('click', function(e) {
removeLightbox();
$('body').css('overflow-y', 'hidden'); // hide scrollbars!
$('<div id="overlay"></div>')
.css('top', $(document).scrollTop())
.css('opacity', '0')
.appendTo('body');
$('<div id="lightbox"></div>')
.hide()
.appendTo('body');
var img = new Image();
img.onload = function() {
var width = img.width,
height = img.height;
$('<img id="lightboxImage" />')
.attr('width', '235')
.attr('src', img.src)
.load(function() {
positionLightboxImage(e);
})
.click(function() {
removeLightbox();
})
.appendTo('#lightbox');
};
img.src = $('#image2').attr('src');
$('#overlay').click(function(e){
})
/*var height = $('<img />').attr('width', .width());
alert(height);
$('<img />')
.attr('src', $(this).attr('href'))
.load(function() {
positionLightboxImage(e);
})
.click(function() {
removeLightbox();
})
.appendTo('#lightbox');
return false;*/
e.preventDefault();
});
});
function positionLightboxImage(e) {
var top = 173;
var left = 271;
/* In plaats van de img width en height de hoogte en breedte van het scherm berekenen en aan de hand heirvan het centrum bepalen. */
$('#lightbox')
.css({
'top': top,
'left': left
})
.fadeIn(500)
.animate({'width': '640','left': '50%', 'margin-left': -($('#lightbox').width()/2), 'top': '19%', 'margin-top': -($('#lightbox').height()/2)}, {queue: false}, 8000);
$('#lightboxImage')
.animate({'width': '550','height': '930'}, {queue: false}, 8000)
}
function removeLightbox() {
$('#overlay, #lightbox')
.fadeOut(500, function() {
$(this).remove();
$('body').css('overflow-y', 'auto'); // show scrollbars!
})
.animate({'width': '235','left': '-72', 'margin-left': ($('#lightbox').width()/2), 'top': '-295', 'margin-top': ($('#lightbox').height()/2)}, {queue: false}, 8000);
$('#lightboxImage')
.animate({'width': '235', 'height': '350'}, {queue: false}, 8000)
}
jQuery.fn.center = function () {
this.css("position","absolute");
this.css("top", Math.max(0, (($(window).height() - this.outerHeight()) / 2) +
$(window).scrollTop()) + "px");
this.css("left", Math.max(0, (($(window).width() - this.outerWidth()) / 2) +
$(window).scrollLeft()) + "px");
return this;
}
})(window, jQuery);
Try to use naturalWidth and naturalHeight methods after image load and your scripts initialised.
jsFiddle example.
var img = $("img")[0];
alert( img.naturalWidth + "x" + img.naturalHeight );
Note: if you wan to do this with another way, you can inspect this answer too: https://stackoverflow.com/a/670433/1428241
Related
I have the following html code that resizes an image:
<img id="my_image" src= "path_to/my_image.png"
style="max-width:50%;
max-height:50%;
width: auto;
height: auto;" />
In the same file, I would like to store in a PHP Session variable the width of the image as it is displayed on the screen (i.e., not the width of the original image my_image.png). Do you know how to do it? Thanks a lot.
In the same file, I can write a Javascript:
<?php
session_start();
$_SESSION['currentWidth'] = "<script>
var img = document.getElementById('my_image');
document.write(img.clientWidth)
</script>
";
echo $_SESSION['currentWidth'];
?>
And it works well. But as soon as I load another PHP page, $_SESSION['currentWidth'] is then empty.
Try this:
<script>
const image = new Image();
image.onload = function() {
document.cookie = 'imgWidth=' + this.width;
document.cookie = 'imgHeight=' + this.height;
}
image.src = 'http://www.google.com/intl/en_ALL/images/logo.gif';
</script>
<?php
echo '<pre>';
var_dump($_COOKIE);
echo '</pre>';
exit;
?>
Via AJAX:
<script>
$( document ).ready( function() {
$( "#my_image" ).on( "unload").on( "load", function() {
var width = document.getElementById("my_image").width ;
var height = document.getElementById("my_image").height;
$.ajax({
type: "POST",
url: "updateSessionSize.php",
data: { "widthAjax": width, "heightAjax":height },
success: function(status){
}
});
return false;
} ).each(function() {
if (this.complete) $(this).trigger('load');
});
} );
</script>
with updateSessionSize.php:
<?php
session_start();
$_SESSION["sizeX"] = $_POST["widthAjax"];
$_SESSION["sizeY"] = $_POST["heightAjax"];
?>
Thank you for the tips.
I am working on drag and drop of images.my drag and drop is working fine.when i drag any image from sidebar and drop it then it shows a control box with dragged item and all this is working fine. Now i need to do the same functionality on click or double click of a image.when user will click any image in sidebar then that image will be automatically dropped in the dropable div area. This is my drag and drop code. Do i need to do same code again on double click of an image?
jQuery(document).ready(function ()
{
dragablediv();
});
function dragablediv()
{
var x = null;
jQuery(".get-image .drag").draggable({
helper: 'clone',
cursor: 'move',
tolerance: 'fit',
revert: true,
/* stop: function (event, ui) { ... } */
});
jQuery(".droppable").droppable({
accept: '.drag',
activeClass: "drop-area",
drop: function (e, ui) {
if (jQuery(ui.draggable)[0].id != "") {
x = ui.helper.clone();
ui.helper.remove();
jQuery("#droppable .resize-img").css({"display":"inline-table"});
/* To show Controls first time on Dragged Image*/
var droppedItemId = ui.draggable.attr("data-item-id");
jQuery(".controls ").attr("controls-item-id",droppedItemId);
jQuery("#droppable").find(".ui-resizable-handle").hide(); // To show Controls
jQuery(".controls").show();
dragEl = jQuery(this);
stopPosition = dragEl.position();
var height = x.height(); // To show the controls with exact position
var width = x.width(); //alert("stoppos"+stopPosition+"leftpos"+leftPos);
var topPos = ui.position.top;
var leftPos = ui.position.left;
var mytop = topPos+height;
var myleft = leftPos + width /2;
//alert("left"+leftPos);
jQuery(".controls").css({"top": mytop , "left":myleft, "display":"block"});
x.draggable({
helper: 'original',
cursor: 'move',
containment: '#droppable',
tolerance: 'fit',
drop: function (event, ui) {
jQuery(ui.draggable).remove();
},
drag: function() {
},
stop: function() {
dragEl = jQuery(this);
stopPosition = dragEl.position();
var leftPos = dragEl.position().left;
var topPos = dragEl.position().top;
stopOffset = dragEl.offset();
document_id = dragEl.data("document-id");
signer_id = dragEl.data("signer-id");
var height = x.height();
var width = x.width();
var mytop = stopPosition.top+height;
//var myleft = stopPosition.left + width /2;
jQuery(".controls").css({"top": mytop , "left":myleft, "display":"block"});
dataItem = jQuery(this).attr('data-item-id');
jQuery("#droppable").find(".ui-resizable-handle").hide();
jQuery(".controls").hide();
jQuery(this).closest(".drag").find(".ui-resizable-handle").show();
jQuery(".controls").show();
jQuery(".controls ").attr("controls-item-id",dataItem);
}
});
x.resizable({
maxHeight: jQuery('#droppable').height(),
maxWidth: jQuery('#droppable').width(),
aspectRatio: true,
helper: "ui-resizable-helper",
handles: "nw, ne, sw,se"
});
//x.addClass('remove');
x.appendTo('.droppable');
}
}
});
}
I am trying to send multiple files with one ajax call .
THe problem is i cant get my progress work out getting this line
TypeError: data.context is undefined
data.context.find('input').val(progress).change();
Cant figure out how to manage progress for each tpl with sendAPI >?I searched a lot try out different thing the basic reason for doing this is i want one ajax request and to have control after that request completes .
MYHTML
<form id="upload" method="post" action="upload.php" enctype="multipart/form-data">
<div>
<div id="drop">
Drop Here <span style="color:white;text-transform:none;font-size: 13px"> OR <span>
<a>Browse</a>
<input type="file" name="upl[]" multiple/>
</div>
<ul>
<!-- The file uploads will be shown here -->
</ul>
</div>
</form>
MY JQUERY
// Initialize the jQuery File Upload plugin
$('#upload').fileupload({
disableImageResize: /Android(?!.*Chrome)|Opera/
.test(window.navigator && navigator.userAgent),
imageMaxWidth: 100,
imageMaxHeight: 100,
maxFileSize: 5000000,
acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i,
dropZone: $('#drop'),
add: function(e, data) {
var type = data.files[0].type;
var size = data.files[0].size;
if ( type == 'image/jpeg' || type == 'image/png' || type == 'image/gif' ) {
if(size<=350000000)
{
// var preview = '<img src="' + URL.createObjectURL(data.files[0]) + '"/>';
var tpl = $('<li class="working"><input type="text" value="0" data-width="48" data-height="48"' +
' data-fgColor="#0788a5" data-readOnly="1" data-bgColor="#3e4043" /><div class="preview"></div><p></p><span></span></li>');
tpl.find('p').text(data.files[0].name).append('<i>' + formatFileSize(data.files[0].size) + '</i>');
loadImage(data.files[0],
function(img) {
tpl.find('.preview').html(img);
},
{
minWidth: 80,
minHeight: 60, maxWidth: 80, maxHeight: 60, contain: true} // Options
);
// Add the HTML to the UL element
data.context = tpl.appendTo(ul);
// Initialize the knob plugin
tpl.find('input').knob();
// Listen for clicks on the cancel icon
tpl.find('span').click(function() {
if (tpl.hasClass('working')) {
jqXHR.abort();
}
tpl.fadeOut(function() {
tpl.remove();
});
});
myfiles.push(data.files[0]);
} else{
noty({type:'error',text: 'file exceeds limit of 350Kb'});
}//check for file type
} else
{
noty({type:'error',text: 'Invalid file type.Please make sure image has valid extension jpeg|gif|jpg'});
}
// $('#post_picture').on('click',function(){
//
//
//
// var jqXHR = data.submit().success(function (result, textStatus, jqXHR) {ar.push(result)});
//
//
// tpl.fadeOut(function() {
// tpl.remove();
// });
// $('#post_picture').off('click');
//
//
//
// });
},
complete:function(e,data)
{
},
progress: function(e, data) {
// Calculate the completion percentage of the upload
var progress = parseInt(data.loaded / data.total * 100, 10);
// Update the hidden input field and trigger a change
// so that the jQuery knob plugin knows to update the dial
data.context.find('input').val(progress).change();
if (progress == 100) {
data.context.removeClass('working');
}
},
fail: function(e, data) {
// Something has gone wrong!
data.context.addClass('error');
}
});
$(document).on('click','#post_picture',function(){
alert('asdas');
$('#upload').fileupload('send', {files: myfiles});
});
This is how i did it Why do these days no body answers :)
var myfiles = [];
// Initialize the jQuery File Upload plugin
$('#upload').fileupload({
disableImageResize: /Android(?!.*Chrome)|Opera/
.test(window.navigator && navigator.userAgent),
imageMaxWidth: 100,
imageMaxHeight: 100,
maxFileSize: 5000000,
acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i,
dropZone: $('#drop'),
add: function(e, data) {
var type = data.files[0].type;
var size = data.files[0].size;
if (type == 'image/jpeg' || type == 'image/png' || type == 'image/gif') {
if (size <= 350000000)
{
// var preview = '<img src="' + URL.createObjectURL(data.files[0]) + '"/>';
var tpl = $('<li class="working"><input type="text" value="0" data-width="48" data-height="48"' +
' data-fgColor="#0788a5" data-readOnly="1" data-bgColor="#3e4043" /><div class="preview"></div><p></p><span></span></li>');
tpl.find('p').text(data.files[0].name).append('<i>' + formatFileSize(data.files[0].size) + '</i>');
loadImage(data.files[0],
function(img) {
tpl.find('.preview').html(img);
},
{
minWidth: 80,
minHeight: 60, maxWidth: 80, maxHeight: 60, contain: true} // Options
);
// Add the HTML to the UL element
data.context = tpl.appendTo(ul);
// Initialize the knob plugin
tpl.find('input').knob();
// Listen for clicks on the cancel icon
tpl.find('span').click(function() {
if (tpl.hasClass('working'))
{
data='';
}
tpl.fadeOut(function() {
tpl.remove();
});
});
// myfiles.push(data.files[0]);
} else {
noty({type: 'error', text: 'file exceeds limit of 350Kb'});
}//check for file type
} else
{
noty({type: 'error', text: 'Invalid file type.Please make sure image has valid extension jpeg|gif|jpg'});
}
$('#post_picture').on('click', function() {
if(data!='')
{
var jqXHR = data.submit().success(function(result, textStatus, jqXHR) {
});
}
tpl.fadeOut(function() {
tpl.remove();
});
$('#post_picture').off('click');
});
},
stop: function(e) {
console.log(myfiles);
},
progress: function(e, data) {
// Calculate the completion percentage of the upload
var progress = parseInt(data.loaded / data.total * 100, 10);
// Update the hidden input field and trigger a change
// so that the jQuery knob plugin knows to update the dial
data.context.find('input').val(progress).change();
if (progress == 100) {
data.context.removeClass('working');
}
},
fail: function(e, data) {
// Something has gone wrong!
data.context.addClass('error');
}
}).on('fileuploaddone', function(e, data) {
myfiles.push(data.result);
});
I have a small problem. i have a link and when i click on this link i want an image to grow to a certain size and move to a certain spot on the screen. Everthing goes fine except that the image pops back to it's original size after the animation is complete.
My project is in Magento so sorry about the weird display of the image
PS: In the img tag it says width="235" height="401".
But the image pops to width=924" and height="1379". These are the dimensions of the actual image.
Here is my HTML code:
<a class="lightbox"href="#">pic</a>
<p class="product-image">
<?php
$_img = '<img id="image1" src="'.$this->helper('catalog/image')->init($_product, 'image').'" alt="'.$this->htmlEscape($this->getImageLabel()).'" title="'.$this->htmlEscape($this->getImageLabel()).'" width="235" height="401 " />';
echo $_helper->productAttribute($_product, $_img, 'image');
?>
And here is my jQuery code:
(function(window, $, undefined) {
jQuery(function(){
$('.lightbox').click(function(e) {
$('body').css('overflow-y', 'hidden'); // hide scrollbars!
var clicked = $('.lightbox').position();
$('<div id="overlay"></div>')
.css('top', $(document).scrollTop())
.css('opacity', '0')
.animate({'opacity': '0.5'}, 'slow')
.appendTo('body');
$('<div id="lightbox"></div>')
.hide()
.appendTo('body');
var img = new Image();
img.onload = function() {
var width = img.width,
height = img.height;
$('<img />')
.attr('src', img.src)
.load(function() {
positionLightboxImage(e, width, height);
})
.click(function() {
removeLightbox();
})
.appendTo('#lightbox');
};
img.src = $('#image1').attr('src');
/*var height = $('<img />').attr('width', .width());
alert(height);
$('<img />')
.attr('src', $(this).attr('href'))
.load(function() {
positionLightboxImage(e);
})
.click(function() {
removeLightbox();
})
.appendTo('#lightbox');
return false;*/
e.preventDefault();
});
});
function positionLightboxImage(e, width, height) {
var top = e.pageY - (height / 2);
var left = e.pageX - (width / 2);
$('#lightbox')
.css({
'top': top,
'left': left
})
.fadeIn(1)
.animate({'width': '50px'}, 3000);
}
function removeLightbox() {
$('#overlay, #lightbox')
.fadeOut('slow', function() {
$(this).remove();
$('body').css('overflow-y', 'auto'); // show scrollbars!
});
}
jQuery.fn.center = function () {
this.css("position","absolute");
this.css("top", Math.max(0, (($(window).height() - this.outerHeight()) / 2) +
$(window).scrollTop()) + "px");
this.css("left", Math.max(0, (($(window).width() - this.outerWidth()) / 2) +
$(window).scrollLeft()) + "px");
return this;
}
})(window, jQuery);
I hope i gave enough information. :)
For anyone who is interested in this answer.
It isn't the best way to fix this.
But using a smaller image for the lightbox and keeping the big image in the data-src did the trick for this situation.
My image gallery has next and previous links, when the user click on either one it loads an image in the #the_image div, but I need the image resize everytime. My thinking I would put the code to resize the image as a callback function for the .load. But's it doesn't work everytime. Odd thing also, if I put an alert("blah"); after image = $('#the_image'); the image get's positioned correctly every time. Any ideas?
Here's my JS:
<script type="text/javascript">
$(document).ready(function() {
$('#previous').live('click', function(e){
$('#img_wrapper').load( $(this).attr('href') + ' #container',function () {
var height = $(window).height();
var width = $(document).width();
var image = $('#the_image');
$("#the_image").css("max-height",height-200);
image.css({
'max-height': height-200,
'left': width/2 - (image.width() /2)-5,
'top': height/2 -(image.height() /2),
});
prev = $('#previous'); next = $('#next');
prev.css({
'left': 0,
'top': (height/2)-150,
});
next.css({
'left': 924,
'top': (height/2)-150,
});
});
e.preventDefault();
});
});
</script>
This is what works. Thanks to Jasper, had to modify his code a bit:
$(function() {
$(document).delegate('#next', 'click', function (e) {
$('#img_wrapper').load( $(this).attr('href') + ' #container',function () {
var height = $(window).height(),
width = $(document).width();
$("#the_image").bind('load', function() {
var image = $('#the_image');
$("#the_image").css("max-height",height-200);
image.css({
'max-height': height-200,
'left': width/2 - (image.width() /2)-5,
'top': height/2 -(image.height() /2),
});
});
$('#previous').css({
'left' : 0,
'top' : ((height / 2) - 150),
});
$('#next').css({
'left' : 924,
'top' : ((height / 2) - 150),
});
});
e.preventDefault();
});
});
The image has to load before you can get it's width/height.
$(function() {
$(document).delegate('#previous', 'click', function (e) {
$('#img_wrapper').load( $(this).attr('href') + ' #container',function () {
var height = $(window).height(),
width = $(document).width();
//here's the fix, we wait for the image to load before changing it's dimensions
$("#the_image").bind('load', function (
$(this).css({
'max-height' : (height - 200),
'left' : (width / 2 - ($(this).width() / 2) - 5),
'top' : (height / 2 - ($(this).height() / 2)),
});
});
$('#previous').css({
'left' : 0,
'top' : ((height / 2) - 150),
});
$('#next').css({
'left' : 924,
'top' : ((height / 2) - 150),
});
});
e.preventDefault();
});
});
Alternatively I would use a different AJAX function so you can add the load event handler to the image before it is added to the DOM (to make sure you can capture the load event before it fires):
$(function() {
$(document).delegate('#previous', 'click', function (e) {
$.get($(this).attr('href'), function (serverResponse) {
var height = $(window).height(),
width = $(document).width();
//here's the fix, we wait for the image to load before changing it's dimensions
serverResponse = $(serverResponse).find('#container');
serverResponse.find('#the_image').bind('load', function (
$(this).css({
'max-height' : (height - 200),
'left' : (width / 2 - ($(this).width() / 2) - 5),
'top' : (height / 2 - ($(this).height() / 2)),
});
});
//add the new HTML to the DOM, `.load()` did this automatically
$('#img_wrapper').html(serverResponse);
$('#previous').css({
'left' : 0,
'top' : ((height / 2) - 150),
});
$('#next').css({
'left' : 924,
'top' : ((height / 2) - 150),
});
});
e.preventDefault();
});
});
Try this, and remember height and width are properties not methods:
Also, don't store objects into variables unless you're going to do more work than dot chaining only once per event fire. Oh and I also forgot... the +"px" will really help for IE!
<script type="text/javascript">
$(document).ready(function() {
$('body #main #wrapper').on('click', '#previous' function(e){
$('#img_wrapper').find("img").attr("src", $(this).attr('href') + ' #container');
var height = $(window).height(), width = $(document).width();
$('#the_image').css({
'max-height': parseInt((height-200), 10)+"px",
'left': parseInt((width/2 - (image.width /2)-5), 10)+"px",
'top': parseInt((height/2 -(image.height /2)), 10)+"px",
});
$('#previous')css({
'left': 0,
'top': parseInt( ((height/2)-150), 10)+"px",
});
$('#next'.css({
'left': 924+"px",
'top': parseInt( ((height/2)-150), 10)+"px",
});
});
e.preventDefault();
});
});
</script>