I am trying to create 5 images in 5 different places inside my div#leftside. I do create 5 images, but they are in the same position and are not randomly spread inside my div. Here is a code... Can someone help?
<!DOCTYPE html>
<html lang="en">
<head http-equiv="content-type" content="text/html; charset=utf-8">
<title>Matching game</title>
<style type="text/css">
img {position: absolute;}
div {position: absolute;width: 500px;height: 500px;}
#rightSide { left: 500px;
border-left: 1px solid black }
</style>
<script type="text/javascript">
function generateFaces() {
var numberOfFaces = 5;
var theLeftSide = document.getElementById("leftSide");
var i = 0;
var topvar = (Math.floor(Math.random()*400));
var leftvar = (Math.floor(Math.random()*400));
if (i < 5){
numberOfFaces = document.createElement("img");
i++;
numberOfFaces.src = "http://home.cse.ust.hk/~rossiter/mooc/matching_game/smile.png";
numberOfFaces.style.top = topvar + 'px';
numberOfFaces.style.left = leftvar + 'px';
theLeftSide.appendChild(numberOfFaces);
}
}
</script>
</head>
<body onload="generateFaces()">
<p>Click on the extra smiling face on the left.</p>
<div id="leftSide"></div>
<div id="rightSide"></div>
</body>
</html>
You were using an if statement when you intended a while loop. Also, you needed to move the positioning logic into the loop.
https://jsfiddle.net/knwL2bn4/
Refactor:
<!DOCTYPE html>
<html lang="en">
<head http-equiv="content-type" content="text/html; charset=utf-8">
<title>Matching game</title>
<style type="text/css">
img {position: absolute;}
div {position: absolute;width: 500px;height: 500px;}
#rightSide { left: 500px;
border-left: 1px solid black }
</style>
<script type="text/javascript">
function generateFaces() {
var numberOfFaces = 5;
var theLeftSide = document.getElementById("leftSide");
var i = 0;
while (i < 5){
var topvar = (Math.floor(Math.random()*400));
var leftvar = (Math.floor(Math.random()*400));
numberOfFaces = document.createElement("img");
i++;
numberOfFaces.src = "http://home.cse.ust.hk/~rossiter/mooc/matching_game/smile.png";
numberOfFaces.style.top = topvar + 'px';
numberOfFaces.style.left = leftvar + 'px';
theLeftSide.appendChild(numberOfFaces);
}
}
</script>
</head>
<body onload="generateFaces()">
<p>Click on the extra smiling face on the left.</p>
<div id="leftSide"></div>
<div id="rightSide"></div>
</body>
</html>
You should use for loop
function generateFaces() {
var numberOfFaces = 5;
var theLeftSide = document.getElementById("leftSide");
var i;
for (i = 0; i < 5; i += 1) {
var topvar = (Math.floor(Math.random()*400));
var leftvar = (Math.floor(Math.random()*400));
numberOfFaces = document.createElement("img");
numberOfFaces.src = "http://home.cse.ust.hk/~rossiter/mooc/matching_game/smile.png";
numberOfFaces.style.top = topvar + 'px';
numberOfFaces.style.left = leftvar + 'px';
theLeftSide.appendChild(numberOfFaces);
}
}
Not quite sure what you are trying to do there, but I rewrote it in a Fiddle. You might have to tweak it to get it to do what you want:
Fiddle
HTML
<body>
<p>Click on the extra smiling face on the left.</p>
<div id="leftSide"></div>
<div id="rightSide"></div>
</body>
Javascript
function generateFaces() {
var face;
var theLeftSide = document.getElementById("leftSide");
for (i = 0; i < 5; i++) {
var topvar = (Math.floor(Math.random() * 400));
var leftvar = (Math.floor(Math.random() * 400));
face = document.createElement("img");
face.src = "http://home.cse.ust.hk/~rossiter/mooc/matching_game/smile.png";
face.style.top = topvar + 'px';
face.style.left = leftvar + 'px';
theLeftSide.appendChild(face);
}
}
generateFaces();
CSS
img {
position: absolute;
}
div {
position: absolute;
width: 500px;
height: 500px;
}
Related
I've been working with JS for about two weeks, and I'm working on a little project. The goal was to be able to change the color on each individual character in a given string when pressing the button. I've gotten that far.
As you can see, I added spans to each character, so that I can individually edit them. I'm trying to apply a transition to the spans so that when I click the button, the color fades to another color instead of just instantaneously changing. Is that possible?
Here's the codepen:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" href="CSS/textColorV2.css">
</head>
<body>
<p id="letter">Color</p>
<button>Click ME</button>
<script type="text/javascript" src="JS/textColorV2.js"></script>
</body>
</html>
CSS
bodybody {
background-color: #FFE7E0;
}
span{
transition: all 4s;
}
#letter {
font-size: 9em;
position: absolute;
top: 30%;
left: 50%;
transform: translate(-50%, -50%);
color:blue;
}
JS
var letter = document.getElementById("letter");
var text = letter.innerHTML;
var button = document.querySelector("button");
button.addEventListener("click", function () {
var newText = "";
for (var i = 0; i < text.length; i++) {
newText += '<span style="color:' + randomColor() + '">' +
text.charAt(i) + '</span>';
letter.innerHTML = newText;
letter.classList.add("trans");
};
});
function randomColor() {
//r
var r = Math.floor(Math.random() * 256);
//g
var g = Math.floor(Math.random() * 256);
//b
var b = Math.floor(Math.random() * 256);
return "rgb(" + r + " ," + g + " ," + b + ")";
}
This is absolutly possible. The key idea here is to separate your string into span elements (per character) at the start of your script, rather than during each click event.
Taking this approach will simplify your implementation - all you need to do in the button click handler is assign a new "random color" to each span element, and leave the CSS transition(s) to the browser to handle:
var letter = document.getElementById("letter");
var text = letter.innerHTML;
var button = document.querySelector("button");
// Convert inner text node to span nodes for each character
// at beginning of script
var text = letter.innerText;
letter.innerText = '';
for(var i = 0; i < text.length; i++) {
var character = text[i];
letter.innerHTML += '<span style="color:' + randomColor() + '">' + character + '</span>';
}
button.addEventListener("click", function () {
// For each span/character of #letter, assign a new random
// color. This causes the browser to handle the CSS color
// transition for you
for(var span of document.querySelectorAll('#letter span')) {
span.style.color = randomColor();
}
});
function randomColor() {
var r = Math.floor(Math.random() * 256);
var g = Math.floor(Math.random() * 256);
var b = Math.floor(Math.random() * 256);
return "rgb(" + r + " ," + g + " ," + b + ")";
}
span{
transition: all 4s;
}
#letter {
font-size: 9em;
position: absolute;
top: 30%;
left: 50%;
transform: translate(-50%, -50%);
color:blue;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" href="CSS/textColorV2.css">
</head>
<body>
<p id="letter">Color</p>
<button>Click ME</button>
</body>
</html>
Here is a more concise version of the same...
const letters = document.querySelectorAll('.letters');
const button = document.querySelector('button');
button.addEventListener('click', () => {
letters.forEach(element => {
element.style.transition = '1s';
element.style.color = randomColor();
});
});
const randomColor = () => {
const r = Math.floor(Math.random() * 256);
const g = Math.floor(Math.random() * 256);
const b = Math.floor(Math.random() * 256);
return `rgb(${r} ,${g},${b})`;
};
body {
background-color: #ffe7e0;
}
#wrapper {
font-size: 4em;
position: absolute;
top: 30%;
left: 50%;
transform: translate(-50%, -50%);
color: blue;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="index.css">
<title>Document</title>
</head>
<body>
<div id="wrapper">
<span class="letters">C</span>
<span class="letters">o</span>
<span class="letters">l</span>
<span class="letters">o</span>
<span class="letters">r</span>
</div>
<button>Click ME</button>
<script src="index.js"></script>
</body>
</html>
I am trying to create a grid which takes a user input and uses that as its number of rows and columns. In other words, if the user inputs X, I want the grid to have X rows and X columns, and be square, meaning the boxes are as high as they are wide.
I have gotten it to work with JavaScript and CSS grid, but only if I already know the number of rows/columns, in that case 10. Please see below.
How can I create a grid that does the same but with any number of rows and columns?
#container {
display: grid;
grid-template-columns: repeat(10, 1fr);
width: 500px;
height: 500px;
}
div {
width: 100%;
height: 100%;
outline: 1px solid;
float: left;
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css">
<title>Etch-a-sketch</title>
</head>
<body>
<h1>Etch-a-sketch</h1>
<button id="start">Start</button>
<div id="container"></div>
</body>
<script>
let btn = document.getElementById("start")
btn.addEventListener("click", createGrid)
function createGrid() {
let numberOfRows = prompt("How many rows do you want?");
let i = 0;
let x = numberOfRows ** 2;
for (i; i < x; i++) {
var div = document.createElement("div");
document.getElementById("container").appendChild(div);
div.addEventListener("mouseenter", function() {
this.style.backgroundColor = "red";
});
}
}
</script>
</html>
You can use CSS variable for that. and change the variable value using javascript.
let btn = document.getElementById("start")
btn.addEventListener("click", createGrid)
function createGrid() {
var Container = document.getElementById("container");
Container.innerHTML = '';
let numberOfRows = prompt("How many rows do you want?");
let i = 0;
let x = numberOfRows * numberOfRows;
document.documentElement.style.setProperty("--columns-row", numberOfRows);
for (i = 0; i < x ; i++) {
var div = document.createElement("div");
document.getElementById("container").appendChild(div);
div.addEventListener("mouseenter", function () {
this.style.backgroundColor = "red";
});
}
}
:root {
--columns-row: 2;
}
#container {
display: grid;
grid-template-columns: repeat(var(--columns-row), 1fr);
grid-template-rows: repeat(var(--columns-row), 1fr);
width: 500px;
height: 500px;
}
div {
border: 1px solid #000;
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css">
<title>Etch-a-sketch</title>
</head>
<body>
<h1>Etch-a-sketch</h1>
<button id="start">Start</button>
<div id="container">
</div>
</body>
</html>
Change your css as per your need. jsfiddle.net/926pd5oh/9
<h1>Etch-a-sketch</h1>
<button id="start">Start</button>
<div id="container"></div>
<style>
#container>div {
width: 100%;
height: 10px;
margin: 2px;
}
#container>div>div {
float: left;
height: 10px;
border-right: 1px solid #ccc;
border-bottom: 1px solid #ccc;
width: 25px;
}
</style>
<script>
let btn = document.getElementById("start")
btn.addEventListener("click", createGrid);
function createGrid() {
let numberOfRows = prompt("How many rows do you want?");
document.getElementById("container").innerHTML = "";
console.log(numberOfRows);
for (let i = 0; i < numberOfRows; i++) {
var divRow = document.createElement("div");
document.getElementById("container").appendChild(divRow);
for (let y = 0; y < numberOfRows; y++) {
let divCol = document.createElement("div");
divCol.addEventListener("mouseenter", function () {
this.style.backgroundColor = "red";
});
divRow.appendChild(divCol);
}
}
}
</script>
I've ended up using a different tool: container.style.gridTemplateColumns and container.style.gridTemplateRows to affect the number of rows and columns of the container. This allows me not to use the :root function above. See JavaScript Syntax at https://www.w3schools.com/cssref/pr_grid-template-columns.asp
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css">
<title>Etch-a-sketch</title>
</head>
<body>
<h1>Etch-a-sketch</h1>
<button id="start">Start</button>
<div id="container"></div>
</body>
<script>
//randomColor function is taken from http://www.devcurry.com/2010/08/generate-random-colors-using-javascript.html //
function randomRgb(value) {
col = "rgb("
+ randomColor(255) * value + ","
+ randomColor(255) * value + ","
+ randomColor(255) * value + ")";
}
function randomColor(num) {
return Math.floor(Math.random() * num);
}
function resetColorOfBoxes() {
boxes = document.querySelectorAll('div');
boxes.forEach(box => box.style.backgroundColor = "white");
}
function promptEntry() {
let userInput = prompt("How many rows would you like?", "Enter a number");
if (isNaN(userInput)) {
alert("That's not a valid entry. Try again");
promptEntry();
}
else {
createGrid(userInput);
}
}
function createGrid(numberOfRows) {
resetColorOfBoxes()
let gridTemplateColumns = 'repeat('+numberOfRows+', 1fr)'
var container = document.getElementById("container");
container.style.gridTemplateColumns = gridTemplateColumns;
container.style.gridTemplateRows = gridTemplateColumns;
let brightness = [];
let i = 0;
let numberOfBoxes = numberOfRows**2;
/*Create boxes*/
for (i; i < numberOfBoxes ; i++) {
brightness[i+1] = 1;
console.log(brightness);
var div = document.createElement("div");
div.classList.add(i+1);
document.getElementById("container").appendChild(div);
div.addEventListener("mouseenter", function () {
var className = this.className;
brightness[className] = brightness[className] - 0.1;
console.log(brightness[className]);
randomRgb(brightness[className]);
this.style.backgroundColor = col;
});
}
}
let btn = document.getElementById("start")
btn.addEventListener("click", promptEntry)
</script>
</html>
I need to distribute points evenly on a circumference of a circle, and I'm out of my wits. The result is not exactly circular but rather spiraly, especially with larger numbers of points. I've researched it vigorously but still can't figure out where I could make a mistake.
window.onload = function() {
var num = 15;
var angle = (2 * Math.PI)/(num+1); var count = 0;
var demo = document.getElementById("demo");
function Dot() {
this.angle = angle * count;
count++;
this.x = Math.cos(this.angle) * 200;
this.y = Math.sin(this.angle) * 200;
}
Dot.prototype.create = function() {
var dot = document.createElement("div");
dot.style.top = this.y + 100 + "px";
dot.style.left = this.x + 200 + "px";
dot.className = "dot";
demo.appendChild(dot);
}
for (var i = 0; i < num; i++) {
var d = new Dot();
d.create();
}
}
.dot {
height: 20px;
width: 20px;
border-radius: 50%;
background: blue;
position: relative;
text-align: center;
}
<!DOCTYPE html>
<html>
<head>
<title>Metcalfe's Law Demo</title>
<link rel="stylesheet" href="style.css">
<script type="text/javascript" src="code.js"></script>
</head>
<body>
<div id="container">
<div id="demo">
</div>
</div>
</body>
</html>
The main mistake is bloody simple - just change the style position: relative to position: absolute:
window.onload = function() {
var num = 12;
var angle = (2 * Math.PI)/(num); var count = 0;
var demo = document.getElementById("demo");
console.log(angle)
function Dot() {
this.angle = angle * count;
count++;
console.log(this.angle,count)
this.x = Math.cos(this.angle) * 200;
this.y = Math.sin(this.angle) * 200;
}
Dot.prototype.create = function() {
var dot = document.createElement("div");
dot.style.top = this.y + 200 + "px";
dot.style.left = this.x + 200 + "px";
dot.className = "dot";
demo.appendChild(dot);
}
for (var i = 0; i < num; i++) {
var d = new Dot();
d.create();
}
}
.dot {
height: 20px;
width: 20px;
border-radius: 50%;
background: blue;
position: absolute;
text-align: center;
}
<!DOCTYPE html>
<html>
<head>
<title>Metcalfe's Law Demo</title>
<link rel="stylesheet" href="style.css">
<script type="text/javascript" src="code.js"></script>
</head>
<body>
<div id="container">
<div id="demo">
</div>
</div>
</body>
</html>
I'm using a Webview in my android app. I'm placing a 2d canvas over a webgl canvas (webgl commented out here). Now, when I start up the app, half the time it draws the expected path, and half the time it draws nothing. Am I missing something? Could this be a caching problem or something?
<!DOCTYPE html>
<html lang="en">
<head>
<title>Cardboard container</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
margin: 0px;
overflow: hidden;
/*background-color: black;*/
}
#container {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 1;
display: none;
}
#stamp {
position: absolute;
top: 0px;
left: 160px;
width: 38px;
height: 38px;
background-color: red;
z-index: 0;
}
#bezier{
z-index: 2;
}
</style>
</head>
<body>
<div id="container"></div>
<div id="stamp"></div>
<canvas id="bezier">Error creating bezier canvas</canvas>
<script src="js/third-party/threejs/three.js"></script>
<script src="js/third-party/threejs/StereoEffect.js"></script>
<script src="js/webgl.js"></script>
<script src="js/bezier.js"></script>
<script>
var consecutiveAbsentFrames = 6;
var totalFrames = 90;
var frameCount = 0;
var straightLineSpeed = 0.05;
var scaleFactor = 0.9;
var numGridPoints = 196;
var fovRadius = 9;
var fovXoffset = 0.5;
var gridPoints = []; // Points are an array [x0,y0,x1,y1,...]
var gridPoints2d = [];
var completePath = [];
var pathIndex = 0;
init();
function init() {
stamp = document.getElementById('stamp');
init2d();
}
function init2d(){
var b = document.getElementById('bezier');
b.width = window.innerWidth * scaleFactor * 0.5;
b.height = window.innerHeight;
var ctx=b.getContext('2d');
ctx.moveTo(0,0);
ctx.lineTo(100,100);
ctx.stroke();
}
</script>
</body>
</html>
EDIT:
Behavior is normal on a Moto X with Android 5.1, incorrect on Note 5 with 5.1.1
Jsfiddle: http://jsfiddle.net/yJJs7/
Javascript:
function main(){
var centerx=250;
var centery=250;
var degrees=0;
var div=document.getElementById('test');
var move=function(){
if(degrees>360)degrees=degrees%360;
var radians = degrees*Math.PI/180;
var newx = Math.cos(radians)*100;
var newy = Math.sin(radians)*100;
div.style.top=(newy+centery)+'px';
div.style.left=(newx+centerx)+'px';
degrees+=10;
};
setInterval(move,50);
console.log(div);
}
main();
HTML:
<div id="test"></div>
<div id="test2"></div>
CSS:
#test{
height:100px;
width:100px;
background:black;
border-radius:100px;
position:fixed;
}
#test2{
position:fixed;
height:30px;
width:30px;
background:black;
border-radius:30px;
position:fixed;
top:250px;
left:250px;
}
The second div is centered at 250x250 px, and the first div should rotate around it. Why isn't it?
Your equation is calculating the new position for the centre of the circle, but style.top/style.left goes from the top/left-most points on the circle, you need to subtract the radius:
div.style.top=(ny+cy-35)+'px';
div.style.left=(nx+cx-35)+'px';
http://jsfiddle.net/yJJs7/1/
That will be rotating around the centre of the small circle (265, 265) rather than (250, 250) though, so you probably want to offset the small circle in the css:
#test2{
...
top:235px;
left:235px;
}
div.style.top=(ny+cy-50)+'px';
div.style.left=(nx+cx-50)+'px';
http://jsfiddle.net/yJJs7/7/
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<style>
#test {
height:100px;
width:100px;
background:black;
border-radius:100px;
position:fixed;
}
#test2 {
position:fixed;
height:30px;
width:30px;
background:black;
border-radius:30px;
position:fixed;
top:250px;
left:250px;
}
</style>
<script type="text/javascript" src="jquery.js"></script>
<script>
$(document).ready(function (e) {
main(100);
});
function main(distance) {
var $this = $("#test2");
var offset = $this.offset();
var width = $this.width();
var height = $this.height();
var cx = offset.left + width / 2;
var cy = offset.top + height / 2;
var i = 0;
var $div = $('#test');
var divOffset = $div.offset();
var divWidth = $div.width();
var divHeight = $div.height();
var move = function () {
if (i > 360) i = i % 360;
var j = i * Math.PI / 180;
var nx = Math.cos(j) * distance;
var ny = Math.sin(j) * distance;
var left = nx + cx - divWidth / 2
var top = ny + cy - divHeight / 2
$div.offset({
top: top,
left: left
});
i += 10;
};
setInterval(move, 50);
}
</script>
</head>
<body>
<div id="test"></div>
<div id="test2"></div>
</body>