Function with if-else doesn't work properly - javascript

I made a function which should disable a button if a variable isn't greater than or equal to another one. This function is run every second on a setInterval(), and the first variable to compare is also incremented by one on the setInterval(). But, the function (evitarNegs()), isn't working properly, and the button is always disabled. Sorry that part of the code is in spanish.
Javascript:
var GmB = {cantidad: 0, perSec: 1};
function Upgrade (pb, ps) {
this.precioBase = pb;
this.perSec = ps;
this.cantidad = 0;
this.precio = pb;
}
Upgrade.prototype.comprar = function() {
GmB.cantidad = GmB.cantidad - this.precio;
GmB.perSec = GmB.perSec + this.perSec;
this.cantidad++;
document.getElementById("gmb").innerHTML = GmB.cantidad;
this.precio = Math.ceil(this.precioBase*Math.pow(1.15, this.cantidad));
evitarNegs();
};
function loop() {
GmB.cantidad = GmB.cantidad + GmB.perSec;
document.getElementById("gmb").innerHTML = GmB.cantidad;
evitarNegs();
}
var upg = new Upgrade(10, 1);
var boton1 = document.getElementById("boton1");
boton1.disabled = true;
window.setInterval(loop, 1000);
//Problematic function
function evitarNegs() {
if (!(GmB >= upg.precio)) {
boton1.disabled = true;
}else {
boton1.disabled = false;
}
}
boton1.onclick = function() {
upg.comprar();
};
HTML:
<html>
<head>
<title>Gummy Bears</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
</head>
<body>
<p id="gmb">0</p>
<button id="boton1" type="button">Upgrade 1</button>
<script src="main.js"></script>
</body>
</html>

You are comparing GmB to upg.precio, but GmB is an object. So you want
function evitarNegs() {
if (!(GmB.cantidad >= upg.precio)) {
boton1.disabled = true;
} else {
boton1.disabled = false;
}
}
However, this can be written much easier as
function evitarNegs() {
boton1.disabled = GmB.cantidad < upg.precio;
}
Fiddle: http://jsfiddle.net/4rRmp/

It seems that you are comparing an object to an integer in GmB >= upg.precio. You probably have to replace it by GmB.cantidad >= upg.precio.

Related

p5js is adding div each time when click

#Hey-PeePs. The issue is happening in p5js:
I have: 1 function(), 1 draw(), 2 sketches(canvas)
Using: Instance Mode
All I want is a gallery! there is an image in thumbnail size, when click goes full-size, which is the reason I have 2 canvases. The following code is working. It will create a canvas with the thumbnail size of the image and then when I click on it, it will create a DIV which contains the full-screen image.
The issue is, every time I click on the thumbnail, it will create another DIV and it just goes on. How can I set a condition for this? So it will only draw once!
var PictureThumbnail = function(p) {
let ThumbImage;
let fullSize;
p.preload = function() {
ThumbImage = p.loadImage('https://www.paulwheeler.us/files/Coin120.png');
};
p.setup = function() {
var canvas = p.createCanvas(100, 100);
canvas.parent('#Thumbnail');
fullSize = createDiv('Full Size Image');
fullSize.addClass('fullSize');
fullSize.hide();
};
p.draw = function() {
p.image(ThumbImage, 0, 0, 700, 70);
if (mouseIsPressed) {
if ((p.mouseX > 0) && (p.mouseX < 100) && (p.mouseY > 0) && (p.mouseY < 100)) {
fullSize.show();
let sketch2 = function(p) {
p.setup = function() {
p.createCanvas(500, 500);
p.background(255);
}
};
new p5(sketch2, window.document.getElementById('fullSize'));
}
}
};
};
let sketch = new p5(PictureThumbnail);
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
</head>
<body>
<div id="Thumbnail"></div>
</body>
</html>
The last line of code is the issue.
new p5(sketch2, window.document.getElementById('fullSize'));
There are a number of issues:
1. Invalid references:
You have several references to global p5.js methods and properties where you should be referencing the instance methods (createDiv and mouseIsPressed).
2. Action in draw() that should be in mousePressed()
The way you're using mouseIsPressed is flawed. Draw is going to be running repeatedly and mouseIsPressed will be true over several calls so you're going to be repeatedly creating sketch2.
3. Attempt to get an element by id that does not exist
You create a div with the class 'fullSize' and no id and then you attempt to get an element with the id 'fullSize' but no such element exist.
Here's a working example:
var PictureThumbnail = function(p) {
let ThumbImage;
let fullSize;
let fullSizeOpen = false;
p.preload = function() {
ThumbImage = p.loadImage('https://www.paulwheeler.us/files/Coin120.png');
};
p.setup = function() {
var canvas = p.createCanvas(100, 100);
canvas.parent('#Thumbnail');
fullSize = p.createDiv('Full Size Image');
fullSize.addClass('fullSize');
fullSize.id('fullSize');
fullSize.hide();
};
p.mousePressed = function() {
if ((p.mouseX > 0) && (p.mouseX < 100) && (p.mouseY > 0) && (p.mouseY < 100)) {
if (!fullSizeOpen) {
fullSizeOpen = true;
fullSize.show();
let sketch2 = function(p) {
p.setup = function() {
p.createCanvas(500, 500);
p.background('red');
}
};
new p5(sketch2, window.document.getElementById('fullSize'));
}
}
}
p.draw = function() {
p.image(ThumbImage, 0, 0, 700, 70);
};
};
let sketch = new p5(PictureThumbnail);
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
</head>
<body>
<div id="Thumbnail"></div>
</body>
</html>

JavaScript while loop through a video while automatically playing and pausing

How can I efficiently write a JavaScript while loop code to automatically play a one hour video while playing for three seconds and pausing for six seconds to allow me time to transcribe? This is what I have tried but I have not succeeded.
<!DOCTYPE html>
<html>
<head>
<title> Video transcription</title>
</head>
<body>
</body>
<video id = 'myVideo' >
<source src = 'testVideo.mp4'>
</video>
<script>
var pauseTime = 6000 // six seconds
var initialTime = 0
var timeUpdate = 3
var timeIncrement = initialTime + timeUpdate
var wasPausedBefore1 = 0;
var wasPausedBefore2 = 0;
var wasPausedBefore3 = 0;
while (video.duration > 0) {
var video = document.getElementById('myVideo');
video.play();
video.ontimeupdate = function() {
let currentTime =video.currentTime;
if (currentTime > initialTime && currentTime < timeIncrement && wasPausedBefore1 == 0) {
video.pause();
wasPausedBefore1 = 1;
setTimeout(function() {
video.play();
}, pauseTime);
} else if(currentTime > initialTime && currentTime < timeIncrement && wasPausedBefore2 == 0){
video.pause();
wasPausedBefore2 = 1;
setTimeout(function() {
video.play();
}, pauseTime);
}
initialTime += timeUpdate
timeIncrement += timeUpdate
}
}
</script>
</body>
</html>
I did the following to create a control logic of your application:
Created a Petri Net diagram of the control logic. I used Notepad to create the diagram as PDF form XObject.
Created an interactive prototype of the control logic as a PDF form application.
Created the control logic of the application based on the prototype. I used the setTimeout API instead of a loop structure.
For me this is an effective way to create the control logic of many applications because creating the interactive prototype based on a Petri Net diagram is a systematic activity.
The interactive prototype plus details on its construction and additional sample source codes are available in a dynamic and interactive PDF at https://www.academia.edu/43005182/How_to_Automatically_Play-and-Pause_a_Video_A_Reply_to_a_Request_at_Stack_Overflow.
The following HTML code is an example of how to use the control logic.
<!DOCTYPE html>
<head>
<title>Play-and-Pause Example</title>
</head>
<body>
<video id = 'video0'>
<source src = '1956Pepto_512kb.mp4'>
</video>
<script>
/* Copyright 2020 John Frederick Chionglo */
var tObject;
var vTime = 64000;
var vID = document.getElementById('video0');
function PlayAndPause(parms) {
this.videoID = parms.videoID;
this.videoTime = parms.videoTime;
this.tObject = undefined;
}
PlayAndPause.objs = [];
PlayAndPause.play = function(id) {
PlayAndPause.objs[id].playSegment(id);
};
PlayAndPause.pause = function(id) {
PlayAndPause.objs[id].pauseSegment(id);
};
with (PlayAndPause) {
prototype.window = this;
prototype.playTime = 3000;
prototype.pauseTime = 6000;
prototype.playSegment = function(id) {
this.videoID.play();
this.videoTime -= this.playTime;
this.tObject = setTimeout("PlayAndPause.pause("+ id + ")", this.playTime);
};
prototype.pauseSegment = function(id) {
if (this.videoTime<0) {}
else {
this.videoID.pause();
this.tObject = setTimeout("PlayAndPause.play(" + id + ")", this.pauseTime);
}
};
}
var ppobj = new PlayAndPause({videoID: vID, videoTime: vTime});
PlayAndPause.objs[0] = ppobj;
ppobj.playSegment(0);
</script>
</body>
</html>

Returning Set of Styles

<!DOCTYPE html>
<html>
<head>
<title></title>
<link rel="stylesheet" type="text/css" href="practise.css"/>
<script type="text/javascript" src="practise.js"></script>
</head>
<body>
<div id="items"><p id="help">Hello World</p></div>
<script>
var para=document.getElementById('help');
var check=true;
//want to return these styles whenever mouse is clicked
function toggle(){
if(check){
para.style.color="#EEFFCC";
para.style.textAlign="center";
para.style.fontSize="1em";
}else{
para.style.color="#223311";
para.style.textAlign="center";
para.style.fontSize="4em";
}
check=!check;
}
para.onclick=toggle();
</script>
</body>
</html>
The code i want to make is that it toggles between two sets of Styles whenever mouse is licked on 'para' element. But i couldn't figure out how to return the styles to the 'para.onclick' call below the function.
Currently you are doing:
para.onclick = toggle();
which means that para.onclick will be the result of executing toggle().
What you want to do is assign toggle to para.onclick:
para.onclick = toggle;
The difference is this:
function result() {
return 2;
}
var res = result();
// res = 2
var fnRes = result;
// fnRes = function() { return 2; }
Just create a little function when you click the onClick it calls your toggle, like so para.onclick = function() {}.
var para = document.getElementById('help');
var check = true;
function toggle() {
if (check) {
para.style.color = "blue";
para.style.textAlign = "center";
para.style.fontSize = "1em";
} else {
para.style.color = "red";
para.style.textAlign = "center";
para.style.fontSize = "4em";
}
check = !check;
}
para.onclick = function() {
toggle()
};
<div id="items">
<p id="help">Hello World</p>
</div>

Strange behaviour of included JS file in node.js

I am making a node app that is in it current state very simple, but I get an issue I can't figure out.
The generated html of my express app looks like this:
<html style="" class=" js no-touch svg inlinesvg svgclippaths no-ie8compat">
<head>
...
<script type="text/javascript" src="/javascripts/mouse.js"></script>
...
</head>
<body class="antialiased" style=""><div class="row"><div class="row">
<script>
var mouse;
var X = 0;
var Y = 0;
window.onload = function()
{
alert(Mouse());//=> undefined
mouse = Mouse();
mouse.setMouseMoveCallback(function(e){ //THIS LINE FAILS: "Cannot call method 'setMouseMoveCallback' of undefined"
X = e.x;
Y = e.y;
alert("move");
});
}
...
</html>
The include script tag in the header adds this javascript file:
function Mouse(onObject){
var mouseDown = [0, 0, 0, 0, 0, 0, 0, 0, 0],
mouseDownCount = 0;
var mouseDownCallbacks = [0, 0, 0, 0, 0, 0, 0, 0, 0];
var mouseTracer = 0;
var tracePosArray;
var target = onObject;
if(!onObject){
onObject = document;
}
onObject.onmousedown = function(evt) {
mouseDown[evt.button] = 1;
mouseDownCount--;
if(mouseDownCallbacks[evt.button] != 0){
mouseDownCallbacks[evt.button](evt);
}
}
onObject.onmouseup = function(evt) {
mouseDown[evt.button] = 0;
mouseDownCount--;
}
var mousemoveCallback;
onObject.onmousemove = function(evt){
//Tracing mouse here:
if(mouseTracer){
tracePosArray.push([evt.pageX,evt.pageY]);
}
if(mousemoveCallback){
mousemoveCallback(evt);
}
}
var mouseWheelCallback;
onObject.onmousewheel = function(evt){
if(mouseWheelCallback){
mouseWheelCallback(evt);
}
}
var mouseOverCallback;
onObject.onmouseover = function(evt){
if(mouseOverCallback){
mouseOverCallback(evt);
}
}
var mouseOutCallback;
onObject.onmouseout = function(evt){
if(mouseOutCallback){
mouseOutCallback(evt);
}
}
//TODO: There is a bug when you move the mouse out while you are pressing a button. The key is still counted as "pressed" even though you release it outside of the intended area
//NOTE: might have fixed the bug. Do some further investigation by making a smaller element.
this.anyDown = function(){
if(mouseDownCount){
for(p in mouseDown){
if(mouseDown[p]){
return true;
}
}
}
}
this.setLeftDownCallbackFunction = function(fun){
mouseDownCallbacks[0] = fun;
}
this.setRightDownCallbackFunction = function(fun){
mouseDownCallbacks[2] = fun;
}
this.setMiddleDownCallbackFunction = function(fun){
mouseDownCallbacks[4] = fun;
}
this.setSpcifiedDownCallbackFunction = function(num, fun){
mouseDownCallbacks[num] = fun;
}
this.leftDown = function(){
if(mouseDownCount){
return mouseDown[0] != 0;
}
}
this.rightDown = function(){
if(mouseDownCount){
return mouseDown[2] != 0;
}
}
this.middleDown = function(){
if(mouseDownCount){
return mouseDown[4] != 0;
}
}
this.setMouseMoveCallback = function (callback){
mousemoveCallback = callback;
}
this.setMouseWheelCallback = function (callback){
mouseWheelCallback = callback;
}
this.setMouseOverCallback = function (callback){
mouseOverCallback = callback;
}
this.setMouseOutCallback = function (callback){
mouseOutCallback = callback;
}
this.enableTracer = function(){
tracePosArray = new Array();
mouseTracer = 1;
}
this.getMouseTracerData = function() {
return tracePosArray;
}
}
So: I have assured that the JS file is loaded. But none the less I am not able to access the Mouse() method in my window.onload function in the body, it shows up as undefined. This is very strange to me because if I create a HTML file that does exactly the same thing I am able to access it.
What is going on here? Is there some magic trickery in node.js / express that disables this kind of interaction?
Additional notes:
I am using Jade as the template engine.
The "mouse.js" file works. I have used it several times before.
I am using socket.io for communication between the client and server.
Complete header:
<head><title>My awesome title</title><link rel="stylesheet" href="/stylesheets/foundation.min.css"><link rel="stylesheet" href="/stylesheets/normalize.css"><link rel="stylesheet" href="/stylesheets/style.css"><script type="text/javascript" src="/socket.io/socket.io.js"></script><style type="text/css"></style><script type="text/javascript" src="/javascripts/jquery.min.js"></script><script type="text/javascript" src="/javascripts/vendor/custom.modernizr.js"></script><script type="text/javascript" src="/javascripts/vendor/zepto.js"></script><script type="text/javascript" src="/javascripts/mouse.js"></script><meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport"><meta name="viewport" content="width=device-width"></head>
That would throw an error if the Mouse function is undefined. The reason alert shows 'undefined' is that the Mouse function doesn't return anything, hence undefined. It should be used as a constructor, as in 'new Mouse()'

Not Looping? HTML5 and JavaScript

I have no idea why this code does not loop as it should. My mind is blown and hopefully someone can give me a hand. This is my first attempt into the HTML5 and JavaScript world and my first StackOverflow post. My background is in java so that should explain the quirks in my code. By the way, if you run the code the canvas and balls will show up, just not move.
First off, here is the HTML5
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>ChainReaction5</title>
<script type="text/javascript" src="chain_reaction.js"></script>
</head>
<body>
<body onLoad="init();">
<canvas id="myCanvas" width="500" height="400">
Your browser dosen't support the HTML5 canvas.</canvas><br />
</body>
</html>
Secondly here is the js
//gobal vars
var context;
var box;
var balls;
var defaultBallX=240;
var defaultBallY=190;
var defaultBallRad=6;
var defaultBallV=5;
var defaultNumBalls=10;
//box class
function Box() {
var boxx=20;
var boxy=20;
var boxWidth=460;
var boxHeight=360;
this.getX = function() {return boxx;}
this.getY = function() {return boxy;}
this.getWidth = function() {return boxWidth;}
this.getHeight = function() {return boxHeight;}
this.getBalls = function() {return ball;}
this.paintMe = function() {
context.fillStyle = "black";
context.strokeRect(boxx, boxy, boxWidth, boxHeight);
}
}
/* Box Class
* this class is sloppy but more memory efficent
*/
function Ball(x, y, radius, vx, vy, color) {
this.x=x;
this.y=y;
this.radius=radius;
this.vx=vx;
this.vy=vy;
this.color=color;
this.paintMe = function() {
context.beginPath();
context.arc(this.x, this.y, radius, 0, 2*Math.PI, true);
context.fillStyle = this.color;
context.fill();
}
}
Array.prototype.appendBalls = new function(array) {}
Array.prototype.clearBalls = new function() {}
Array.prototype.appendBalls = function(array) {
for (var i = 0; i < array.length; i++) {
balls.push(array[i]);
}
}
Array.prototype.clearBalls = function() {
balls = new Array();
}
// begin program
function init() {
context = document.getElementById("myCanvas").getContext("2d");
box = new Box();
balls = new Array();
balls.appendBalls(createBalls(box, defaultNumBalls));
setInterval(moveBall(balls, box), 100);
}
function createBalls(box, numBalls) {
var locBalls = new Array(numBalls);
for (var i = 0; i < numBalls; i++) {
var randx = randp(50, 400)
var randy = randp(50, 300);
var randr = Math.random()*defaultBallRad+1;
var randvx = randv();
var randvy = randv();
var randc = randColor();
locBalls[i] = new Ball(randx, randy, randr, randvx, randvy, randc);
}
return locBalls;
function randv() {
var neg = 1;
if (Math.random()>.5) neg = -neg;
return Math.random()*defaultBallV*neg;
}
function randp(low, hight) {
if (low < 0) low = 0;
var p = -1;
while (p > hight || p < low) {
p = Math.random()*hight;
}
return p;
}
function randColor() {
var letters = '0123456789ABCDEF'.split('');
var color = '#';
for (var i = 0; i < 6; i++ ) {
color += letters[Math.round(Math.random() * 15)];
}
return color;
}
}
function moveBall(balls, box) {
clear(this.box);
this.box.paintMe();
for (var i = 0; i < this.balls.length; i++) {
moveAndCheck(this.balls[i], this.box);
}
}
function moveAndCheck(b, box) {
if ((b.x+b.vx+b.radius-1)>(this.box.boxWidth+this.box.boxx) || b.x+b.vx-b.radius<this.box.boxx+1) {
b.vx = -b.vx;
}
if ((b.y+b.vy+b.radius-1)>(this.box.boxHeight+this.box.boxy) || b.y+b.vy-b.radius<this.box.boxy+1) {
b.vy = -b.vy;
}
b.x += b.vx;
b.y += b.vy;
b.paintMe();
}
function clear(box) {
context.clearRect(this.box.boxx, this.box.boxy,
this.box.boxWidth, this.box.boxHeight);
}
The first time I tried running it I got the following in the Firebug console:
useless setInterval call (missing quotes around argument?)
[Break On This Error] setInterval(moveBall(balls, box), 100);
Putting quotes around 'moveBalls(balls, box)' animates things.
Incidentally, you can use prototype inhertiance to make your function a bit more efficient, the methods in Box are given to each instance. To have them inherit the methods, put them on the constructor's prototype:
Box.prototype = {
getX: function() {return this.boxx;},
getY: function() {return this.boxy;},
getWidth: function() {return this.boxWidth;},
getHeight: function() {return this.boxHeight;},
getBalls: function() {return this.ball;},
paintMe: function() {
context.fillStyle = "black";
context.strokeRect(this.boxx, this.boxy, this.boxWidth, this.boxHeight);
}
};
Note that in javascript, a function's this keyword is set by the call, it is not set by how you declare the function (though you can use ES5 bind, but that is not widely supported yet).
Some other hints:
In the Box constructor you are making local variables but you really want to assign them to the new Box instance, so use this instead of var:
function Box() {
this.boxx=20;
this.boxy=20;
this.boxWidth=460;
this.boxHeight=360;
}
In the clearBox function, you are using this when it is not set in the call, so it references window. Just get rid of it, you pass box to the function so reference it directly:
function clear(box) {
context.clearRect(box.boxx, box.boxy,
box.boxWidth, box.boxHeight);
}
Same applies to the moveBall and moveAndCheck functions, just get rid of this (I think you should do some research on how this is handled in javascript, there are many articles on it, it's quite different to Java).
Now the balls will bounce around nicely inside the box.
I want to thank the people who contributed to my question and it has been helpful in resolving the issue and the answer I selected was current in a way, but it fixed the problem for a different reason.
Incorrect:
Putting quotes around 'moveBalls(balls, box)' animates things.
What actually fixes the problem is removing the arguments and parentheses from the call to the moveball function. I discovered this when rewriting other parts of my code as the poster suggested.
So for future notice to other people with a similar problem if you need to remove the arguments and use a wrapper function or global variables.

Categories

Resources