Container height based on every 2 images row - javascript

I´m working on this website
I´m doing the resize of vertical images using this script:
function Gallery(selector) {
this.add_module = function (type, image) {
var portrait_text = image.next('.portrait_text');
var container = $('<div />', {
'class': 'gallery_container'
}).append(image).append(portrait_text);
if (type == 'horizontal') {
var h_ar = image.attr('height') / image.attr('width');
var c_width = selector.width();
var c_height = selector.width() * h_ar
container.css({
'width': c_width,
'height': c_height
})
}
if (type == 'vertical') {
var c_width = v_width;
var c_height = v_height
container.css({
'width': Math.floor(v_width),
'height': v_height
})
}
container.css({
'float': 'left',
})
container.find('img').attr({
'width': '100%',
'height': '100%'
})
container.attr('ar', c_height / c_width)
container.appendTo(selector);
//container.children('img').fitToBox();
}
this.resized = function () {
//console.log(sel)
$('.gallery_container').each(function () {
if ($(this).attr('ar') >= 1) { // vertical
$(this).css({
'width': sel.width() / 2,
'height': sel.width() / 2 * $(this).attr('ar')
})
} else { // horizontal
$(this).css({
'width': sel.width(),
'height': sel.width() * $(this).attr('ar')
})
}
})
}
var _this = this;
var gutter = 0;
// start vars for counting on vertical images
var v_counter = 0;
var w_pxls = 0;
var h_pxls = 0;
var v_ar;
// iterates through images looking for verticals
selector.children('img').each(function () {
if (parseInt($(this).attr('width')) < parseInt($(this).attr('height'))) {
v_counter++;
h_pxls += $(this).attr('height');
w_pxls += $(this).attr('width');
v_ar = $(this).attr('height') / $(this).attr('width')
}
})
// calculates average ar for vertical images (anything outside from aspect ratio will be croped)
var h_avrg = Math.floor(h_pxls / v_counter);
var w_avrg = Math.floor(w_pxls / v_counter);
var v_width = Math.floor((selector.width()) / 2);
var v_height = v_width * v_ar;
var sel = selector;
selector.children('img').each(function () {
if (parseInt($(this).attr('width')) > parseInt($(this).attr('height'))) {
_this.add_module('horizontal', $(this));
} else {
_this.add_module('vertical', $(this));
}
})
$(window).bind('resize', _this.resized);
}
var gallery = new Gallery($('#gallery_images_inner'));
http://jsfiddle.net/mZ2Ks/
The problem I have is that the script makes all the container the same of height (depending on the last image on the page I think), so for example first images resizes in a bad way. If you look at the example, all 2 image rows have a height of 613px.
Is there any way how can I control each two images container to calculate it´s own height based on its images, it looks like right now it calculates the last image resize height and apply it to all other containers
Applying height: auto instead of 100% won´t work cause it will not make the images fit the height of the vertical container.
How can I fix the script?

yes, there is a easy way. but frist: your gallery-script calculates a average aspect ratio for all images inside. there is no simple way to change this behavior.
But you can do this simple workaround: put echt two images in their own gallery!
var gallery1 = new Gallery($('#gallery_images_inner1'));
var gallery2 = new Gallery($('#gallery_images_inner2'));
var gallery3 = new Gallery($('#gallery_images_inner3'));
See http://jsfiddle.net/mZ2Ks/2/ - i had to clean up your html code a little bit - you copied the "javascript affected" html code from (i assume) firebug, but you should have copied the plain html from source code direct (CTRL + U in firefox).

Related

how to animate canvas using this plug in

Im still new to this type of programming, im trying to create kaledoscope kind of effect to be projected on screen. I want to make the image move isnide each section of the effect. is there a way to move it? i cant seem to target the canvas created by the plug in.
https://codepen.io/muspelheim/pen/gpymF
var images = [
"http://media-cache-ak0.pinimg.com/736x/5d/d8/41/5dd8416cbae27edeac61aa525a5df99d.jpg",
"https://1.bp.blogspot.com/-FpxaoVBBxXs/T5aWaP2dMDI/AAAAAAAAAw8/qdaPYyuqSt8/s1600/spugnaepicinfame.jpg",
"https://25.media.tumblr.com/tumblr_m9ls7nRTuR1rvqbato1_1280.jpg",
"https://3.bp.blogspot.com/-SJAKrZTcqwI/T5kwYk71YCI/AAAAAAAAAxE/HNlX3i2-xwk/s1600/spugnabimbofango.jpg"
];
// Let's create graphemescope object inside the container
var container = $("#container");
var scope = new Graphemescope( container[0] );
var index = 0;
function changePicture() {
scope.setImage(images[index]);
index = (index + 1) % images.length;
};
setInterval(changePicture, 2000);
changePicture();
$(window).mousemove(function(event) {
var factorx = event.pageX / $(window).width();
var factory = event.pageY / $(window).height()
// This will move kaleidoscope
scope.angleTarget = factorx;
scope.zoomTarget = 1.0 + 0.5 * factory;
});
var resizeHandler = function() {
container.height( $(window).height() );
container.width( $(window).width() );
};
$(window).resize(resizeHandler);
$(window).resize();
container.click(changePicture);

How to prevent randomly positioned images from overlapping using Angular

I have an Angular application that loads multiple images on to the page at random locations by utilizing the following code:
HTML:
<div ng-repeat="s in selectedImages" class="container">
<img ng-src="{{s.img}}" class="sImage" ng-style="s.pos"/>
</div>
CSS:
.wordImage {
position:absolute;
width:100px;
}
JS Controller:
function loadImages() {
$scope.myImages = ['img1.png', 'img2.png', 'img3.png', 'img4.png', 'img5.png']
$scope.selectedImages = [];
for (i in $scope.myImages) {
$scope.selectedImages.push(addRandomLocationToImage($scope.myImages[i]));
}
}
function addRandomLocationToImage(image) {
image.pos = {};
var preTop = getRandomHeight(); // get Height for this image
var preLeft = getRandomWidth(); // get Width for this image
image.pos = {top:preTop,
left:preLeft};
return image; // returns the same image object but contains pos{} for ng-style
}
function getRandomHeight() {
var imgHeight = 100;
var winHeight = $(window).height();
var randomH = Math.random() * (winHeight - 100); // subtract 100 for the header. and also footer padding
if (randomH < 150) {
randomH += 150; // add to keep it out of the header
}
if(winHeight - randomH < 100) { // if image will be on bottom edge of page
randomW -= imgHeight; // subtract 100 because that is the height of the images, this will prevent them from being partially off the page
}
return randomH;
}
function getRandomWidth() {
var imgWidth = 100;
var winWidth = $(window).width();
var randomW = Math.random() * winWidth;
if (randomW < 0) { // make sure it is not less than zero, then assign new number until it is greater than zero
while (randomW < 0) {
randomW = Math.random() * winWidth;
}
}
if (winWidth - randomW < 100) { // if image will be on right edge of page
randomW -= imgWidth; // subtract 100 because that is the width of the images, this will prevent them from being partially off the page
}
return randomW;
}
loadImages();
This definitely generates random images on a page...but they overlap very easily. My question is, how can I prevent them from overlapping? Here is some code that I have been working on.
var newLeft = currentImage.pos.left;
var newTop = currentImage.pos.top;
for (i in $scope.selectedImages) {
var originalLeft = $scope.selectedImages[i].pos.left;
var originalTop = $scope.selectedImages[i].pos.top;
if ((originalLeft - newLeft < 100 && originalLeft - newLeft > -100) && // could overlap horizontally
(originalTop - newTop < 100 && originalTop - newTop > -100)) { // could overlap vertically
//do something to select a new random location.
}
}
Basically you have to check a image position with every other image. You can use Array.some for this:
Considering that you store the image position in the image object as
x and y properties
function checkCollision(testImage) {
return $scope.myImages.some(function(img) {
if (img == testImage)
return false;
if (!img.x || !img.y) // Image has no position yet
return false;
return
testImage.x < img.x + imgWidth &&
testImage.x + imgWidth > img.x &&
testImage.y < img.y + imgHeight &&
testImage.y + imgHeight > img.y;
});
}
You have to be aware that depending of the available space and image sizes there might be a situation where is not possible to find a suitable position for a image.
I made a functional example.

fengyuanchen Cropper - How to Fit Image into Canvas If Rotated?

I gone through documentation of cropper by fengyuanchen. I want the image to be fit by default into canvas if rotated. But I couldnt find a way to achieve this. Any idea how to achieve this functionality?
I want it to be like this to be default: link
Check issue demo here: link
I fixed this behavior but for my special needs. I just needed one rotate button which rotates an image in 90° steps. For other purposes you might extend/change my fix.
It works in "strict" mode by dynamically change the cropbox dimensions.
Here my function which is called, when I want to rotate an image. Ah and additionally the misplacement bug has also been fixed.
var $image;
function initCropper() {
$image = $('.imageUploadPreviewWrap > img').cropper({
autoCrop : true,
strict: true,
background: true,
autoCropArea: 1,
crop: function(e) {
}
});
}
function rotateImage() {
//get data
var data = $image.cropper('getCropBoxData');
var contData = $image.cropper('getContainerData');
var imageData = $image.cropper('getImageData');
//set data of cropbox to avoid unwanted behavior due to strict mode
data.width = 2;
data.height = 2;
data.top = 0;
var leftNew = (contData.width / 2) - 1;
data.left = leftNew;
$image.cropper('setCropBoxData',data);
//rotate
$image.cropper('rotate', 90);
//get canvas data
var canvData = $image.cropper('getCanvasData');
//calculate new height and width based on the container dimensions
var heightOld = canvData.height;
var heightNew = contData.height;
var koef = heightNew / heightOld;
var widthNew = canvData.width * koef;
canvData.height = heightNew;
canvData.width = widthNew;
canvData.top = 0;
if (canvData.width >= contData.width) {
canvData.left = 0;
}
else {
canvData.left = (contData.width - canvData.width) / 2;
}
$image.cropper('setCanvasData', canvData);
//and now set cropper "back" to full crop
data.left = 0;
data.top = 0;
data.width = canvData.width;
data.height = canvData.height;
$image.cropper('setCropBoxData',data);
}
This is my extended code provided by AlexanderZ to avoid cuttong wider images than container :)
var contData = $image.cropper('getContainerData');
$image.cropper('setCropBoxData',{
width: 2, height: 2, top: (contData.height/ 2) - 1, left: (contData.width / 2) - 1
});
$image.cropper('rotate', 90);
var canvData = $image.cropper('getCanvasData');
var newWidth = canvData.width * (contData.height / canvData.height);
if (newWidth >= contData.width) {
var newHeight = canvData.height * (contData.width / canvData.width);
var newCanvData = {
height: newHeight,
width: contData.width,
top: (contData.height - newHeight) / 2,
left: 0
};
} else {
var newCanvData = {
height: contData.height,
width: newWidth,
top: 0,
left: (contData.width - newWidth) / 2
};
}
$image.cropper('setCanvasData', newCanvData);
$image.cropper('setCropBoxData', newCanvData);
Not a direct answer to the question ... but i'm betting many people that use this plugin will find this helpfull..
Made this after picking up #AlexanderZ code to rotate the image.
So ... If you guys want to ROTATE or FLIP a image that has already a crop box defined and if you want that cropbox to rotate or flip with the image ... use these functions:
function flipImage(r, data) {
var old_cbox = $image.cropper('getCropBoxData');
var new_cbox = $image.cropper('getCropBoxData');
var canv = $image.cropper('getCanvasData');
if (data.method == "scaleX") {
if (old_cbox.left == canv.left) {
new_cbox.left = canv.left + canv.width - old_cbox.width;
} else {
new_cbox.left = 2 * canv.left + canv.width - old_cbox.left - old_cbox.width;
}
} else {
new_cbox.top = canv.height - old_cbox.top - old_cbox.height;
}
$image.cropper('setCropBoxData', new_cbox);
/* BUG: When rotated to a perpendicular position of the original position , the user perceived axis are now inverted.
Try it yourself: GO to the demo page, rotate 90 degrees then try to flip X axis, you'll notice the image flippped vertically ... but still ... it fliped in relation to its original axis*/
if ( r == 90 || r == 270 || r == -90 || r == -270 ) {
if ( data.method == "scaleX") {
$image.cropper("scaleY", data.option);
} else {
$image.cropper("scaleX", data.option);
}
} else {
$image.cropper(data.method, data.option);
}
$image.cropper(data.method, data.option);
}
function rotateImage(rotate) {
/* var img = $image.cropper('getImageData'); */
var old_cbox = $image.cropper('getCropBoxData');
var new_cbox = $image.cropper('getCropBoxData');
var old_canv = $image.cropper('getCanvasData');
var old_cont = $image.cropper('getContainerData');
$image.cropper('rotate', rotate);
var new_canv = $image.cropper('getCanvasData');
//calculate new height and width based on the container dimensions
var heightOld = new_canv.height;
var widthOld = new_canv.width;
var heightNew = old_cont.height;
var racio = heightNew / heightOld;
var widthNew = new_canv.width * racio;
new_canv.height = Math.round(heightNew);
new_canv.width = Math.round(widthNew);
new_canv.top = 0;
if (new_canv.width >= old_cont.width) {
new_canv.left = 0;
} else {
new_canv.left = Math.round((old_cont.width - new_canv.width) / 2);
}
$image.cropper('setCanvasData', new_canv);
if (rotate == 90) {
new_cbox.height = racio * old_cbox.width;
new_cbox.width = racio * old_cbox.height;
new_cbox.top = new_canv.top + racio * (old_cbox.left - old_canv.left);
new_cbox.left = new_canv.left + racio * (old_canv.height - old_cbox.height - old_cbox.top);
}
new_cbox.width = Math.round(new_cbox.width);
new_cbox.height = Math.round(new_cbox.height);
new_cbox.top = Math.round(new_cbox.top);
new_cbox.left = Math.round(new_cbox.left);
$image.cropper('setCropBoxData', new_cbox);
}
var photoToEdit = $('.photo_container img');
$( photoToEdit ).cropper({
autoCrop : true,
crop: function(e) {}
});
$("#rotate_left_btn").click( function () {
$( photoToEdit ).cropper('rotate', -90);
var containerHeightFactor = $(".photo_container").height() / $( photoToEdit).cropper('getCanvasData').height;
if ( containerHeightFactor < 1 ) { // if canvas height is greater than the photo container height, then scale (on both x and y
// axes to maintain aspect ratio) to make canvas height fit container height
$( photoToEdit).cropper('scale', containerHeightFactor, containerHeightFactor);
} else if ( $( photoToEdit).cropper('getData').scaleX != 1 || $( photoToEdit).cropper('getData').scaleY != 1 ) { // if canvas height
// is NOT greater than container height but image is already scaled, then revert the scaling cuz the current rotation will bring
// the image back to its original orientation (landscape/portrait)
$( photoToEdit).cropper('scale', 1, 1);
}
}
I Fixed this issue hope fully. i have added or changed the option to 0 (viewMode: 0,). Now its working well.
cropper = new Cropper(image, {
dragMode: 'none',
viewMode: 0,
width: 400,
height: 500,
zoomable: true,
rotatable: true,
crop: function(e) {
}
});
document.getElementById('rotateImg').addEventListener('click', function () {
cropper.rotate(90);
});

Auto scrolling to element in scrollable div

I have 5 elements that are within a div larger than the screen (on a mobile phone).
I want the user to be able to click on one of the elements and have that element scroll to the centre of the screen.
I've tried writing this with jQuery myself, but I can't seem to get the logic quite right. I've got it kind of moving but the element selected doesn't go to the centre of the screen.
Here's a Fiddle of what I have do far: http://jsfiddle.net/geQ64/1/
Here's the JS from the fiddle also:
$(window).on('load', function() {
$('.tab-3').trigger('click');
var width = $(window).width();
if (width < 651) {
$('.ul-wrap').scrollLeft( $('.tab-3').offset().left );
}
});
$('.single-tabs').on('click', function() {
var offset = $('.tabs').width();
offset = offset/5;
var center = offset/2;
var tab = $(this).data('tab');
$('.tabs-content').hide();
$('.tab'+ tab +'').show();
var width = $(window).width();
if (width > 650) {
var arrow = tab*20-12;
$('.arrow-up').css('margin-left', '' + arrow + '%');
} else {
tab = tab - 1;
var position = offset * tab - center;
$('.ul-wrap').scrollLeft(position);
}
});
Found a fix, here's the JS is anyone needs it.
The - 55 in the var position is for an arrow that sits in the centre of the page below the elements I'm moving with this script.
$(window).on('load', function() {
$('.tab-3').trigger('click');
var width = $(window).width();
if (width < 651) {
var offset = $('.tabs').width();
offset = offset/7;
var center = offset/2;
var position = offset * 2 + center - 50;
$('.ul-wrap').animate({
scrollLeft: position
}, 200);
}
});
$('.single-tabs').on('click', function() {
var offset = $('.tabs').width();
offset = offset/7;
var center = offset/2;
var tab = $(this).data('tab');
$('.tabs-content').hide();
$('.tab'+ tab +'').show();
var width = $(window).width();
if (width > 650) {
var arrow = tab*20-12;
$('.arrow-up').css('margin-left', '' + arrow + '%');
} else {
tab = tab - 1;
var position = offset * tab + center - 50;
$('.ul-wrap').animate({
scrollLeft: position
}, 200);
}

Different images loaded for different web screen sizes

I have this code which loads automatically a different picture from an array everytime a user loads index.html. This is the jquery code:
$(window).load(function() {
var randomImages = ['img1','img2','img3','img4','img5'];
var rndNum = Math.floor(Math.random() * randomImages.length);
var $win = $(this);
var $img = $('#background').attr('src', '_img/bg/index_rnd/' + randomImages[rndNum] + '.jpg').css({'position':'fixed','top':0,'left':0});
function resize() {
if (($win.width() / $win.height()) < ($img.width() / $img.height())) {
$img.css({'height':'100%','width':'auto'});
} else {
$img.css({'width':'100%','height':'auto'});
}
}
$win.resize(function() { resize(); }).trigger('resize');
});
I'm new with adapting images to different screen resolutions. So I thought that if somebody opens my web with for example an imac with 2560/1440px the image will be adapted correctly with this code, but I suppose it will be completely pixeled. So I think, I have to create a larger image file so those computers load the bigger file to adapt in resolution. I want to avoid that other users with a normal screen load the big file for speed reasons. What could I add to this code to make bigger screens load a bigger file so it doesnt pixalate?!?!
P.D. If you also know which is the best image resolution for different groups of screen sizes it would be VERY helpful!
Thanks!
You could always check the window size, either height or width, whatever floats your boat, and add something to the image filenames to load high res images, like having img4.jpg as a normal image and img4_big.jpg as a high res image etc.
Would look something like this :
$(window).load(function() {
var randomImages = ['img1', 'img2', 'img3', 'img4', 'img5'];
var rndNum = Math.floor(Math.random() * randomImages.length);
var $win = $(this);
//add _big to image filename if window width is over 1920px,
//like so : img4_big.jpg etc.
var isBig = $(window).width() > 1920 ? '_big' : '';
//add the string to the image filename
var $img = $('#background')
.attr('src', '_img/bg/index_rnd/' + randomImages[rndNum] + isBig + '.jpg')
.css({
'position': 'fixed',
'top': 0,
'left': 0
});
function resize() {
if (($win.width() / $win.height()) < ($img.width() / $img.height())) {
$img.css({
'height': '100%',
'width': 'auto'
});
} else {
$img.css({
'width': '100%',
'height': 'auto'
});
}
}
$win.resize(function() {
resize();
}).trigger('resize');
});​

Categories

Resources