Change position of last image - javascript

The code:
function showLetter() {
setInterval(function() {
var letter = imgsArray[random()];
var top = random();
var left = random();
$("div").append("<img src='imgs/" + letter + ".png'>");
$("div").last().css({"position": "absolute", "top": top + "px", "left": left + "px"});
}, 1000);
}
In each position of the array imgsArray, I have the name of an image.
What I want to do:
Add an image every 1000 ms, giving it a random position on the screen. (If it's possible to prevent overlapping, that'd be great, but I think that has already been answered).
What it does:
Every 1000 ms, it adds a new image of a letter, and gives the same properties to all images so they all end up horizontally aligned :)
I really don't understand why this is happening. With $("div").last().css(), am I not choosing the last image added to the div and changing only its properties?
Thanks in advance.

$("div").last() gives you the last item in the `$("div") jquery object. There are no images in that jQuery object.
Perhaps what you want is:
$("div img").last()
But, that is quite inefficient. If you just want to operate on the newly created image object, then you can just operate on it directly:
function showLetter() {
setInterval(function() {
var letter = imgsArray[random()];
var top = random();
var left = random();
var img = $("<img src='imgs/" + letter + ".png'>");
img.css({"position": "absolute", "top": top + "px", "left": left + "px"});
$("div").append(img);
}, 1000);
}

You might want to consider something like this:
var div = $('<div/>').css({position:'absolute'....}).appendTo('body');
var img = $('<img/>', {src:'imgs/' + letter + '.png'}).appendTo(div);
This will add new <div> containing an image to <body>.

Related

JavaScript move character. Change image on clicking right arrow

Hi currently I'm making some RPG game. I want to move my character with arrows. Which is working right now. But I want to change image when I clicking let's say the right arrow. Right now when I click right arrow with this code:
function rightArrowPressed() {
var element = document.getElementById("image1").src = "/img/run_1.png";
element = document.getElementById("image1");
element.style.left = parseInt(element.style.left) + 5 + 'px';
}
The image change's to run_1.png ant it stays like that. Than just the image slides in one pose. How to change the image again when I click right arrow ?
HTML
<img id="image1" src="{{Auth::user()->char_image}}" style="position:absolute;left:0; top:0;height: 45px; image-rendering: -webkit-optimize-contrast;">
You can use a counter variable:
var counter = 0;
function rightArrowPressed() {
counter = (counter === 4) ? 1 : counter+1;
var image = "/img/run_"+counter+".png";
var element = document.getElementById("image1");
element.src = image;
var left = parseInt(element.style.left)+5;
element.style.left = left + "px";
}
And this would make it so that every time you right click, a different image is used.
You can use an arry imeges sources to make a scene
function rightArrowPressed() {
var slides=['/img/run_1.png','/img/run_2.png','/img/run_1.png'];
slides.forEach(slide => {
setTimeout(function(){
var element = document.getElementById("image1").src = slide;
element = document.getElementById("image1");
element.style.left = parseInt(element.style.left) + 5 + 'px';
}, 500);//add a time in screen
});
}

How to check bottom of child div touching parent bottom

i'm trying to change position of a child element(with varying height based on text) using range input,i would like to stop applying top position once the child div touches the bottom of the parent having fixed height.
$('#change_position').on('input', function () {
var val = +$(this).val(),
ScrSize = parseInt($('.screen').css('height')),
Stop = $('.screentip').offset().top,
h = parseInt($('.screentip').css('height')),
tofsset = Stop - h;
if (tofsset < ScrSize) {
$('.screentip').css('top', val + "%");
}
});
The height you are expecting jQuery to return is actually a string with the ending "px". You can use the function .height(). This will return you the height of the element as integer. I have tried a slightly modiefied version of your code:
$('#input').on('input', function () {
var val = parseInt($(this).val()),
ScrSize = parseInt($('#container').height()),
TxtSize = parseInt($("#text").height()),
Stop = ScrSize - TxtSize,
valInPixel = ScrSize * val / 100;
if (valInPixel < Stop) {
$('#text').css('top', val + "%");
}
else
{
$("#text").css("top", Stop + "px");
}
});
The else part will position your element to the bottom, if the number exceeds the frame. You may also have to be aware of padding and margin. This could also lead to mispositioning.
Hope this helps.

Opening Div at a specific position

I need to open a div at a specific location on the page. When I focus on a textbox the div should be opened(made visible). I am able to do this part. The problem is it opens right underneath the textbox and when there is no scroll on the page, it creates one. I need help in showing the div above the textbox when there is more space on upper half of the page then the lower half of the page. Here is the JSFiddle I have created and if someone can edit it, it would be of too much help to me.
And this is how I am opening the div:
function openDIV(activatorCtl) {
var leftpos = 0;
var toppos = 0;
var sScrollTop = getScrollTop;
var aTag = activatorCtl;
do {
aTag = aTag.offsetParent;
sScrollTop = (aTag.scrollTop > sScrollTop) ? aTag.scrollTop : sScrollTop;
leftpos += aTag.offsetLeft;
toppos += aTag.offsetTop;
} while (aTag.tagName != 'BODY');
document.getElementById("divDetails").style.left = leftpos + "px";
document.getElementById("divDetails").style.top = toppos + 20 + "px";
document.getElementById("divDetails").style.zIndex = "999";
document.getElementById("divDetails").style.visibility = "visible";
}
You mean like this?
https://jsfiddle.net/36vdoaqo/3/
I added an if for when the toppos is bigger than 250 (your divs height)
if(toppos <= 250)
Another tip:
You use this 4 times in a row:
document.getElementById("divDetails")
save this element in an variable to get shorter statements like:
var detailsDiv = document.getElementById("divDetails");
detailsDiv.style.left = leftpos + "px";
detailsDiv.style.zIndex = "999";
EDIT: i did not save the jsfiddle properly.

Javascript-moving image

How is it posible move an image from one position to other with fadeout?
I hav such functions
for hiding:
function SetOpacity(object,opacityPct)
{
// IE.
object.style.filter = 'alpha(opacity=' + opacityPct + ')';
// Old mozilla and firefox
object.style.MozOpacity = opacityPct/100;
// Everything else.
object.style.opacity = opacityPct/100;
}
function ChangeOpacity(id,msDuration,msStart,fromO,toO)
{
var element=document.getElementById(id);
var opacity = element.style.opacity * 100;
var msNow = (new Date()).getTime();
opacity = fromO + (toO - fromO) * (msNow - msStart) / msDuration;
if (opacity<0)
SetOpacity(element,0)
else if (opacity>100)
SetOpacity(element,100)
else
{
SetOpacity(element,opacity);
element.timer = window.setTimeout("ChangeOpacity('" + id + "'," + msDuration + "," + msStart + "," + fromO + "," + toO + ")",1);
}
}
function FadeOut(id)
{
var element=document.getElementById(id);
if (element.timer) window.clearTimeout(element.timer);
var startMS = (new Date()).getTime();
element.timer = window.setTimeout("ChangeOpacity('" + id + "',500," + startMS + ",100,0)",1);
}
for get current position or next position (by id of image and id of div)
function findPos(e){
var obj = document.getElementById(e);
var posX = obj.offsetLeft;var posY = obj.offsetTop;
while(obj.offsetParent){
posX=posX+obj.offsetParent.offsetLeft;
posY=posY+obj.offsetParent.offsetTop;
if(obj==document.getElementsByTagName('body')[0]){break}
else{obj=obj.offsetParent;}
}
alert(posX+'-'+posY);
}
the first position is position of image, and next - is position of div
The easiest approach with minimal code will be to use jQuery and use the animate function mate.
Ex:
$(".block").animate({"left": "+=50px"}, "slow");
You can use multiple parameters in the brackets like background-color, opacity, etc as you wish to dynamically change the values.
A link for your reference is located at: http://api.jquery.com/animate/
Most javascript animations rely on timer to create the effect of fluid motion. To slide an image across the page, you would set an interval that changed the css position to the right 1px every 5 milliseconds or something of the like. Javascript animation tutorial.
However, animation is most easily accomplished with a library like jquery or many others.

replacing images inplace

I have a array of static images that I am using for an animation.
I have one frame image that I want to update the image of and I have seen a lot of tutorials on animating images with javascript just simply update the source of an image.
frame.src = animation[2].src; etc
When I look at the resource tracking in chrome, it doesnt look like they are getting cached even thought the web browser does download the image more than once but not once for each time it is displayed, so there is still some browser caching going on.
What is the best way to replace the frame image object with another image?
Well, you can either position all images absolute and give them a z-index, then use jQuery/JS to shuffle their z-indexes, bringing a new one to the top in a cross fader style,
or you can take all the id's and fadeone in slightly faster than the last one fades out.
Like so:
function fader(func) {
var currID = $('#mainimg ul').data('currLI');
var currLiStr = '#mainimg ul li#' + currID;
img = $(currLiStr).find('img').attr('src');
nextID = (currID == 'six') ? 'one' : $(currLiStr).next().attr('id');
nextLiStr = $('#mainimg ul li#' + nextID);
$(currLiStr).fadeOut(3000);
$(nextLiStr).fadeIn(2000).find('div.inner').delay(3000).fadeIn('slow').delay(6000).fadeOut('slow');
$('#mainimg ul').data('currLI',nextID);
}
Note 'six' is the id of the last li, reseting it back to one, but if you do $('#mainimg ul li:last').attr('id'); and $('#mainimg ul li:first').attr('id') to get the last and first id's, you can allow it to cope with any amount of images (obviously this is with li's given id's one, two and so on, but if you are finding out the last and first id you could use any structure.
Or you can set a ul width a width of all the li's multiplied, and give the li's the width of the images, and set overflow to hidden, then use JS to pull the li's left by the width of 1 li on each iteration in a slider like I have done here: http://www.reclaimedfloorboards.com/
There are loads of options
I ended up using jquery's replaceWith command and gave all the frames a class "frame" that i could select with $('.frame') which happened to only select visible frames.
<script type="text/javascript">
var animation = [];
var firstFrame = 1;
var lastFrame = 96;
var animationFrames = 16;
var loadedImageCount = 0;
$(function() {
$("button, input:submit",'#forecastForm').button();
$("#progressbar").progressbar({
value: 0
});
$('#id_Species').attr('onChange', 'loadAnimation($(\'#id_Species\').val(),$(\'#id_Layer\').val(),$(\'#id_StartTime\').val(),$(\'#id_EndTime\').val())' )
$('#id_Layer').attr('onChange', 'loadAnimation($(\'#id_Species\').val(),$(\'#id_Layer\').val(),$(\'#id_StartTime\').val(),$(\'#id_EndTime\').val())' )
$('#id_StartTime').attr('onChange', 'loadAnimation($(\'#id_Species\').val(),$(\'#id_Layer\').val(),$(\'#id_StartTime\').val(),$(\'#id_EndTime\').val())' )
$('#id_EndTime').attr('onChange', 'loadAnimation($(\'#id_Species\').val(),$(\'#id_Layer\').val(),$(\'#id_StartTime\').val(),$(\'#id_EndTime\').val())' )
});
if (document.images) { // Preloaded images
loadAnimation('Dry_GEM',1,1,96);
}
function rotate(animation, frame)
{
if (frame >= animation.length)
frame = 0;
$('.frame').replaceWith(animation[frame]);
window.setTimeout('rotate(animation,'+eval(frame+1)+')',150);
}
function loadAnimation(species, layer, startTime, endTime)
{
layer = Number(layer);
startTime = Number(startTime);
endTime = Number(endTime);
if (startTime > endTime)
{
swap = startTime;
startTime = endTime;
endTime = swap;
delete swap;
}
for (i=0;i<animation.length;i++)
delete animation[i];
delete animation;
animation = []
$('#progressbar').progressbar({value: 0});
loadedImgCount = 0;
animationFrames = endTime - startTime + 1;
for(i=0;i < animationFrames;i++)
{
animation[i] = new Image();
animation[i].height = 585;
animation[i].width = 780;
$(animation[i]).attr('class','frame');
animation[i].onload = function()
{
loadedImgCount += 1;
$('#progressbar').progressbar({value: eval(loadedImgCount / animationFrames * 100)});
};
animation[i].src = 'http://[[url]]/hemi_2d/' + species + '_' + layer + '_' + eval(i+startTime) + '.png';
}
}
</script>
The easiest way to do it is create a separate hidden image for each frame. Something like this:
var nextImage = (function(){
var imagePaths='basn0g01.png,basn0g02.png,basn0g04.png,basn0g08.png'.split(','),
imageHolder=document.getElementById('custom-header'),
i=imagePaths.length, imageIndex=i-1, img;
for (;i--;) {
img=document.createElement('img');
img.src='http://www.schaik.com/pngsuite/' + imagePaths[i];
if (i) img.style.display='none';
imageHolder.appendChild(img);
}
return function(){
imageHolder.childNodes[imageIndex].style.display='none';
if (++imageIndex >= imageHolder.childNodes.length) imageIndex=0;
imageHolder.childNodes[imageIndex].style.display='inline-block';
}
}());
Try this example on this page; paste it in the console and then call nextImage() a few times. Watch the top of the page.
edit
If you already have all the images in your HTML document, you can skip most of the above and just do something like this:
var nextImage = (function(){
var imageHolder=document.getElementById('custom-header'),
images=imageHolder.getElementsByTagName('img'),
i=images.length, imageIndex=0, img;
for (;i--;) if (i) images[0].style.display='none';
return function(){
imageHolder.childNodes[imageIndex].style.display='none';
if (++imageIndex >= imageHolder.childNodes.length) imageIndex=0;
imageHolder.childNodes[imageIndex].style.display='inline-block';
}
}());

Categories

Resources