i found a script that would position divs / images randomly. However, it isn't completely working the way i want/need it to.
The images are loaded each within a div (which isn't ideal i guess). I have around 30 images.
But they don't load nicely and var posy = (Math.random() * ($(document).height() - 0)).toFixed(); doesn't work nicely either. The images mostly load on top (i think that the images in the blog don't count so it gets the height without images?)
So what I want: Load the in more nicely Randomize them so they get to the bottom of the page, too
var circlePosition = document.getElementsByClassName('circle');
console.log(circlePosition);
function position() {
for (var i = 0; i < circlePosition.length; i++ ) {
//give circle a random position
var posx = (Math.random() * ($(document).width() - 0)).toFixed();
var posy = (Math.random() * ($(document).height() - 0)).toFixed();
//apply position to circle
$(circlePosition[i]).css({
'position':'absolute',
'left':posx+'px',
'top':posy+'px',
})
}
} //end function position
var circleTotal = circlePosition.length;
$('.circle').click(function() {
$(this).fadeOut();
circleTotal = circleTotal - 1;
console.log(circleTotal);
if(circleTotal == 0) {
position()
$('.circle').fadeIn();
}
});
position();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img src="//placehold.it/1x5000"> <!-- Placeholder image to show issue -->
<div class="circle">
<img src="http://static.tumblr.com/tensqk8/k8anq0438/01.png">
</div>
<div class="circle">
<img src="http://static.tumblr.com/tensqk8/k8anq0438/01.png">
</div>
A clean and readable and solution without a jQuery dependence might be something like this. It avoids unnecessarily wrapping your images in divs by positioning the images themselves. It includes a hidden element as a sort of "poor man's" shadow DOM.
http://jsfiddle.net/sean9999/yv9otwr7/9/
;(function(window,document,undefined){
"use strict";
var init = function(){
var canvas = document.querySelector('#x');
var icon_template = document.querySelector('#template');
var icon_width = 40;
var icon_height = 30;
var the_images = [
'http://static.tumblr.com/tensqk8/k8anq0438/01.png',
'http://static.tumblr.com/tensqk8/rYanq05el/04.png',
'http://static.tumblr.com/tensqk8/SYknq05py/05.png',
'http://static.tumblr.com/tensqk8/s7inq057d/03.png'
];
var pickRandomImage = function(){
var i = Math.floor( Math.random() * the_images.length );
return the_images[i];
};
var total_number_of_images = 10;
var max_height = canvas.offsetHeight - icon_height;
var max_width = canvas.offsetWidth - icon_width;
var randomCoordinate = function(){
var r = [];
var x = Math.floor( Math.random() * max_width );
var y = Math.floor( Math.random() * max_height );
r = [x,y];
return r;
};
var createImage = function(){
var node = icon_template.cloneNode(true);
var xy = randomCoordinate();
node.removeAttribute('id');
node.removeAttribute('hidden');
node.style.top = xy[1] + 'px';
node.style.left = xy[0] + 'px';
node.setAttribute('src',pickRandomImage());
canvas.appendChild(node);
};
for (var i=0;i<total_number_of_images;i++){
createImage();
};
};
window.addEventListener('load',init);
})(window,document);
body {
background-color: #fed;
}
#x {
border: 3px solid gray;
background-color: white;
height: 400px;
position: relative;
}
#x .icon {
position: absolute;
z-index: 2;
}
<h1>Randomly distributed images</h1>
<div id="x"></div>
<img src="#" class="icon" hidden="hidden" id="template" />
try moving your position(); call inside the $(window).load function.
I think maybe the images are being positioned before all the images have loaded, so the page is shorter then.
Related
I want to split multiple images into tiles(it must be div or similar). (With Javascript or jQuery.)
and Images should be one below the other.
Its my div;
<div class="reading-content">
<div class="page-break no-gaps">
<img id="image-0" src="image.jpg" class="some-class">
</div>
<div class="page-break no-gaps">
<img id="image-1" src="image1.jpg" class="some-class">
</div>
</div>
example jsfiddle; http://jsfiddle.net/0Lxr2tad/
var t = Date.now();
var img = new Image();
var length = 30;
var ylength = 20;
img.onload = function() {
var width = this.width,
height = this.height,
_length = -length,
i, j;
// create a <div/> with all basic characteristics, to be cloned over and over in the loops below.
var $basicDiv = jQuery('<div/>', {
class: 'splitImg',
css: {
'width': Math.floor(width/length),
'height': Math.floor(height/ylength),
'background-image': 'url(' + img.src + ')'
}
});
// Finding a node in the DOM is slow. Do it once and assign the returned jQuery collection.
// Also, #wrapper's width can be set here.
var $wrapper = $('#wrapper').width(width + length * 2);
for (i = 0; i > _length; i--) {
for (j = 0; j > _length; j--) {
$basicDiv.clone().css({'background-position': `${width/length * j}px ${height/ylength * i}px`}).appendTo($wrapper);
}
}
console.log(Date.now() - t);
}
img.src = 'http://www.jqueryscript.net/images/Simplest-Responsive-jQuery-Image-Lightbox-Plugin-simple-lightbox.jpg'; // how to do multiple this??
Anyone can help?
I don't use jquery much so I can suggest javascript option like this:
const targetElement = document.querySelector(...) // I choose the div that we are going to append newdivs
I don't know if it exists but I assume there is an array of content you use for src urls or any other data.
let arrayOfInfo = [{},{}] // this is a hypothetical array of objects that we will use
arrayOfInfo.forEach(obj => {
let newDiv = document.createElement("div");
newDiv.classList.add("page-break","no-gaps")
newDiv.innerHTML=`<img id="image-${obj.index}" src=${obj.url} class="some-class">`
targetElement.append(newDiv);
})
so with that approach you automate everything. If you need to reuse, you can make it into a function and run it wherever you need. It is also handy if you need to change some content later on, so you only change the array values and rest goes auto again.
I hope this was what you need.
I tried to do it again after a long time and I was able to do it yesterday, anyone can use it. ( You can remove .splitImg { some style } class for remove spaces. )
JSFiddle Example
let i = 0;
let seenUrls = new Set()
setInterval(() => {
let url = document.querySelectorAll('#someid p img')[i].src;
let image = document.querySelectorAll('#someid p')[i]
let gor = document.querySelectorAll('#someid p')
if (!seenUrls.has(url)) {
seenUrls.add(url)
var t = Date.now();
var img = new Image();
var length = 5;
var ylength = 5;
img.onload = function() {
var width = this.width,
height = this.height,
_length = -length,
i, j;
// create a <div/> with all basic characteristics, to be cloned over and over in the loops below.
var $basicDiv = jQuery('<div/>', {
class: 'splitImg',
css: {
'width': Math.floor(width/length),
'height': Math.floor(height/ylength),
'background-image': 'url(' + img.src + ')'
}
});
// Finding a node in the DOM is slow. Do it once and assign the returned jQuery collection.
// Also, #wrapper's width can be set here.
var $wrapper = image;
image.style.width = width + length * 2 + "px";
for (i = 0; i > _length; i--) {
for (j = 0; j > _length; j--) {
$basicDiv.clone().css({'background-position': `${width/length * j}px ${height/ylength * i}px`}).appendTo($wrapper);
}
}
console.log(Date.now() - t);
}
img.src = url
i = (i + 1) % gor.length;
}
}, 50)
#someid {
max-width: 100%;
}
#someid p {
display:flex;
flex-wrap:wrap;
margin: 0 auto;
}
#someid p img {
display: none!important;
}
.splitImg {
padding: 1px;
background-clip: content-box;
background-repeat: no-repeat;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<div id="someid">
<p>
<img src="http://www.jqueryscript.net/images/Simplest-Responsive-jQuery-Image-Lightbox-Plugin-simple-lightbox.jpg" />
</p>
<p>
<img src="https://www.jqueryscript.net/images/Responsive-Touch-Friendly-jQuery-Gallery-Lightbox-Plugin-lightGallery.jpg" />
</p>
</div>
I need this one image to be in a random position on the screen every time i refresh the page, i found a javascript code that could work but i just don't know how to make it work.
this is my html
<body>
<p>
find rufus
</p>
<img src="molerat.jpg" id="molerat"></img>
</body>
javascript:
console.log();
function onloadFunction() {
var amount = 10;
var arrayIDs = "molerat";
for (i=1;i<=amount;i++) {
var element = document.getElementById(arrayIDs[i-1]);
var positionInfo = element.getBoundingClientRect();
var imgHeight = positionInfo.height;
var imgWidth = positionInfo.width;
var screenWidth = window.innerWidth;
var screenHeight = window.innerHeight;
var imgLeft = Math.floor(Math.random() * (screenWidth - imgWidth));
var imgTop= Math.floor(Math.random() * (screenHeight - imgHeight));
document.getElementById(arrayIDs[i-1]).style.top = imgTop+"px";
document.getElementById(arrayIDs[i-1]).style.left = imgLeft+"px";
}
}
css:
body{
background-color:white;
font-family: monospace;
font-size: 50px;
}
img {
position: absolute;
}
arrayIDs is not an array.
var arrayIDs = "molerat"; needs to be var arrayIDs = ["molerat"];
Also you only have 1 image so the amount needs to be set to 1
function onloadFunction() {
var amount = 1;
var arrayIDs = ["molerat"];
for (i=1;i<=amount;i++) {
var element = document.getElementById(arrayIDs[i-1]);
var positionInfo = element.getBoundingClientRect();
var imgHeight = positionInfo.height;
var imgWidth = positionInfo.width;
var screenWidth = window.innerWidth;
var screenHeight = window.innerHeight;
var imgLeft = Math.floor(Math.random() * (screenWidth - imgWidth));
var imgTop= Math.floor(Math.random() * (screenHeight - imgHeight));
document.getElementById(arrayIDs[i-1]).style.top = imgTop+"px";
document.getElementById(arrayIDs[i-1]).style.left = imgLeft+"px";
}
}
onloadFunction();
body{
background-color: white;
font-family: monospace;
font-size: 50px;
}
img {
position: absolute;
}
<p>
find rufus
</p>
<img src="https://picsum.photos/200" id="molerat" />
Your onloadFunction needs to be invoked, when the page loads. If you're using jQuery in your project, then $(document).ready(...) is the way to go:
$(onloadFunction)
Otherwise you might want to check this question for pure JavaScript $(document).ready(...) alternatives.
I have created random stars using a js unction which manipulates CSS based on window height & width. My goal was to fit them at all-time in the viewport as I resize the height and width of the window.
The problem is every time that I resize the window, the js function adds CSS to previous ones without removing them first which causes a horizontal scroll and other unappealing visual issues.
Is there any way to prevent that? perhaps disabling and re-enabling the function or something else that fits the stars exactly in the viewport and make them behave dynamically as the width and height change without keeping the previous applied css properties and values?
<style>
body, html {margin: 0;}
#header {display: grid;background-color: #2e2e2e;width: 100vw;height: 100vh;overflow: hidden;}
#header i {position: absolute;border-radius: 100%;background: grey; }
</style>
<body>
<div id="header"></div>
<script>
window.onresize = function() {
skyCity();
};
function skyCity() {
for( var i=0; i < 400; i++) {
var header = document.getElementById("header"),
cityLight = document.createElement("i"),
x = Math.floor(Math.random() * window.innerWidth * .98),
y = Math.floor(Math.random() * window.innerHeight),
size = Math.random() * 1.5;
animate = Math.random() * 50;
cityLight.style.left = x + 'px';
cityLight.style.top = y + 'px';
cityLight.style.width = size + 1.5 + 'px';
cityLight.style.height = size + 1.5 + 'px';
cityLight.style.opacity = Math.random();
cityLight.style.animationDuration = 10 + animate + 's';
header.appendChild(cityLight);
}
};
skyCity();
</script>
</body>
Simply said, every time you resize, you call skyCity() which runs header.appendChild(cityLight); 400 times. It is just programmed to add new lights...
You can, a) remove every <i> from #header in skyCity() before the loop,
and b), b for better, init the 400 <i> once on load, on then on resize just update their properties.
it seems that the issue is it appends more i tags or stars when resizing, not really css issue.
I suggest to clear the wrapper #header before adding more <i>s.
You can do something like this:
window.onresize = function() {
skyCity();
};
function skyCity() {
var header = document.getElementById("header")
header.innerHTML=''
for( var i=0; i < 400; i++) {
var cityLight = document.createElement("i"),
x = Math.floor(Math.random() * window.innerWidth * .98),
y = Math.floor(Math.random() * window.innerHeight),
size = Math.random() * 1.5;
animate = Math.random() * 50;
cityLight.style.left = x + 'px';
cityLight.style.top = y + 'px';
cityLight.style.width = size + 1.5 + 'px';
cityLight.style.height = size + 1.5 + 'px';
cityLight.style.opacity = Math.random();
cityLight.style.animationDuration = 10 + animate + 's';
header.appendChild(cityLight);
}
};
skyCity();
#header {display: grid;background-color: #2e2e2e;width: 100vw;height: 100vh;overflow: hidden;}
#header i {position: absolute;border-radius: 100%;background: grey; }
<div id="header"></div>
You can check the full page link so you can try to resize the window
I would suggest you keep the "stars" as an array (cityLights in the code below) and apply the new style every time the browser size changes.
<style>
body, html {margin: 0;}
#header {display: grid;background-color: #2e2e2e;width: 100vw;height: 100vh;overflow: hidden;}
#header i {position: absolute;border-radius: 100%;background: grey; }
</style>
<body>
<div id="header"></div>
<script>
window.onresize = function() {
skyCity();
};
var header = document.getElementById("header");
var cityLights = []
for( var i=0; i < 400; i++) {
cityLights.push(document.createElement("i"));
}
function skyCity() {
for( var i=0; i < 400; i++) {
var cityLight = cityLights[i],
x = Math.floor(Math.random() * window.innerWidth * .98),
y = Math.floor(Math.random() * window.innerHeight),
size = Math.random() * 1.5;
animate = Math.random() * 50;
cityLight.style.left = x + 'px';
cityLight.style.top = y + 'px';
cityLight.style.width = size + 1.5 + 'px';
cityLight.style.height = size + 1.5 + 'px';
cityLight.style.opacity = Math.random();
cityLight.style.animationDuration = 10 + animate + 's';
header.appendChild(cityLight);
}
};
skyCity();
</script>
</body>
I'm trying to create 'snow' on the background of a single div. The code is below but you can see it here: http://www.getwiththebrand.com/makeabrew_copy/
I want to put the effect on the div with the red border only (number 4).
Can anyone tell me what I'm missing?
<!-- language: lang-js -->
var width = getWidth();
var height = getHeight();
var flakeCount = 50;
var gravity = 0.7;
var windSpeed = 20;
var flakes = [];
function getWidth() {
var x = 0;
if (self.innerHeight) {
x = self.innerWidth;
}
else if (document.documentElement && document.documentElement.clientHeight) {
x = document.documentElement.clientWidth;
}
else if (document.body) {
x = document.body.clientWidth;
}
return x;
}
function getHeight() {
var y = 0;
if (self.innerHeight) {
y = self.innerHeight;
}
else if (document.documentElement && document.documentElement.clientHeight) {
y = document.documentElement.clientHeight;
}
else if (document.body) {
y = document.body.clientHeight;
}
return y;
}
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
var currentFlake = 0;
var snowglobe = document.getElementById("snowglobe");
while (currentFlake < flakeCount) {
var flake = document.createElement("div");
flake.className = 'flake';
flake.style.fontSize = getRandom(12, 24) + 'px';
flake.style.top = getRandom(0, height) + 'px';
flake.style.left = getRandom(0, width) + 'px';
flake.innerHTML = "•";
newFlake = snowglobe.appendChild(flake);
newFlake.speed = getRandom(1, 100);
flakes.push(newFlake);
currentFlake++;
}
function doAnimation() {
for (var i = 0; i < flakes.length; i++) {
newX = false;
newY = false;
// Calculate Y position
newY = parseFloat(flakes[i].style.top) + (flakes[i].speed / 100) * gravity;
if (newY > height) {
newY = 0 - parseInt(flakes[i].style.fontSize);
// If Y is at bottom, randomize X
newX = getRandom(0, width);
}
// Calculate X position if it hasn't been set randomly
if (!newX) newX = parseFloat(flakes[i].style.left) + Math.sin(newY / windSpeed);
if (newX < -20) newX = width + 20;
if (newX > width + 20) newX = -20;
// Set new position
flakes[i].style.top = newY + 'px';
flakes[i].style.left = newX + 'px';
}
}
setInterval(doAnimation, 10);
window.onresize = function(event) {
width = getWidth();
height = getHeight();
}
<!-- language: lang-css -->
#snowglobe .flake {
position: absolute;
width: 1px;
height: 1px;
color: rgba(255,255,255,0);
text-shadow: 0 0 3px rgba(255,255,255,1);
}
<!-- language: lang-html -->
<div class="ui-full-width">
<div class="container even" id="snowglobe">
<h3><span class="num">4</span>Add freshly boiled water to the pot</h3>
<p>Give it a stir and secure the lid. Wrap your pot in a tea-cosy if it's nippy outside!</p>
</div>
</div>
<!-- end snippet -->
<div class="ui-full-width">
<div class="container even" id="snowglobe">
<h3><span class="num">4</span>Add freshly boiled water to the pot</h3>
<p>Give it a stir and secure the lid. Wrap your pot in a tea-cosy if it's nippy outside!</p>
</div>
</div>
Your myjs.js has an extra character at the end of the file when it's loaded in my browser and it triggers a rightful
SCRIPT1014: Invalid character
myjs.js (116,2)
The script part:
window.onresize = function(event) {
width = getWidth();
height = getHeight();
}â // << here
Also, I don't know what browser you're using but try hitting F12, you'll get the console and you'll see javascript erros and other useful informations.
Edit: it's even worse, you have multiple characters at the end of your script:
window.onresize = function(event) {
width = getWidth();
height = getHeight();
}​ // ??
Did you mess around with some file encoding options?
thanks for looking. I commented out the code so that's what the extra characters were. I haven't done anything to the file encoding options.
I checked the console and there were some elements undefined. Looks like I missed a whole chunk:
var width = getWidth();
var height = getHeight();
var flakeCount = 50;
var gravity = 0.7;
var windSpeed = 20;
var flakes = [];
All good now!
I'm trying to build a draggable column based layout in JavaScript and having a bit of hard time with it.
The layout comprises of 3 columns (divs), with two dragable divs splitting each. The idea is that they are positioned absolutely and as you drag the draggers, the columns' respective widths, and left values are updated.
The three columns should always span the full width of the browser (the right most column is 100% width), but the other two should remain static by default when the browser is resized (which is why i'm using px, not %).
My code isn't working as of yet, I'm relatively new to JavaScript (which is why I don't want to use jQuery).
Having said that, there must be a more efficient (and cleaner) way of achieving this with less code that works (without reaching for the $ key).
If anyone with some awesome JS skills can help me out on this I'd be super-appreciative.
Here's the fiddle I'm working on http://jsfiddle.net/ZFwz5/3/
And here's the code:
HTML
<!-- colums -->
<div class="col colA"></div>
<div class="col colB"></div>
<div class="col colC"></div>
<!-- draggers -->
<div class="drag dragA" style="position: absolute; width: 0px; height: 100%; cursor: col-resize; left:100px;"><div></div></div>
<div class="drag dragB" style="position: absolute; width: 0px; height: 100%; cursor: col-resize; left: 300px;"><div></div></div>
CSS:
body {
overflow:hidden;
}
.col {
position: absolute;
height:100%;
left: 0;
top: 0;
overflow: hidden;
}
.colA {background:red;width:100px;}
.colB {background:green; width:200px; left:100px;}
.colC {background:blue; width:100%; left:300px;}
.drag > div {
background: 0 0;
position: absolute;
width: 10px;
height: 100%;
cursor: col-resize;
left: -5px;
}
and my terrible JavaScript:
//variabe columns
var colA = document.querySelector('.colA');
var colB = document.querySelector('.colB');
var colC = document.querySelector('.colC');
//variable draggers
var draggers = document.querySelectorAll('.drag');
var dragA = document.querySelector(".dragA");
var dragB = document.querySelector(".dragB");
var dragging = false;
function drag() {
var dragLoop;
var t = this;
var max;
var min;
if (dragging = true) {
if (this == dragA) {
min = 0;
max = dragB.style.left;
} else {
min = dragA.style.left;
max = window.innerWidth;
}
dragLoop = setInterval(function () {
var mouseX = event.clientX;
var mouseY = event.clientY;
if (mouseX >= max) {
mouseX = max;
}
if (mouseY <= min) {
mouseY = min;
}
t.style.left = mouseX;
updateLayout();
}, 200);
}
}
function updateLayout() {
var posA = dragA.style.left;
var posB = dragB.style.left;
colB.style.paddingRight = 0;
colA.style.width = posA;
colB.style.left = posA;
colB.style.width = posB - posA;
colC.style.left = posB;
colC.style.width = window.innerWidth - posB;
}
for (var i = 0; i < draggers.length; i++) {
draggers[i].addEventListener('mousedown', function () {
dragging = true;
});
draggers[i].addEventListener('mouseup', function () {
clearInterval(dragLoop);
dragging = false;
});
draggers[i].addEventListener('mouseMove', function () {
updateLayout();
drag();
});
}
I see a couple of things wrong here. First of all, the mousemove event only fires on an element when the mouse is over that element. You might have better luck registering a mousemove listener on the parent of your div.drag elements, then calculating the mouse's position inside that parent whenever a mouse event happens, then using that position to resize your columns and your draggers.
Second, I'm not quite sure what you're trying to do by registering a function with setInterval. You're doing pretty well with registering event listeners; why not continue to use them to change the state of your DOM? Why switch to a polling-based mechanism? (and the function you pass to setInterval won't work anyway - it refers to a variable named event, which in that context is undefined.)
This is just a little example... I hope it can help you :)
window.onload = function() {
var myDiv = document.getElementById('myDiv');
function show_coords(){
var monitor = document.getElementById('monitor');
var x = event.clientX - myDiv.clientWidth / 2;
var y = event.clientY - myDiv.clientWidth / 2;
monitor.innerText = "X: " + x + "\n" + "Y: " + y;
myDiv.style.left = x + "px";
myDiv.style.top = y + "px";
}
document.onmousemove = function(){
if(myDiv.innerText == "YES"){show_coords();}
}
myDiv.onmousedown = function(){
myDiv.innerText = "YES";
}
myDiv.onmouseup = function(){
myDiv.innerText = "NO";
}
}