I need to send a multiplier to my server so I can properly manage my image. The client can upload images, and onload I want to immediatly figure out the difference between natural and client width. The image is in a container which is 350px and the image is set to min-width: 100%; I tried below, and oddly it worked a few times.
When I run this I get a correct naturalWidth, but clientWidth is 0.
Below is a method from jcrop. And some added functionality to get the natural and client width.
$('#target').Jcrop({
onChange : updatePreview,
onSelect : updatePreview,
aspectRatio : xsize / ysize
}, function() {
// Use the API to get the real image size
var bounds = this.getBounds();
boundx = bounds[0];
boundy = bounds[1];
// Store the API in the jcrop_api variable
jcrop_api = this;
// Move the preview into the jcrop container for css positioning
$preview.appendTo(jcrop_api.ui.holder);
});
function updatePreview(c) {
$('#xmargin').val(Math.round(c.x));
$('#ymargin').val(Math.round(c.y));
$('#x2').val(Math.round(c.w));
$('#y2').val(Math.round(c.h));
var clientW = document.getElementById("target").clientWidth;
var naturalW = document.getElementById("target").naturalWidth;
var multiply = naturalW/clientW;
$('#multiply1').val(clientW); //Returns 0
$('#multiply2').val(naturalW); //Returns correct value
if (parseInt(c.w) > 0) {
var rx = xsize / c.w;
var ry = ysize / c.h;
$pimg.css({
width : Math.round(rx * boundx) + 'px',
height : Math.round(ry * boundy) + 'px',
marginLeft : '-' + Math.round(rx * c.x) + 'px',
marginTop : '-' + Math.round(ry * c.y) + 'px'
});
}
}
Related
This is how I get the click position when clicking on an image to do some image transformation. But my problem is, that the image has the CSS attribute max-width: 1000px. So the code works only for images which are smaller. For larger images the position result is not the real pixel which was clicked on.
My question is, if it is possible to calculate the correct click position for the natural sized image. An alternative would be to set some data attributes with the real image size like data-width: '1200px' and data-height: '1000px'. But still I have to do some calculation.
parentPosition = getPosition(event.currentTarget),
x = event.clientX - parentPosition.x,
y = event.clientY - parentPosition.y;
function getPosition(element) {
var xPosition = 0;
var yPosition = 0;
while (element) {
xPosition += (element.offsetLeft - element.scrollLeft + element.clientLeft);
yPosition += (element.offsetTop - element.scrollTop + element.clientTop);
element = element.offsetParent;
}
return { x: xPosition, y: yPosition };
}
If you know natural size and current size, i think you can just do this:
naturalClickPosX = (naturalWidth / currentWidth) * currentClickPosX;
naturalClickPosY = (naturalHeight / currentHeight) * currentClickPosY;
Have a look at this JSFiddle
HTML
<img src="http://placehold.it/1200x1000" width="1000">
JavaScript
$('img').on("click", function(e){
var $img = $(this);
var currentClickPosX = e.pageX - $img.offset().left;
var currentClickPosY = e.pageY - $img.offset().top;
var currentWidth = $img.width();
var currentHeight = $img.height();
var naturalWidth = this.naturalWidth;
var naturalHeight = this.naturalHeight;
var naturalClickPosX = ((naturalWidth / currentWidth) * currentClickPosX).toFixed(0);
var naturalClickPosY = ((naturalHeight / currentHeight) * currentClickPosY).toFixed(0);
alert("Current X: " + currentClickPosX + " Current Y: " + currentClickPosY +
"\r\nNatural X: " + naturalClickPosX + " Natural Y: " + naturalClickPosY);
});
try this , will work on all sizes
$('.img-coordinate').click(function(e){
var parentOffset = $(e.target).parent().offset();
// here the X and Y on Click
X = e.pageX - $(e.target).offset().left;
Y = e.pageY - $(e.target).offset().top;
alert(X + ' , ' + Y );
});
working fiddel : https://jsfiddle.net/h09kfsoo/
Is it possible to set/update jCrop aspect ratio on select box change?
I've added a ratio and selection variables and worked fine statically but can't get it to work on select change while the select alerts the right values
jQuery(function ($) {
var ratio = 4 / 3
var selection = '[0,0,4,3]';
$("#ratio").change(function () {
var text = $(this).find(':selected').text();
ratio = text;
val = $(this).val();
selection = '[0,0,' + val + ']';
alert(ratio)
}).trigger('change');
// Create variables (in this scope) to hold the API and image size
var jcrop_api,
boundx,
boundy,
// Grab some information about the preview pane
$preview = $('#preview-pane'),
$pcnt = $('#preview-pane .preview-container'),
$pimg = $('#preview-pane .preview-container img'),
xsize = $pcnt.width(),
ysize = $pcnt.height();
console.log('init', [xsize, ysize]);
$('#target').Jcrop({
onChange: updatePreview,
onSelect: updateCoords,
setSelect: selection,
aspectRatio: ratio
}, function () {
// Use the API to get the real image size
var bounds = this.getBounds();
boundx = bounds[0];
boundy = bounds[1];
// Store the API in the jcrop_api variable
jcrop_api = this;
// Move the preview into the jcrop container for css positioning
$preview.appendTo(jcrop_api.ui.holder);
});
$('#coords').on('change', 'input', function (e) {
var x1 = $('#X').val(),
y1 = $('#Y').val();
jcrop_api.setSelect([x, y]);
});
function updatePreview(c) {
if (parseInt(c.w) > 0) {
var rx = xsize / c.w;
var ry = ysize / c.h;
$pimg.css({
width: Math.round(rx * boundx) + 'px',
height: Math.round(ry * boundy) + 'px',
marginLeft: '-' + Math.round(rx * c.x) + 'px',
marginTop: '-' + Math.round(ry * c.y) + 'px'
});
}
};
});
function updateCoords(c) {
$('#X').val(Math.round(c.x));
$('#Y').val(Math.round(c.y));
$('#W').val(Math.round(c.w));
$('#H').val(Math.round(c.h));
};
And here is the select values and text which I'm not stick to:
<select id="ratio">
<option value="4,3">1.3</option>
<option value="6,3">1.6</option>
<option value="9,3">.8</option>
</select>
You can set the Aspect Ratio by:
jcrop_api.setOptions({
aspectRatio: yourAspectRatioValue
});
In your code,
$("#ratio").change(function () {
var text = $(this).find(':selected').text();
ratio = text;
val = $(this).val();
selection = '[0,0,' + val + ']';
jcrop_api.setOptions({
aspectRatio: ratio
});
}).trigger('change');
But place this code after the code where you are applying jCrop on the image.
I'm looking for an effect very similar to this:
http://jsfiddle.net/G5Xrz/
function rnd(max) { return Math.floor(Math.random()*(max+1)) }
function showImage(container, maxwidth, maxheight, imgsrc, imgwidth, imgheight) {
var id = "newimage" + rnd(1000000);
$(container).append(
"<img id='" + id + "' src='" + imgsrc +
"' style='display:block; float:left; position:absolute;" +
"left:" + rnd(maxwidth - imgwidth) + "px;" +
"top:" + rnd(maxheight - imgheight) + "px'>");
$('#' + id).fadeIn();
return id;
}
setInterval(
function() {
showImage("#container", 400, 600,
"http://placekitten.com/" + (90 + rnd(10)) + "/" + (90 + rnd(10)),
100, 100);
}, 700);
But i'd prefer a flexible layout, ie images not bound by a div with predefined height and width, instead responding to the dimensions of the browser.
The following piece of code seems to have a more appropriate way of generating the random positions:
http://jsfiddle.net/Xw29r/15/
function makeNewPosition(){
// Get viewport dimensions (remove the dimension of the div)
var h = $(window).height() - 50;
var w = $(window).width() - 50;
var nh = Math.floor(Math.random() * h);
var nw = Math.floor(Math.random() * w);
return [nh,nw];
}
function animateDiv(){
var newq = makeNewPosition();
var oldq = $('.a').offset();
var speed = calcSpeed([oldq.top, oldq.left], newq);
$('.a').animate({ top: newq[0], left: newq[1] }, speed, function(){
animateDiv();
});
};
However I'm very much a beginner with javascript and I don't know how to combine the two.
Can anyone help?
Thanks
Take this part from the second code:
// Get viewport dimensions (remove the dimension of the div)
var h = $(window).height() - 50;
var w = $(window).width() - 50;
and use those variables h and w with the browser height and width (minus 50) as the appropriate parameters in this part of the first code:
setInterval(
function() {
showImage("#container", 400, 600,
"http://placekitten.com/" + (90 + rnd(10)) + "/" + (90 + rnd(10)),
100, 100);
}, 700);
Also, the first code has this HTML:
<div id="container" style="width:400px; height:600px; background: green; position:relative"></div>
That hard-codes the height and width at pixel values. You can use a CSS percentage value to make the width respond to the parent container's size. However, you will need JS to set the height properly; a percentage for the height does nothing
Putting that all together (and removing the "minus 50" part), you get this:
jsFiddle demo
<div id="container" style="width:100%; height:100px; background: green; position:relative"></div>
function adjustContainerHeight(height) {
$('#container').height(height);
}
adjustContainerHeight($(window).height());
setInterval(
function() {
var h = $(window).height();
var w = $(window).width();
adjustContainerHeight(h);
showImage("#container", w, h,
"http://placekitten.com/" + (90 + rnd(10)) + "/" + (90 + rnd(10)),
100, 100);
}, 700);
This updates the height of the container when the page is first loaded, and once again whenever the random image is placed. More robust code would have a separate height-adjusting event handler that updates the height whenever the page size changes.
I'm currently coding a script in javascript in order to display images into a web page. These images are loaded with an ajax request and a css style is directly applied from jquery. The script works with firefox/Opera/IE, but Google Chrome doesn't display correctly the CSS.
When I debug the HTML page with Google Chrome, the code is correct and the images contain the right css style. If I uncheck and check an attribute in the css editor panel, chrome refreshes the style and displays correctly all the elements.
The code is visible below
function displayCroppedFace(faceData, parentElem) {
var randomid = Math.floor(Math.random() * Math.pow(2, 32));
$("#" + parentElem).append("<div id=\"faceImg_border_" + randomid + "\" />");
$("#faceImg_border_" + randomid).append("<div id=\"faceImg" + randomid + "\" />");
$("#faceImg" + randomid).attr('class','cropped_model');
$('#faceImg' + randomid).append('<img id="faceImg' + randomid + '_img" src="' + faceData.image_url + '"/>');
$('#faceImg' + randomid + '_img').load(function() {
crop($(this), faceData.x, faceData.y, faceData.w, faceData.h);
});
}
function crop(imgObj, x, y, width, height) {
var originalWidth = imgObj.width();
var originalHeight = imgObj.height();
var scale_x = imgObj.parent().width() / (width + 20);
var scale_y = imgObj.parent().height() / (height + 20);
imgObj.css({
'position' : 'absolute',
'display' : 'block',
'left' : (-x * scale_x - 5) + 'px',
'top' : (-y * scale_y - 5) + 'px',
'width' : (originalWidth * scale_x + 10) + 'px',
'height' : (originalHeight * scale_y + 10) + 'px',
'z-index' : '10'
});
}
faceData is a javascript object that contains an image url and four coordinates (x, y, w, h).
Is anybody know what is the problem with Google Chrome and how to do in order to fix this error?
Problem solved! The error was in the CSS.
I am opening a pop up window using window.open function
window.open('some_page.htm','','width=950,height=500');
Now what I want is when user tries to resize the window, the aspect ratio should be maintained i.e., if width is reduced then accordingly height should also get reduced and vice versa. I just want to calculate the new dimensions. So far I have tried this
function ResizeWindow()
{
var iOrignalWidth = 950;
var iOrignalHeight = 500;
var iOuterHeight = window.outerHeight;
var iOuterWidth = window.outerWidth;
var iNewOuterWidth = Math.round((iOrignalWidth / iOrignalHeight) * iOuterHeight);
var iNewOuterHeight = Math.round((iOrignalHeight / iOrignalWidth) * iNewOuterWidth);
alert("New Width: "+ iNewOuterWidth + "\t" + "New Height" + iNewOuterHeight);
}
I know that there's something wrong up there since I am not getting desired results. ANy solution on this ?
You'll want to either adjust the width to the height or visa versa, not both.
In this code, I assumed you want the width adjusted to the height:
function ResizeWindow()
{
var iOrignalWidth = 1000;
var iOrignalHeight = 500;
var iOrginalRatio = iOrignalWidth/iOrignalHeight; // 2
var iOuterWidth = window.outerWidth; // example: 1083
var iOuterHeight = window.outerHeight; //example: 600
var iNewOuterHeight = iOuterHeight; // 600
var iNewOuterWidth = Math.round(iNewOuterHeight*iOrginalRatio); //600 * 2 = 1200
alert("New Width: "+ iNewOuterWidth + "\t" + "New Height" + iNewOuterHeight);
}
I changed to original width to 1000 for the example, but you can change that back in your actual code.
You should do to accoording to one resize for maintain the aspect ratio. For example:
function ResizeWindow()
{
var iOrignalWidth = 950;
var iOrignalHeight = 500;
var iOuterHeight = window.outerHeight;
var iOuterWidth = window.outerWidth;
var w = (window.outerWidth - iOrignalWidth) / iOrignalWidth; // for exam: (1280-950) / 950= 0.34
var h = (window.outerHeight - iOrignalHeight) / iOrignalHeight; // for exam : (800 - 500) / 500= 0.60
var newWidth;
var newHeight;
if (w<h)
{
// If percentage of width is less than percentage of height, Resize should be according to percentage of width.
newWidth = iOrignalWidth * w * 100;
newHeight = iOrignalHeight * w *100;
}
else
{
// If percentage of height is less than percentage of width, Resize should be according to percentage of height.
newWidth = iOrignalWidth * h * 100;
newHeight = iOrignalHeight * h *100;
}
alert("New Width: "+ newWidth + "\t" + "New Height" + newHeight );
}
So that maintain the aspect ratio is always preserved.