I want to randomly place an image in boundaries of parent div - javascript

I have some code that shows one or two random images form a list and places it in a random position in a div. Sometimes the images appear outside the div. How can I contain the images to only show in boundaries of parent div?
Current code :
$('.draggable').each(function(i, el) {
var tLeft = Math.floor(Math.random() * 99) + 1 + '%',
tTop = Math.floor(Math.random() * 99) + 1 + '%';
$(el).css({
'left': tLeft,
'top': tTop
});
});
.draggable {
position: absolute;
}
.top-images {
position: relative;
width: 700px;
height: 80vh;
margin: 0 auto;
}
.top-images img {
width: 300px;
height: auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="top-images">
<img class="draggable" src="http://serwer1858479.home.pl/autoinstalator/wordpress/wp-content/themes/cincio/img/main/main_page(9).jpg">
<img class="draggable" src="http://serwer1858479.home.pl/autoinstalator/wordpress/wp-content/themes/cincio/img/main/main_page(3).jpg">
</div>

in js get the width and height of each image...
get the width and height of parent..
place the image randomly between 0,0 to (parent_width-img_width+1),(parent_height-img_height+1)
Note:new to js so the exact code might differ slightly but the general cocept is accurate
replace this in the math function
var tLeft = Math.floor(Math.random() * ($(el).parent().width()-$(el).clientwidth+1)) + 'px',
tTop = Math.floor(Math.random() * ($(el).parent().height()-$(el).clientheight+1)) + 'px';
if the size is auto it might mess up the values
Edit 1: errors in the code

Since 300px (width of images) is 43% of 700 (width of the div that images appear in)
you need to limit tleft to 57 (100-43). But tTop is a bit different since you used pixels for it. Try this :
var maxTop = $('.top-images').first().height() - $(this).height(),
tLeft = Math.floor(Math.random() * 57) + 1 + '%',
tTop = Math.floor(Math.random() * maxTop) + 'px';

Related

Scaling elements based on another element

I have elements positioned on top of am img in the following way:
<div style={{ display: "inline-block", position: "relative" }} >
<img />
<div style={{ position: "absolute", left: 0, right: 0, top: 0, bottom: 0, width: "100%", height: "100%" }} >
<child elements I'm trying to position />
</div>
</div>
The child elements use the top, left, width, height properties to position themselves on top of the image.
I'm trying to make them scale with the image (- when the image's width and height changes I want them to stay in the same place and scale to the image):
width: Math.round(((box.x2 - box.x1) / imgWidth) * 100) + "%",
height: Math.round(((box.y2 - box.y1) / imgHeight) * 100) + "%",
left: Math.round((box.x1 / imgWidth) * 100) + "%",
top: Math.round((box.y1 / imgHeight) * 100) + "%"
But the results when using percentage are a little off than just using the coordinates.
Is there a better way to position the elements (boxes) so they scale with the image? Is there something wrong with the formula I'm using?
Edit:
For example:
The squares are the child elements I mentioned and when the user zooms in or out of the page or if the image's size changes I want the squares position on the image to be preserved and their scale match the image's scale
Ok, so this may not fit into your project straight off the bat but you should be able to get it working with a little bit of tweaking.
Use some JavaScript to calculate the absolute positioning of the child elements to a percentage.
var imgWrapper = document.getElementById("wrapper");
var children = document.getElementsByClassName("child");
window.onresize = function(event) {
var imgWidth = imgWrapper.offsetWidth;
var imgHeight = imgWrapper.offsetHeight;
for (var i = 0; i < children.length; i++)
{
// - Current child element
var child = children.item(i);
// - Child positions
var currentTop = child.offsetTop;
var currentLeft = child.offsetLeft;
var currentBottom = imgHeight - (currentTop + child.offsetHeight);
var currentRight = imgWidth - (currentLeft + child.offsetWidth);
var newTop = (100 * currentTop / imgHeight);
var newLeft = (100 * currentLeft / imgWidth);
var newBottom = (100 * currentBottom / imgHeight);
var newRight = (100 * currentRight / imgWidth);
child.style.top = newTop + "%";
child.style.left = newLeft + "%";
child.style.bottom = newBottom + "%";
child.style.right = newRight + "%";
}
};
http://next.plnkr.co/edit/E8RbqFTClYklW4w7

Image move with mouse position - box issue?

I had originally taken some information from here and expanded on it: onextrapixel.com/examples/interactive-background/index4.html
I have instead incorporated the image to move with mouse position on the page, however there seems to be an issue with there being a top "box" that cuts off some of the hovered image. You can see it in action on a sample page here
My css:
.top-image {
background:url('http://i.imgur.com/wZRaMrB.png');
position:absolute ;
top:400px;
width:100%;
z-index:0;
height:100%;
background-repeat: no-repeat;
}
My js:
$(document).ready(function() {
var movementStrength = 25;
var height = movementStrength / $(window).height();
var width = movementStrength / $(window).width();
$("body").mousemove(function(e){
var pageX = e.pageX - ($(window).width() / 2);
var pageY = e.pageY - ($(window).height() / 2);
var newvalueX = width * pageX * -1 - 25;
var newvalueY = height * pageY * -1 - 50;
$('.top-image').css("background-position", newvalueX+"px "+newvalueY+"px");
});
});
I also hope to repeat this for the right side of the page.
After some suggesting in the comments here is the jsfiddle https://jsfiddle.net/yx1w8ysr/#&togetherjs=D4Q1xTfcaO
If you know the image's size beforehand, you can set the size of your div fixedly and don't need to use background-size:contain. Instead set it to some relative value (less than 100%) so that you have a padding around for the movement of the background image. However if you don't know the size of the image, you should use background-size:contain to ensure that your image sits right inside your div container. However with this approach we cannot control the size of the image anymore. That means you cannot use background-position to move the image around (because the size fits its parent, moving will cause the image be cut off).
So you need some another wrapper/container and move your inner div (.top-image) instead of changing the background-position.
Here is the detailed code:
var movementStrength = 25;
var w = $(window).width();
var h = $(window).height();
$(window).mousemove(function(e) {
var pageX = (e.pageX - w / 2) / w / 2;
var pageY = (e.pageY - h / 2) / h / 2;
var newvalueX = pageX * movementStrength;
var newvalueY = pageY * movementStrength;
$('.top-image').css({
left: newvalueX + 'px',
top: newvalueY + 'px'
});
});
.container {
padding: 25px;
width: 35%;
height: 35%;
position: absolute;
top: 400px;
}
.top-image {
background: url('http://i.imgur.com/wZRaMrB.png');
position: absolute;
background-size: contain;
width: 100%;
z-index: 0;
height: 100%;
background-repeat: no-repeat;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='container'>
<div class="top-image"></div>
</div>

How to make a div which escapes from mouse cursor randomly? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I tried to find a code that makes a div escaping from the cursor randomly but I couldn't find any. Maybe I don't know how to search, maybe it's so easy but my English is not good enough to solve that situation.
I want a div which escapes from cursor randomly in a parent div, can you help me?
Thanks a lot!
Randomized but also animated :
$("#move").mouseenter(function () {
$(this).animate({
top: Math.random() * 300
}, 100);
$(this).animate({
left: Math.random() * 300
}, 100);
});
JSFiddle demo
Cheers :D
Hope it will help:
HTML
<div id="runner">
</div>
CSS
#runner {
position: absolute;
width: 20px;
height: 20px;
background-color: red;
left: 100px;
top: 100px;
}
JS
$("#runner").on('mouseover', function(){
var offset = $(this).offset();
var goX = Math.random() < 0.5 ? -1 : 1;
var goY = Math.random() < 0.5 ? -1 : 1;
$(this).css('top', offset.top + 20 * goY);
$(this).css('left', offset.left + 20 * goX);
});
https://jsfiddle.net/3hLp6myj/
HTML
<div class="touchMeNot"></div>
jQuery
$('.touchMeNot').on('mouseenter',function(e){
var maxX = $(window).width() - $(this).width();
var maxY = $(window).height() - $(this).height();
$(this).css({
'left':getRandomInt(0, maxX),
'top':getRandomInt(0, maxY)
});
});
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
CSS
.touchMeNot{
position:absolute;
border: 1px solid red;
height:50px;
width:50px;
}
Here is the fiddle.
Update
This is done in order to avoid the box going out of the window.
var maxX = $(window).width() - $(this).width();
var maxY = $(window).height() - $(this).height();
We can generalize by using the div width in the function itself.
We've done this as a joke not too long ago, it's quite simple:
$('button').hover(function() {
$(this).text("Can't touch this!");
$(this).css('top', Math.random()*500 + 'px').css('left', Math.random()*600 + 'px');
});
Fiddle example
This has been answered in another question, here is the example that was created http://jsfiddle.net/karalamalar/atNva/ . I believe this is what you was after correct?
jQuery(function($) {
$('#img').mouseover(function() {
var dWidth = $(document).width() - 100, // 100 = image width
dHeight = $(document).height() - 100, // 100 = image height
nextX = Math.floor(Math.random() * dWidth),
nextY = Math.floor(Math.random() * dHeight);
$(this).animate({ left: nextX + 'px', top: nextY + 'px' });
});
});
Here is the other question: Need to animate an image to move away from cursor postion on each mouseover?
Hope this helps.

Adapt random image placement code for flexible layout

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.

Optimizing how my jQuery code is written

I have just currently started learning jQuery and I seem to be able to get it work how I want but I feel that the way that I am writting it is not very efficient. Could anyone assist me in this example below:
$('.tiles-wrapper').css({top:'50%',left:'50%',margin:'-'+($('.tiles-wrapper').height() / 2)+'px 0 0 -'+($('.tiles-wrapper').width() / 2)+'px'});
$(window).resize(function() {
$('.tiles-wrapper').css({top:'50%',left:'50%',margin:'-'+($('.tiles-wrapper').height() / 2)+'px 0 0 -'+($('.tiles-wrapper').width() / 2)+'px'});
});
So here I am positioning a div in the center of the screen. And then it also does it again on window resize as its contents width properties are percentage values. It works perfectly but I can't help but feel that there must be a better way to write this. Any help would be greatly appreciated. Thank you
You can cache the object and trigger the resize event, this way the resize handler is executed on DOM Ready.
$(window).resize(function() {
var $elem = $('.tiles-wrapper');
$elem.css({
top: '50%',
left: '50%',
margin: '-' + ($elem.height() / 2) + 'px 0 0 -' + ($elem.width() / 2) + 'px'
});
}).resize()
var $tilesWrapper = $('.tiles-wrapper');
function setWrapperStyle () {
var halfWidth = $tilesWrapper.width() * 0.5;
var halfHeight = $tilesWrapper.height() * 0.5;
$tilesWrapper.css({
top: '50%',
left: '50%',
margin: '-' + halfHeight + 'px 0 0 -' + halfWidth + 'px'
});
}
setWrapperStyle();
$(window).on('resize', setWrapperStyle);
You should make a fonction with your first line :
function center(){
$('.tiles-wrapper').css({top:'50%',left:'50%',margin:'-'+($('.tiles-wrapper').height() / 2)+'px 0 0 -'+($('.tiles-wrapper').width() / 2)+'px'});
}
and then you call it a first time and you call it when you resize your window:
center();
$(window).resize(center);
Do you really need jquery here ?
You can use directly css
.tiles-wrapper{
top:50% ;
left:50% ;
width: //what u given
height: //what u given
margin-left: //tiles width/2
margin-right: //tiles height/2
position: //absolute or float
}
if you want to calculate height and width dynamically
just write this on document ready
var $elem = $('.tiles-wrapper');
$elem.css({
top: '50%',
left: '50%',
margin: '-' + ($elem.height() / 2) + 'px 0 0 -' + ($elem.width() / 2) + 'px'
});
In re-size it will automatically on center position.

Categories