Javascript random function changing the picture in the html file - javascript

I would like to ask for help completing this homework. Now, before you turn away , i am not asking anyone to write anything for me. I just need someone to point me in the right direction.
So, i need to create a dice game. My problem is that i am having problems finding a way to connect Javascript code to my Dices in the HTML file.
For example:
If the code :
var dice1 = Math.round(Math.random() * 6);
gives me say 4, then i would like for it to show my dice_4.png picture.
This is the code for the cube/dice on the html file.
<div class="wrap">
<div class="cube">
<div class="front"></div>
<div class="back"></div>
<div class="top"></div>
<div class="bottom"></div>
<div class="left"></div>
<div class="right"> </div>
</div>
</div>
And on my css file.
.front {
background-image: url('Pildid/dice_1.png');
background-size:100%;
}
.back {
background-image: url('Pildid/dice_6.png');
background-size:100%;
}
.right {
background-image: url('Pildid/dice_4.png');
background-size:100%;
}
.left {
background-image: url('Pildid/dice_3.png');
background-size:100%;
}
.top {
background-image: url('Pildid/dice_2.png');
background-size:100%;
}
.bottom {
background-image: url('Pildid/dice_5.png');
background-size:100%;
}
I used a 3D cube without the rotation.
To recap, when random gives me say 4 for the first cube, i want the html to show me the .right part of the css file.
Not sure how much sense i am making here, will try to explain better if this is too confusing.
Does anyone have any ideas where i should look?
(Sorry, the format is a little messed up but its my first time and whatnot).
Thank you.

If you have to keep exactly the same HTML arrangement you have:
<div class="wrap">
<div class="cube">
<div class="front"></div>
<div class="back"></div>
<div class="top"></div>
<div class="bottom"></div>
<div class="left"></div>
<div class="right"> </div>
</div>
</div>
Then you need some way to associate dice numbers to cube side div's. I would suggest an array of class names.
var dice1 = Math.round(Math.random() * 5);
var sides = ['front', 'top', 'left', 'right', 'bottom', 'back'];
var cubeSides = document.getElementsByClassName('cube')[0].children;
for (var i = 0; i < cubeSides.length; i++) {
// If you only have a class associated to the cube side div's.
cubeSides[i].style.display = cubeSides[i].className === sides[dice1] ? 'block' : 'none';
// If you can have more than one class in the side div's, use this statement instead of the previous one.
// cubeSides[i].style.display = cubeSides[i].className.split(' ').indexOf(sides[dice1]) > -1 ? 'block' : 'none';
}
See demo.
But, if it is allowed to change the HTML structure to arrange the div's in ascending order:
<div class="wrap">
<div class="cube">
<div class="front"></div>
<div class="top"></div>
<div class="left"></div>
<div class="right"></div>
<div class="bottom"></div>
<div class="back"></div>
</div>
</div>
then the code becomes easier:
var dice1 = Math.round(Math.random() * 5);
var cubeSides = document.getElementsByClassName('cube')[0].children;
for (var i = 0; i < cubeSides.length; i++) {
cubeSides[i].style.display = i === dice1 ? 'block' : 'none';
}
See demo.

var number = Math.round(Math.random() * 5) + 1;
document.getElementById("demo").innerHTML = number;
var image = 'url(Pildid/dice_'+number +'.png)';
document.getElementById('image').innerHTML = image;
// apply
document.getElementsByClassName('image')[0].style.backgroundImage=image;
<p id="demo"></p>
<div id="image"></div>
<div class="image"></div>

Related

Display text in time intervals with CSS and JS

I would like to create, using the setInterval() JS function, a visual effect that displays text one character at the time with an interval of 100ms per character, on an Angular application.
Note that this happens in the index.html within the <app-root> tags, so it will appear only while the app is bootstrapped.
After reading the setInterval() page i thought that this would make the job, so this is my code:
var divs=['rBox','aBox','tBox','sBox'];
var index=-1;
function displayChars(){
for(container of divs){
document.getElementById(container).style.visibility='hidden';
}
var fun = setInterval(display,100);
}
function display(){
if(index < 4){
document.getElementById(divs[++index]).style.visibility='visible'
}else{
clearInterval(fun);
}
}
displayChars();
<app-root>
<div class="rats-div">
<div id="rBox">1</div>
<div id="aBox">2</div>
<div id="tBox">3</div>
<div id="sBox">4..</div>
</div>
</app-root>
But it does not display anything, the divs containing the numbers are there with visibility set to hidden but it seems like they are never set to visible
I can't see where the problem lies. If I look at the code from an algorithmic point of view, I guess I probably don't understand very well the inner working of setInterval().
fun was not declared globally
And index was incremented too much
A rough update to the code:
var divs=['rBox','aBox','tBox','sBox'];
var index=-1;
var fun
function displayChars(){
for(container of divs){
document.getElementById(container).style.visibility='hidden';
}
fun = setInterval(display,100);
}
function display(){
if(index < 3){
document.getElementById(divs[++index]).style.visibility='visible'
}else{
clearInterval(fun);
}
}
displayChars()
<app-root>
<div class="rats-div">
<div id="rBox">1</div>
<div id="aBox">2</div>
<div id="tBox">3</div>
<div id="sBox">4..</div>
</div>
</app-root>
After minor modifications it's working, see below. I changed index to start at 0 and to be used with divs[index++] (so use-then-increment), and to compare it with divs.length instead of hardcoded 4. Also I put variable fun at the global level.
var divs = ['rBox', 'aBox', 'tBox', 'sBox'];
var index = 0;
var fun = -1; // timer handle
function displayChars() {
for (container of divs) {
document.getElementById(container).style.visibility = 'hidden';
}
fun = setInterval(display, 100);
}
function display() {
if (index < divs.length) {
document.getElementById(divs[index++]).style.visibility = 'visible'
} else {
clearInterval(fun);
}
}
displayChars();
<div class="rats-div">
<div id="rBox">1</div>
<div id="aBox">2</div>
<div id="tBox">3</div>
<div id="sBox">4..</div>
</div>
Your variable fun needs to be global, otherwise display() can't
access it
Don't forget to declare container in your for...of loop as an actual variable
You where incrementing index too often
var divs = ['rBox', 'aBox', 'tBox', 'sBox'];
var index = -1;
var fun;
function displayChars() {
for (var container of divs) {
document.getElementById(container).style.visibility = 'hidden';
}
fun = setInterval(display, 100);
}
function display() {
if (index < 3) {
document.getElementById(divs[++index]).style.visibility = 'visible';
} else {
clearInterval(fun);
}
}
displayChars();
<app-root>
<div class="rats-div">
<div id="rBox">1</div>
<div id="aBox">2</div>
<div id="tBox">3</div>
<div id="sBox">4..</div>
</div>
</app-root>
Pure CSS solution, if an option, looks something like this:
.rats-div > div {
opacity: 0; /* or "visibility: hidden" */
animation: opacity .1s forwards;
}
.rats-div > div:nth-child(2) {animation-delay: .1s}
.rats-div > div:nth-child(3) {animation-delay: .2s}
.rats-div > div:nth-child(4) {animation-delay: .3s}
#keyframes opacity {
to {opacity: 1} /* or "visibility: visible / initial" */
}
<div class="rats-div">
<div id="rBox">1</div>
<div id="aBox">2</div>
<div id="tBox">3</div>
<div id="sBox">4..</div>
</div>
var divs=['rBox','aBox','tBox','sBox'];
var index=0;
var fun=null;
function displayChars(){
for(container of divs){
document.getElementById(container).style.visibility='hidden';
}
fun = setInterval(display,100);
}
function display(){
if(index < 4){
document.getElementById(divs[index]).style.visibility='visible'
index++;
}else{
clearInterval(fun);
}
}
displayChars();
<app-root>
<div class="rats-div">
<div id="rBox">1</div>
<div id="aBox">2</div>
<div id="tBox">3</div>
<div id="sBox">4..</div>
</div>
</app-root>
try this code. it should do your job.

Insert div on next line when element is clicked

I am trying to make something similar to what you find in google images. When a picture is clicked, a div with the image appears on the next line over the other images that is under the clicked one.
I have a set of divs with float:left and position:relative. They have different widths. When i click on a div i want a new full width div to appear on the next line. The divs under the clicked one should be bushed down under the full width one.
I tried to do this by looping through the divs and compare the position of the divs to the clicked one like this:
$(".Wrapper").on("click", ".testDivs", function () {
var thisTop = $(this).position().top;
$(".testDivs").each(function(i, obj) {
var otherTop = $(obj).position().top;
if(thisTop < otherTop){
$(".fullWidthDiv").insertBefore(obj);
return;
}
});
});
This doesn't work and I don't really know how I should do this. Any tips/solutions?
This requires a lot of information to explain. So I'd rather suggest reading a blog post on this topic.Hope this will help you.
https://www.sitepoint.com/recreating-google-images-search-layout-css/
Here is a way to achieve that. It will not keep scroll position but that would be another easy fix.
<div class="wrapper">
<div class="row1 row">
<div class="img1 img"></div>
<div class="img2 img"></div>
<div class="img3 img"></div>
</div>
<div class="row2 row">
<div class="img1 img"></div>
<div class="img2 img"></div>
<div class="img3 img"></div>
</div>
<div class="row3 row">
<div class="img1 img"></div>
<div class="img2 img"></div>
<div class="img3 img"></div>
</div>
</div>
I only applied some styling ti increase visibility of the changes.
.img {
width: 32%;
height: 100px;
background-color: #ccc;
display: inline-block;
}
.row {
border: 1px solid green
}
.big-img {
height: 300px;
}
And finally the JS:
$('.img').click(function() {
var expandedImg = '<div class="big-img"></div>';
$('.big-img').remove();
$(this).parent().append(expandedImg);
})
Fiddle: https://jsfiddle.net/a5fm2dup/
why don't you just do
$(".Wrapper").on("click", ".testDivs", function () {
$(this).after($(".fullWidthDiv"));
});
Ended up making a solution based on my initial code. This doesn't require all the CSS the other solution that was postet suggested. Adding rows dynamically was also suggested, but this became very complicated when making it responsive to window resizing. Feel free to reply if you have any comments on this
function positionDiv() {
var checker = false;
var n;
var thisTop = clickedElement.position().top;
$(".testDivs").each(function(i, obj) {
var otherTop = $(obj).position().top;
if(thisTop < otherTop){
$(".testDivs:eq(" + (i-1) + ")").after($(".fullWidthDiv"));
checker = true;
return false;
}
n = i;
});
if (!checker) {
$(".testDivs:eq(" + n + ")").after($(".fullWidthDiv"));
}
}
var clickChecker = null;
$(".wrapper").on("click", ".testDivs", function () {
if (clickChecker === this){
$(".fullWidthDiv").hide();
clickChecker = null;
} else {
$(".fullWidthDiv").show();
clickChecker = this;
}
clickedElement = $(this);
positionDiv();
});
window.onresize = function(event) {
if( clickedElement != null) {
$(".tagTextWrapper").hide();
positionDiv();
$(".tagTextWrapper").show();
}
}

Getting divs next to each other when clicking on a button / JQuery

i am making a kind of storyboard where you can add and remove frames but i need to set divs next to each other, the code i now have it places the div's beneath each other. I want to make it with a loop
Here is my code:
HTML
<div id="storyboard">
<div id="container">
<div class="frame">
<div class="frame__outer">
<div class="frame__inner"></div>
<div class="frame__content"></div>
<div type="button" value="fade_in" class="add__button"> + </div>
</div>
</div>
</div>
</div>
JS
_this.addClickFunction = function() {
var i = 0;
$('.add__button').click(function() {
$('.frame').after('<div id="container'+(i++)+'"></div> <div class="frame__outer"> <div class="frame__inner"></div><div class="frame__content"></div></div>');
});
};
Use append() instead of after() function. This should work:
_this.addClickFunction = function() {
var i = 0;
$('.add__button').click(function() {
$('.frame').append('<div id="container'+(i++)+'"></div> <div class="frame__outer"> <div class="frame__inner"></div><div class="frame__content"></div></div>');
});
};
This works for keeping one .frame element and adding multiple divs to it of the structure:
<div class="container[i]">
<div class="frame__outer">
<div class="frame__inner"></div>
<div class="frame__content"></div>
</div>
</div>
If you want to arrange elements side by side which normaly are block elements and thus are positioned underneath eachother by default use either css floats or css flexbox.
https://css-tricks.com/all-about-floats/
https://css-tricks.com/snippets/css/a-guide-to-flexbox/
i need to set divs next to each other
Try this example to add new story container to all current .container
var i = 1;
$('.add__button').click(function() {
i++;
$(".container").each(function(x) {
$(this).after('<div id="container' + x + '_' + i + '" class="container"><div class="frame"><div class="frame__outer"> <div class="frame__inner"></div><div class="frame__content">story ' + i + '</div></div></div></div>');
});
});
.frame__outer {
padding: 20px;
background: #222;
color: white;
border-bottom: solid 3px green;
margin: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="storyboard">
<input type='button' value='add story' class="add__button" />
<div id="container" class='container'>
<div class="frame">
<div class="frame__outer">
<div class="frame__inner"></div>
<div class="frame__content">story 1</div>
</div>
</div>
</div>
</div>

Find number of columns produced by ng-repeat

I have a div on which i used ng-repeat. It displays the list of photos in a grid. This is all very simple stuff and working fine.
I need to add file explorer like navigation on the items inside the grid. The easiest way would be to know the length of a line (number of items in the line) and then do simple math to calculate where to move the selection based on the key pressed.
The problem i'm having is finding out the length of the line. Is it even doable?
Edit :
<div class="images-cq__item" ng-repeat="photo in displayedPhotos">
<div ng-class="{active: photo.selected}" id="{{photo.uuid}}" ng-click="selectionEvent({value: photo.uuid, event: $event, index: $index})">
<div class="images-cq-statut" ng-show="photo.statusCQ != 'none'">
{{photo.statusCQ}}
</div>
<div class="img-cq">
<img ng-src="{{photo.thumbPath100}}" alt="Alternate Text" />
zoom
</div>
<p>
{{photo.title}}
</p>
<ul class="images-cq-tags">
<li id="{{photo.uuid}}.{{tag.value}}" ng-repeat="tag in tags" style="display:none">
<span>{{tag.name}}</span>
</li>
</ul>
</div>
The displayedPhotos is a simple array with photo objects obtained from the server. It contains several links (thumbnails, original), and some other info but i don't think it is relevant in this case.
This is what i got:
JavaScript
var items = $(".images-cq__item");
var previousTop = null;
var itemsPerRow = 0;
for(var i = 0; i < items.length;i++){
var item = items.eq(i);
var offset = item.offset();
var top = offset.top;
if(!previousTop || (top == previousTop)){
previousTop = top;
itemsPerRow++;
} else{
break;
}
}
console.log(itemsPerRow); // 3
HTML
<div class="container">
<div class="images-cq__item"></div>
<div class="images-cq__item"></div>
<div class="images-cq__item"></div>
<div class="images-cq__item"></div>
<div class="images-cq__item"></div>
<div class="images-cq__item"></div>
<div class="images-cq__item"></div>
<div class="images-cq__item"></div>
<div class="images-cq__item"></div>
<div class="images-cq__item"></div>
</div>
CSS
.container{
width: 400px;
}
.images-cq__item{
width: 120px;
height: 120px;
background: green;
margin-right: 10px;
margin-bottom: 10px;
display: inline-block;
}
You can use {{$index}} inside ng-repeat
See this Angular.js. How to count ng-repeat iterations which satisfy the custom filter

How do I modify this script to use different colors?

I have a page that has a 4x4 grid and two squares change color one white and the other black. I need to know how to ammend the script to make the color white appear before the black one.
Please could someone help me to solve this issue, the code is pasted below:
html:
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"> </script>
<LINK REL=StyleSheet HREF="style1.css" TYPE="text/css" MEDIA=screen>
<SCRIPT LANGUAGE="JavaScript" SRC="script1.js"> </SCRIPT>
</head>
<body>
<div class="container">
<div class="box spacing"></div>
<div class="box spacing"></div>
<div class="box spacing"></div>
<div id="square1id" class="box"></div>
<div class="box spacing"></div>
<div class="box spacing"></div>
<div id="square2id" class="box spacing"></div>
<div class="box"></div>
<div class="box spacing"></div>
<div class="box spacing"></div>
<div class="box spacing"></div>
<div class="box"></div>
<div class="box spacing"></div>
<div class="box spacing"></div>
<div class="box spacing"></div>
<div class="box"></div> </div>
</body>
</html>
css:
body{
background-color:#000000;
margin:0;
padding:0;
}
h1{
color:#ffffff;
text-align:center;
}
.container{
overflow:hidden;
width:860px;
margin-left:250px;
margin-top:20px;
}
.box{
width:210px;
height:120px;
float:left;
background-color:#4D4D4D;
margin-bottom:3px;
}
.spacing{
margin-right:3px;
}
JavaScript:
$(document).ready(function(){
var colourinfo = {
square1id: [
'#FFE600'
],
square2id: [
'#008B45'
]
};
var count = 0;
var changecol = function(){
$.each(colourinfo, function(tileid, colarray){
$('#'+tileid).css('background-color', colarray[count%colarray.length]);
});
count++;
};
setInterval(changecol, 1000);
});
I would appreciate any help on this. Thank you.
The following sets up an array where each element is an object giving the normal and highlight colour for each square. Called via setInterval() the changeColour() function changes the colour of the last square back to normal and the next square to highlight:
var colourInfo = [
{id : "square1id",
colourNormal : "#4D4D4D",
colourHighlight : "#FFE600"},
{id : "square2id",
colourNormal : "#4D4D4D",
colourHighlight : "#008B45"}
// add your other squares' info here
];
var index = 0;
var changeColour = function(){
$('#'+colourInfo[index]["id"]).css('background-color',
colourInfo[index]["colourNormal"]);
if (++index >= colourInfo.length)
index = 0;
$('#'+colourInfo[index]["id"]).css('background-color',
colourInfo[index]["colourHighlight"]);
}
setInterval(changeColour,1000);
Note: the if statement in the middle of the changeColour() function just increments the index and keeps looping around and around the array in order. If you want the squares to change colour in random order you could replace the if statement with something like
index = Math.floor(Math.random() * colourInfo.length);
EDIT: I assumed above (due to David's use of setInterval()) that the idea was to keep changing the colours indefinitely. Now that I find the idea was to flash each square once I'd suggest the following (untested) change. (Yes, I know this is getting clunky, but I couldn't be bothered starting from scratch and I figure the point is to give David some ideas on how he might do it, not to do his work for him and present a beautifully unit-tested and documented masterpiece.)
var index = -1;
var changeColour = function(){
if (index > -1) {
$('#'+colourInfo[index]["id"]).css('background-color',
colourInfo[index]["colourNormal"]);
}
if (++index < colourInfo.length) {
$('#'+colourInfo[index]["id"]).css('background-color',
colourInfo[index]["colourHighlight"]);
setTimeout(changeColour,1000);
}
}
setTimeout(changeColour,1000);
Looks like the colors are set in colourInfo. Try this:
var colourinfo = {
square1id: ['#FFFFFF'],
square2id: ['#000000']
};

Categories