I need a photography gallery to display in 3 rows, each row showing different number of images. Not all images have the same width. When the screen resizes I want more images to show, but in the same ratio (grow to 3/5/4, 4/6/5, etc...). The ratio should be like this (brackets represent an image):
[][]
[][][][]
[][][]
Visual example here.
It was partly working except for the offset. I tried to write an offset loop, and now it's not working at all. Here is the code:
<script>
jQuery(document).ready(function() {
jQuery('.gallery').wrap('<div class="gal-wrapper" />');
resizeGallery("#gallery-1",2);
resizeGallery("#gallery-2",4);
resizeGallery("#gallery-3",3);
});
jQuery(window).resize(function() {
resizeGallery("#gallery-1",2);
resizeGallery("#gallery-2",4);
resizeGallery("#gallery-3",3);
});
function resizeGallery(gall, initpos){
var x = 0;
var y = 0;
var accum_width = 0;
var final_width = accum_width;
var offset = initpos;
var wW = jQuery(window).width()-jQuery("#nav").width();
while(accum_width < wW){
var new_width = jQuery(gall).find("img.attachment-medium:eq("+x+")").width();
if((accum_width + new_width) > wW){
break;
}else{
accum_width += new_width+4;
}
x++;
}
/* worked partly to this point... onto the offset! */
while(y < offset){
var subtract_width = jQuery(gall).find("img.attachment-medium:eq("+x+")").width();
final_width -= subtract_width+4;
y++;
x--;
}
jQuery(gall).parent().width(final_width);
}
</script>
Here is a jsfiddle example.
Your working JS fiddle
In case That fiddle link doesn't work...
jQuery(document).ready(function() {
jQuery('.gallery').wrap('<div class="gal-wrapper" />');
var picCount = resizeGallery("#gallery-2", Number.POSITIVE_INFINITY);
resizeGallery("#gallery-3", picCount-1);
resizeGallery("#gallery-1", picCount-2);
});
jQuery(window).resize(function() {
var picCount = resizeGallery("#gallery-2", Number.POSITIVE_INFINITY);
resizeGallery("#gallery-3", picCount-1);
resizeGallery("#gallery-1", picCount-2);
});
function resizeGallery(gall, picCount) {
var x = 0;
var y = 0;
var accum_width = 0;
var wW = jQuery(window).width() - jQuery("#nav").width();
while (accum_width < wW && x < picCount) {
var new_width = jQuery(gall).find("img.attachment-medium:eq(" + x + ")").width();
if ((accum_width + new_width) > wW) {
break;
} else {
accum_width += new_width + 4;
}
x++;
}
jQuery(gall).parent().width(accum_width);
return x;
}
Related
I have a paragraph tag in my html id is move, I am trying to move the p tag to slowing fall down while on page load. but my code is not working.......
var speed = 12;
var direction = 1;
var getParagraph = document.getElementById("move");
getParagraph.onmouseover = moving;
function moving() {
var bo = getParagraph.offsetHeight;
var boTop = getParagraph.offsetTop;
var boBottom = boTop + bo;
// When right side of the box goes too far - change direction:
if (boBottom > document.body.offsetHeight) {
direction = -1;
}
// When left side of the box goes too far - change direction:
if (boTop < 0) {
direction = 1;
}
// Recalculate position:
getParagraph.style.Top = (boTop + speed * direction)
}
This is your code with minor changes, and it "works":
JS:
var speed = 12;
var direction = 1;
var getParagraph = document.getElementById("move");
document.getElementById("move").addEventListener("mouseover", moving);
//getParagraph.onmouseover = moving;
function moving() {
console.log("Moving??");
var bo = document.getElementById("move").offsetHeight;
var boTop = document.getElementById("move").offsetTop;
var boBottom = boTop + bo;
// When right side of the box goes too far - change direction:
if (boBottom > document.body.offsetHeight) {
direction = -1;
}
// When left side of the box goes too far - change direction:
if (boTop < 0) {
direction = 1;
}
// Recalculate position:
document.getElementById("move").style.marginTop = (boTop + speed * direction) + "px";
speed++;
}
CSS:
#move {
display : block ;
position : absolute ;
}
Hope it helps.
I'm trying to spawn randomly generated targets on the screen using a function to copy an invisible image of the target to be spawned at a random place within the screen using window object properties.
For this to happen I think the image have to have position set to absolute, but then several images may be spawned in a way that they will overlap, how can I prevent this from happening?
The div element where I copy my first image and also store the other copies.
<div id="targetsDiv">
<img src="target2.png" alt="target_shot" class="target" />
</div>
Inside the script:
var x_pixels = window.innerWidth - 180;
var y_pixels = window.innerHeight - 180;
var x_midScreen = window.innerWidth / 2;
var y_midScreen = window.innerHeight / 2;
var xRandom = Math.floor(Math.random()*x_pixels) +1;
var yRandom = Math.floor(Math.random()*y_pixels) +1;
var targetCollection = document.getElementById("targetsDiv");
var targetCopy = targetCollection.innerHTML
var targetList = document.getElementsByClassName("target");
targetList[0].style.display = "none";
var targetNr = 1;
var numberOfSpawns = 3;
function spawnTargets () {
while (targetNr <= numberOfSpawns) {
if ((xRandom < x_midScreen - 126 || xRandom > x_midScreen + 26) || (yRandom < y_midScreen - 126 || yRandom > y_midScreen + 26)) {
targetCollection.innerHTML += targetCopy;
targetList[targetNr].style.left = xRandom + "px";
targetList[targetNr].style.top = yRandom + "px";
targetNr++;
}
xRandom = Math.floor(Math.random()*x_pixels) +1;
yRandom = Math.floor(Math.random()*y_pixels) +1;
}
}
PS: I appreciate all help, tips and tweaks that you guys provide:) Thanks for helping
The area you want to exclude in the centre of the screen is rather large, and on my little laptop, there isn't even any room to still show the random positioned images.
But anyway, this piece of code should do the job -- I added some infinite loop protection which on my PC was a life-saver:
HTML (added style attribute)
<div id="targetsDiv">
<img src="target2.png" alt="target_shot" class="target"
style="visibility:hidden"/>
</div>
JavaScript:
window.addEventListener('load', function () {
var targetCollection = document.getElementById("targetsDiv");
var template = document.getElementsByClassName("target")[0];
var targetWidth = template.offsetWidth;
var targetHeight = template.offsetHeight;
var x_pixels = window.innerWidth - targetWidth;
var y_pixels = window.innerHeight - targetHeight;
var x_midScreen = window.innerWidth / 2;
var y_midScreen = window.innerHeight / 2;
function spawnTargets (numberOfSpawns) {
var targets = [];
var count = 0; // infinite recursion protection
for (var i = 0; i < numberOfSpawns; i++) {
do {
do {
var x = Math.floor(Math.random()*x_pixels);
var y = Math.floor(Math.random()*y_pixels);
if (count++ > 200) {
console.log('give up');
return;
}
} while ((x >= x_midScreen-450 && x <= x_midScreen+300) && (y >= y_midScreen-350 || y <= y_midScreen+200));
for (var j = 0; j < i; j++) {
if (x >= targets[j].x - targetWidth && x <= targets[j].x + targetWidth &&
y >= targets[j].y - targetHeight && y <= targets[j].y + targetHeight) break; // not ok!
}
} while (j < i);
targets.push({x, y});
img = document.createElement('img');
img.src = template.src;
img.setAttribute('width', targetWidth + 'px');
img.setAttribute('height', targetHeight + 'px');
img.className = template.className;
targetCollection.appendChild(img);
img.style.left = x + "px";
img.style.top = y + "px";
}
}
spawnTargets(3);
});
Hello I am having errors with my code:
https://jsfiddle.net/wzhm2whj/
<script>
//Initial Global variables
var mainloop_frame_time = 34;
var top = 0;
var rootMenu = document.getElementById('menu');
var rootMenuDivs = rootMenu.getElementsByTagName('div')[0];
var rootListDivs = rootMenuDivs.getElementsByTagName('ul')[0];
var childDivs = rootListDivs.getElementsByTagName('div');
var childDiv = childDivs[0];
var childDiv_counter = 0;
var child_change_flag = true;
var child_index_increment = 0;
var child_index_amount = childDivs.length;
//var child_animation_keyframe = 0;
var frame = 0;
var childDiv_tmp1_position = 0;
//finding the web browsers viewport size.
var elem = (document.compatMode === "CSS1Compat") ? document.documentElement : document.body;
var client_height = elem.clientHeight;
var process_array = new Array();
//Initial styling
for (var i = 0; i < childDivs.length; i++) {
var childDiv = childDivs[0];
childDiv.style.backgroundColor = "antiquewhite";
}
var childDiv = childDivs[0];
//rotate function variables
var rotate_div;
var rotate_passed_deg;
var rotate_deg_stop;
var rotate_results;
var rotate_current_deg = 0;
var speed_modifier = 1;
var tmp1_speed = 0;
//case flags
case2_flag = -1;
case3_flag = -1;
//This may not be needed >>> If not, put all code in mainloop.
var processes_logic = function() {
switch (frame) {
case 0:
process_array.push(menu_child0);
break;
//this case is when the previous case is 80% done
case 28:
rootMenu.style.transformOrigin = "top left";
process_array.push(menu_slant);
break;
case 35:
//Added the ability for paramaters, all push paramaters here are: function, menu_index, position, speed, tmp as flag for switching to next menu,
//process_index used to give the process index as refrence to delete..
window.alert(process_array.length);
process_array.push(new Array(menu_div_slide_out, child_index_amount - 1, 0, 0, 0, process_array.length-1));
break;
}
}
var initiate_all_processes = function() {
for (var i = 0; i < process_array.length; i++) {
//Added the ability for paramaters, considerer removing as its not used atm, or revising.
if (process_array[i] != undefined && process_array[i] != null && process_array[i] != "") {
if (process_array[i].length < 6) {
process_array[i]();
} else {
process_array[i][0](process_array[i][5]);
}
}
}
}
function menu_div_slide_out(process_index) {
/*process_array[process_index][
0 = function,
1 = current menu item (index length working backwards)
2 = position,
3 = speed,
4 = tmp,
5 = refrence to this process in array] */
//for debuging purposes to see if a ChildDiv is not devined, what process index is being pointed to.
//window.alert('Process index ' + process_index);
//!!!!!!!! You are probably mixing up how you are setting process index! try +1
process_array[process_index][2] += 3.5 + (process_array[process_index][3] * 1.7);
process_array[process_index][3] += (speed_modifier * .3);
childDivs[process_array[process_index][1]].style.left = process_array[process_index][2] + 'px';
if (process_array[process_index][2] > 100 && process_array[process_index][4] && process_array[process_index][1] > 0) {
// window.alert('CCC');
process_array[process_index][4] = true;
//Add another process at ever 100pxs
process_array.push(new Array(menu_div_slide_out, process_array[process_index][1] - 1, 0, 0, false, process_array.length-1));
//debugger;
} else
if (process_array[process_index][2] >= (900 - (process_array[process_index][2] / 20))) {
childDivs[process_array[process_index][1]].remove();
//process_array.splice(process_array[process_index][5], 1);
}
}
function menu_slant() {
rotate_return = rotate(rootMenu, .1 + (tmp1_speed), 27);
tmp1_speed += (speed_modifier * .5);
if (rotate_return === true) {
/////////////This can be unremoved because there is more animation, perhaps. or can be done in another key frame.
tmp1_speed = 0;
rotate_current_deg = 0;
remove_process(menu_slant);
} else {
if (rotate_return / 27 * 100 >= 60 && case3_flag < 0) {
case2_flag = frame;
}
}
}
var menu_child0 = function() {
childDiv_tmp1_position += 3 + (tmp1_speed * 1.7);
childDiv.style.top = childDiv_tmp1_position + 'px';
rotate(childDiv, .2 + (tmp1_speed), 170);
tmp1_speed += (speed_modifier * .7);
if (childDiv_tmp1_position / client_height * 100 >= 80 && case2_flag < 0) {
case2_flag = frame;
}
if (childDiv_tmp1_position >= client_height) {
childDiv.style.visibility = 'hidden';
tmp1_speed = 0;
childDiv_tmp1_position = 0;
rotate_current_deg = 0;
//may be bloated >>
remove_process(menu_child0);
}
}
function remove_process(index) {
var index_tmp = process_array.indexOf(index);
if (index_tmp >= 0) {
process_array.splice(index_tmp, 1);
}
}
function rotate(rotate_div, rotate_passed_deg, rotate_passed_deg_stop) {
rotate_current_deg += rotate_passed_deg;
rotate_deg = rotate_current_deg < rotate_passed_deg_stop ? rotate_current_deg : rotate_passed_deg_stop;
rotate_div.style.webkitTransform = 'rotate(' + rotate_deg + 'deg)';
rotate_div.style.mozTransform = 'rotate(' + rotate_deg + 'deg)';
rotate_div.style.msTransform = 'rotate(' + rotate_deg + 'deg)';
rotate_div.style.oTransform = 'rotate(' + rotate_deg + 'deg)';
rotate_div.style.transform = 'rotate(' + rotate_deg + 'deg)';
if (rotate_current_deg >= rotate_passed_deg_stop) {
return true;
} else {
return rotate_current_deg;
}
}
//main loop for the animation
var mainloop = function() {
processes_logic();
initiate_all_processes();
frame++;
}
var loop_interval = setInterval(mainloop, mainloop_frame_time);
</script>
I am trying to animate my website falling apart but I am having a hard time articulation this into code. I thought of running the animation in a loop, creating events at specific frames and reusing some codes as functions. I have a rotate function which works to rotate several things.
THE PROBLEM:
The problem I am having is sliding my menu items one at a time to the right. I want one to slide a bit and the next to start sliding after. I wrote a function to slide an item and then in that function it adds another process to an array for the next menu item to be called and run the same function (with passed interval of who is calling). I do not know how many menu items there will be, thats why I am trying to make it dynamic.
I can get it so that the first mwnu item falls, the menu falls by rotating it (some times if there is an error in the code then it wont rotate, but when there are no errors it works better).
The issue is sliding each menu item.
my website is here: http://clearlove.ca/89-404-error
Can any one help me with why this isnt working, and if there is a better way to do what I am trying to do?
I'm developing a site and I don't know how to create a javascript animation that looks like this:
I have a div that have some text on it, and when the user moves his mouse over this text, I want each character to move independently of each other, in order to maintain a certain distance from it (the mouse). Also, I want this animation to have rotation, but it isn't that important now. Here's an image explanation:
Here's what I did so far:
HTML:
<div class="div1">Hello World</div>
Javascript:
var chars = $(".div1").html().split('');
$(".div1").empty();
for(var i = 0; i < chars.length; i++){
$(".div1").append("<span class='letter'>"+chars[i]+"</span>");
}
JSFiddle
Can someone help me to achieve this effect? I don't know how to proceed and there's no site or answer that helped me. You can use jQuery or pure JavaScript but, please, keep it simple! Thank you.
Oh here we go, I've found a solution for this.
What I did was using a different class name for each character (.letter + character number) and then created a way of moving the characters depending on the mouse position and distance compared to each character, so, for example, when the distance between the mouse and a character is less than X, and the mouse Y is less than the character Y, then the character will go down.
Thanks to adeneo and Derek
Here's the relevant code:
JavaScript:
var chars = $(".div1").html().split('');
$(".div1").empty();
for (var i = 0; i < chars.length; i++) {
$(".div1").append("<span class='letter" + i + "'>" + chars[i] + "</span>");
$(".letter" + i).css({
"position":"relative",
});
$(".letter" + i).css({
"transition": "0.5s"
});
}
$(document).on("mousemove", function (e) {
for (var i = 0; i < chars.length; i++) {
var x = e.pageX,
y = e.pageY;
var distx = x - $(".letter" + i).offset().left + ($(".letter" + i).width() / 2);
var disty = y - $(".letter" + i).offset().top;
if (Math.abs(distx) < 24 && Math.abs(disty) < 24) {
if (distx > 6 || distx < -6) {
if (x < $(".letter" + i).offset().left) {
$(".letter" + i).css({
"left": + (24 / Math.abs(distx) * Math.abs(distx)),
"position": "relative"
});
} else {
$(".letter" + i).css({
"left": - (24 / Math.abs(distx) * Math.abs(distx)),
"position": "relative"
});
}
}
if (disty > 12 || disty < -12) {
if (y < $(".letter" + i).offset().top + 6) {
$(".letter" + i).css({
"top": + (24 / Math.abs(disty) * Math.abs(disty)),
"position": "relative"
});
} else {
$(".letter" + i).css({
"top": - (24 / Math.abs(disty) * Math.abs(disty)),
"position": "relative"
});
}
}
}
distx = 0;
disty = 0;
}
});
HTML:
<div class="div1">Hello World</div>
Updated JSFiddle with CSS Transitions to improve smoothness
Well since you say yo want to learn, i'll give a code to help you out, but you have to work your way through, i haven't test it, i just wrote it blindly so it propably won't work but might give you a good idea of what must be done.
Html:
<div class="container">
<div id="coolDiv" class="scatterContainer">Hello World</div>
</div>
Css:
*{margin:0;}
span:hover{
color:#0CF;
}
.scatterContainer{
display: inline;
}
.container {
margin: 30px auto;
}
Javascript
LetterScatterer = (function() {
function LetterScatterer(id) {
this.id = id
this.$el = $('#' + this.id);
this.rangeOfaction = 3; // Number of characters to affect
this.maxVerticalMovement = 10; // Value in px
this.minVerticalMovement = 2
this.duration = 100; // In miliseconds
// Event Listeners
this.$el.on(mousemove((function(_this){
return function(e){
var x = e.pageX;
var y = e.pageY;
return _this.scatter(x, y);
}
})(this));
}
LetterScatterer.prototype.splitCharacters = function() {
var nodes = [];
var nodesQ = 0;
var _this = this;
this.chars = $el.text().split('');
$el.empty();
for(var i = 0; i < chars.length; i++){
var markup = "<span class='letter'>"+chars[i]+"</span>";
nodes.push(markup);
}
this.$nodes = $(nodes);
this.nodesWidth = [];
this.$nodes.each(function(){
var width = $(this).outerWidth();
_this.nodesWidth.push(width);
});
$el.append(this.$nodes);
}
LetterScatterer.prototype.scatter = function(x, y) {
var epicenter;
var offset = 0;
var midPoint, farestLeft;
for(var i = 0, len = this.nodesWidth.length; i < len; i++){
offset += this.nodesWidth[i];
if(x <= offset){
epicenter = i;
break;
}
}
leftRange = (this.rangeOfaction - 1) / 2; // We remove one, this is our epicenter, then we get left and right halves
farestLeft = epicenter - leftRange;
for(var i = farestLeft; i < this.rangeOfaction; i++){
this.animateY($node[i]);
}
}
LetterScatterer.prototype.animateY = function(node, verticalDisplacement) {
var $node = $(node);
$node.animate({margin-top: verticalDisplacement + 'px'}, this.duration);
}
return LetterScatterer;
})();
letterScatterer = new LetterScatterer('coolDiv');
What you see in the code is a classlike function, first you pass it the id of the element containing the text that will be scattered. There are some config varaibles, range of action is lets say, if you mouse over one character, how many characters to the left and to the right (also including the current hovered element) should be animated, the max and min verticalMovement, determines how much should move the one that is hovered (max) and those further apart will use min, those in between should interpolate, but i didn't code that far.
We then got a mousemove listener, that calls the method scatter, this method finds which items is currently hovered by adding up each character widht, but now i think about it, it should be easier to just add a listener to the span, and get the current index of that element with the jQuery method index(), then based on that index you animate that one and those in the range. You must create the code that calculates the rotation, and x movement if you want to, but i think i gave you a lot to start, it took me a while to code it, so i hope it helps and this answer satisfies your question. :)
I have an element with animated top margin. I need to detect if it isn't too close from the border, and if it is, scroll parent div to lower position, to prevent animated element from hiding. Here is an example:
http://jsfiddle.net/zYYBR/5/
This green box shouldn't be below the red line after clicking the "down" button.
Do you mean this?
var new_margin;
var step = 75;
var limit = $("#max")[0].offsetTop;
$('#down').click(function() {
var goStep = step;
var elHeight = $("#animated")[0].offsetTop + $("#animated")[0].offsetHeight;
if((elHeight + step) > limit)
{
goStep = limit - elHeight;
}
new_margin = goStep + parseInt($('#animated').css('margin-top'));
$("#animated").animate({marginTop: new_margin}, 1000);
});
http://jsfiddle.net/zYYBR/8/
EDIT: Or maybe something like that (of course you can improve the calculation, because currently it's very buggy with scroll):
var new_margin;
var step = 75;
$('#down').click(function () {
scroll(1000);
});
var scrollTimer = null;
$("#container").bind("scroll", function () {
clearTimeout(scrollTimer);
scrollTimer = setTimeout(function () { scroll(1); }, 10);
});
function scroll(speed) {
var scrollStep, animationStep = step;
var currentBoxBottom = $("#animated")[0].offsetTop + $("#animated")[0].offsetHeight;
var nextCurrentBoxBottom = currentBoxBottom + step;
var limit = $("#max")[0].offsetTop + $("#container")[0].scrollTop;
if (nextCurrentBoxBottom > limit) {
if (limit >= $("#container")[0].scrollTop) {
scrollStep = $("#container")[0].scrollTop + nextCurrentBoxBottom - limit;
}
else {
scrollStep = $("#container")[0].scrollTop - nextCurrentBoxBottom - limit;
animationStep = nextCurrentBoxBottom - limit;
}
$("#container")[0].scrollTop = scrollStep;
}
new_margin = animationStep + parseInt($('#animated').css('margin-top'));
$("#animated").animate({ marginTop: new_margin }, speed);
}
http://jsfiddle.net/zYYBR/13/
Do you mean something like this?
I have the same visual result as Alex Dn did, but I added a little extra direction to what I think you're talking about. If it's what you're looking for I'll make updates:
var new_margin;
var step = 75;
var limit = $("#max")[0].offsetTop;
$('#down2').click(function() {
var anim = $("#animated");
var hrOff = $("#max").offset();
var thOff = anim.offset();
new_margin = Math.min(hrOff.top - thOff.top - anim.height(), 75);
console.log(new_margin, hrOff.top, thOff.top);
var st = 0;
if (new_margin < 75) {
st = 75 - new_margin;
//have container scroll by this much?
}
anim.animate({
marginTop: "+=" + new_margin
}, 1000);
});
http://jsfiddle.net/zYYBR/10/