Re-Spin Wheel after Complete Stop - javascript

How can I re-spin the wheel below, after it comes to a stop. Having one of those days where I just can't figure it out.
I created a resetWheel function that resets the wheel once it comes to a complete stop. I tried inserting it once the wheel is locked and stopped, but it refuses to work with me. Thank you in advance for the feedback and help. Feel free to add to my existing code, since I'm still fairly new, any advice is good !
function rand(min, max) {
return Math.random() * (max - min) + min;
}
var color = ['#6897bb', '#6dc066', '#f67f5c', '#cc5466', '#e6e6fa', '#fbc', '#f88', "#fbc", "#f67"];
var label = ['5', '3', '2', '1', '15', '6', '10', '0', "20", '0'];
var slices = color.length;
var sliceDeg = 360 / slices;
var deg = rand(0, 360);
var speed = 0;
var slowDownRand = 0;
var ctx = canvas.getContext('2d');
var width = canvas.width; // size
var center = width / 2; // center
var isStopped = false;
var lock = false;
var logged = false;
let totalScore = 0;
function deg2rad(deg) {
return deg * Math.PI / 180;
}
function drawSlice(deg, color) {
ctx.beginPath();
ctx.fillStyle = color;
ctx.moveTo(center, center);
ctx.arc(center, center, width / 2, deg2rad(deg), deg2rad(deg + sliceDeg));
ctx.lineTo(center, center);
ctx.fill();
}
function drawText(deg, text) {
ctx.save();
ctx.translate(center, center);
ctx.rotate(deg2rad(deg));
ctx.textAlign = "right";
ctx.fillStyle = "#fff";
ctx.font = 'bold 30px sans-serif';
ctx.fillText(text, 130, 10);
ctx.restore();
}
function drawImg() {
ctx.clearRect(0, 0, width, width);
for (var i = 0; i < slices; i++) {
drawSlice(deg, color[i]);
drawText(deg + sliceDeg / 2, label[i]);
deg += sliceDeg;
}
}
drawImg();
function resetWheel() {
(anim());
}
startSpin.addEventListener("click", function anim() {
deg += speed;
deg %= 360;
// Increment speed
if (!isStopped && speed < 3) {
speed = speed + 1 * 0.1;
}
// Decrement Speed
if (isStopped) {
if (!lock) {
lock = true;
slowDownRand = rand(0.959, 0.998);
}
speed = speed > 0.2 ? speed *= slowDownRand : 0;
}
if (lock && !speed) {
var ai = Math.floor(((360 - deg - 90) % 360) / sliceDeg); // deg 2 Array Index
ai = (slices + ai) % slices; // Fix negative index
let score = label[ai];
if (!logged) {
console.log(score);
totalScore = totalScore + score;
console.log(totalScore)
logged = true;
}
}
drawImg();
window.requestAnimationFrame(anim);
});
document.getElementById("stopSpin").addEventListener("mousedown", function() {
isStopped = true;
//setTimeout(loadPhrase, 2000); //waits for wheel to stop, then starts function
}, false);
#wheel {
display: block;
text-align: center;
overflow: hidden;
}
#wheel:after {
content: "";
background: red;
border: 2px solid white;
position: absolute;
top: -7px;
left: 50%;
width: 10px;
height: 10px;
margin-left: -7px;
transform: rotate(45deg)
}
<div id="gameScreen">
<div id="wheel">
<canvas id="canvas" width="300" height="300"></canvas>
</div>
<br>
<button id="startSpin">Spin!</button>
<button id="stopSpin">Stop!</button>
<div id="gameWrapper">
<h1 id="game_header">Guess The Correct Letters</h1>
<div id="display">
</div>
</div>
</div>

Having one of those days where I just can't figure it out.
Oof that hit me on a personal level
Anyway, you're not setting isStopped back to false so your wheel won't spin also your anim() function isn't accessible anywhere else in your code so your reset function can't see it.
JS
function rand(min, max) {
return Math.random() * (max - min) + min;
}
var color = ['#6897bb', '#6dc066', '#f67f5c', '#cc5466', '#e6e6fa', '#fbc', '#f88', "#fbc", "#f67"];
var label = ['5', '3', '2', '1', '15', '6', '10', '0', "20", '0'];
var slices = color.length;
var sliceDeg = 360 / slices;
var deg = rand(0, 360);
var speed = 0;
var slowDownRand = 0;
var ctx = canvas.getContext('2d');
var width = canvas.width; // size
var center = width / 2; // center
var isStopped = false;
var lock = false;
var logged = false;
let totalScore = 0;
function deg2rad(deg) {
return deg * Math.PI / 180;
}
function drawSlice(deg, color) {
ctx.beginPath();
ctx.fillStyle = color;
ctx.moveTo(center, center);
ctx.arc(center, center, width / 2, deg2rad(deg), deg2rad(deg + sliceDeg));
ctx.lineTo(center, center);
ctx.fill();
}
function drawText(deg, text) {
ctx.save();
ctx.translate(center, center);
ctx.rotate(deg2rad(deg));
ctx.textAlign = "right";
ctx.fillStyle = "#fff";
ctx.font = 'bold 30px sans-serif';
ctx.fillText(text, 130, 10);
ctx.restore();
}
function drawImg() {
ctx.clearRect(0, 0, width, width);
for (var i = 0; i < slices; i++) {
drawSlice(deg, color[i]);
drawText(deg + sliceDeg / 2, label[i]);
deg += sliceDeg;
}
}
function anim() {
deg += speed;
deg %= 360;
// Increment speed
if (!isStopped && speed < 3) {
speed = speed + 1 * 0.1;
}
// Decrement Speed
if (isStopped) {
if (!lock) {
lock = true;
slowDownRand = rand(0.959, 0.998);
}
speed = speed > 0.2 ? speed *= slowDownRand : 0;
}
if (lock && !speed) {
var ai = Math.floor(((360 - deg - 90) % 360) / sliceDeg); // deg 2 Array Index
ai = (slices + ai) % slices; // Fix negative index
let score = label[ai];
if (!logged) {
console.log(score);
totalScore = totalScore + score;
console.log(totalScore)
logged = true;
}
}
drawImg();
window.requestAnimationFrame(anim);
}
drawImg();
function resetWheel() {
if(isStopped){
isStopped = false;
anim();
}
}
startSpin.addEventListener("click", anim);
document.getElementById("stopSpin").addEventListener("mousedown", function() {
isStopped = true;
//setTimeout(loadPhrase, 2000); //waits for wheel to stop, then starts function
}, false)
document.getElementById("restartSpin").addEventListener("click",resetWheel);
HTML (I've added a restart button)
<div id="gameScreen">
<div id="wheel">
<canvas id="canvas" width="300" height="300"></canvas>
</div>
<br>
<button id="startSpin">Spin!</button>
<button id="stopSpin">Stop!</button>
<button id="restartSpin">Restart</button>
<div id="gameWrapper">
<h1 id="game_header">Guess The Correct Letters</h1>
<div id="display">
</div>
</div>
</div>

Related

Remove objects in the canvas in certain coordinates

I would like to remove the balls already generated in the canvas on the click and decrease the counter on the bottom, but my function does not work. Here is my code concerning the part of the ball removal.
Is it possible to use a div to get the same result and to facilitate the removal of the balls? thank you
ball.onclick = function removeBalls(event) {
var x = event.clientX;
var y = event.clientY;
ctx.clearRect(x, y, 100, 50);
ctx.fillStyle = "#000000";
ctx.font = "20px Arial";
ctx.fillText("Balls Counter: " + balls.length - 1, 10, canvas.height - 10);
}
below I enclose my complete code
// GLOBAL VARIBLES
var gravity = 4;
var forceFactor = 0.3; //0.3 0.5
var mouseDown = false;
var balls = []; //hold all the balls
var mousePos = []; //hold the positions of the mouse
var ctx = canvas.getContext('2d');
var heightBrw = canvas.height = window.innerHeight;
var widthBrw = canvas.width = window.innerWidth;
var bounciness = 1; //0.9
window.onload = function gameCore() {
function onMouseDown(event) {
mouseDown = true;
mousePos["downX"] = event.pageX;
mousePos["downY"] = event.pageY;
}
canvas.onclick = function onMouseUp(event) {
mouseDown = false;
balls.push(new ball(mousePos["downX"], mousePos["downY"], (event.pageX - mousePos["downX"]) * forceFactor,
(event.pageY - mousePos["downY"]) * forceFactor, 5 + (Math.random() * 10), bounciness, random_color()));
ball
}
function onMouseMove(event) {
mousePos['currentX'] = event.pageX;
mousePos['currentY'] = event.pageY;
}
function resizeWindow(event) {
canvas.height = window.innerHeight;
canvas.width = window.innerWidth;
}
function reduceBounciness(event) {
if (bounciness == 1) {
for (var i = 0; i < balls.length; i++) {
balls[i].b = bounciness = 0.9;
document.getElementById("btn-bounciness").value = "⤽ Bounciness";
}
} else {
for (var i = 0; i < balls.length; i++) {
balls[i].b = bounciness = 1;
document.getElementById("btn-bounciness").value = " ⤼ Bounciness";
}
}
return bounciness;
}
function reduceSpeed(event) {
for (var i = 0; i < balls.length; i++) {
balls[i].vx = velocityX = 20 + c;
balls[i].vy = velocityY = 20 + c;
}
}
function speedUp(event) {
for (var i = 0; i < balls.length; i++) {
balls[i].vx = velocityX = 120 + c;
balls[i].vy = velocityY = 120 + c;
}
}
function stopGravity(event) {
if (gravity == 4) {
for (var i = 0; i < balls.length; i++) {
balls[i].g = gravity = 0;
balls[i].vx = velocityX = 0;
balls[i].vy = velocityY = 0;
document.getElementById("btn-gravity").value = "►";
}
} else {
for (var i = 0; i < balls.length; i++) {
balls[i].g = gravity = 4;
balls[i].vx = velocityX = 100;
balls[i].vy = velocityY = 100;
document.getElementById("btn-gravity").value = "◾";
}
}
}
ball.onclick = function removeBalls(event) {
var x = event.clientX;
var y = event.clientY;
ctx.clearRect(x, y, 100, 50);
ctx.fillStyle = "#000000";
ctx.font = "20px Arial";
ctx.fillText("Balls Counter: " + balls.length - 1, 10, canvas.height - 10);
}
document.getElementById("btn-gravity").addEventListener("click", stopGravity);
document.getElementById("btn-speed-up").addEventListener("click", speedUp);
document.getElementById("btn-speed-down").addEventListener("click", reduceSpeed);
document.getElementById("btn-bounciness").addEventListener("click", reduceBounciness);
document.addEventListener("mousedown", onMouseDown);
document.addEventListener("mousemove", onMouseMove);
window.addEventListener('resize', resizeWindow);
}
// GRAPHICS CODE
function circle(x, y, r, c) { // x position, y position, r radius, c color
//draw a circle
ctx.beginPath(); //approfondire
ctx.arc(x, y, r, 0, Math.PI * 2, true);
ctx.closePath();
//fill
ctx.fillStyle = c;
ctx.fill();
//stroke
ctx.lineWidth = r * 0.1; //border of the ball radius * 0.1
ctx.strokeStyle = "#000000"; //color of the border
ctx.stroke();
}
function random_color() {
var letter = "0123456789ABCDEF".split(""); //exadecimal value for the colors
var color = "#"; //all the exadecimal colors starts with #
for (var i = 0; i < 6; i++) {
color = color + letter[Math.round(Math.random() * 15)];
}
return color;
}
function selectDirection(fromx, fromy, tox, toy) {
ctx.beginPath();
ctx.moveTo(fromx, fromy);
ctx.lineTo(tox, toy);
ctx.moveTo(tox, toy);
}
//per velocità invariata rimuovere bounciness
function draw_ball() {
this.vy = this.vy + gravity * 0.1; // v = a * t
this.x = this.x + this.vx * 0.1; // s = v * t
this.y = this.y + this.vy * 0.1;
if (this.x + this.r > canvas.width) {
this.x = canvas.width - this.r;
this.vx = this.vx * -1 * this.b;
}
if (this.x - this.r < 0) {
this.x = this.r;
this.vx = this.vx * -1 * this.b;
}
if (this.y + this.r > canvas.height) {
this.y = canvas.height - this.r;
this.vy = this.vy * -1 * this.b;
}
if (this.y - this.r < 0) {
this.y = this.r;
this.vy = this.vy * 1 * this.b;
}
circle(this.x, this.y, this.r, this.c);
}
// OBJECTS
function ball(positionX, positionY, velosityX, velosityY, radius, bounciness, color, gravity) {
this.x = positionX;
this.y = positionY;
this.vx = velosityX;
this.vy = velosityY;
this.r = radius;
this.b = bounciness;
this.c = color;
this.g = gravity;
this.draw = draw_ball;
}
// GAME LOOP
function game_loop() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
if (mouseDown == true) {
selectDirection(mousePos['downX'], mousePos['downY'], mousePos['currentX'], mousePos['currentY']);
}
for (var i = 0; i < balls.length; i++) {
balls[i].draw();
}
ctx.fillStyle = "#000000";
ctx.font = "20px Arial";
ctx.fillText("Balls Counter: " + balls.length, 10, canvas.height - 10);
}
setInterval(game_loop, 10);
* {
margin: 0px; padding: 0px;
}
html, body {
width: 100%; height: 100%;
}
#canvas {
display: block;
height: 95%;
border: 2px solid black;
width: 98%;
margin-left: 1%;
}
#btn-speed-up, #btn-speed-down, #btn-bounciness, #btn-gravity{
padding: 0.4%;
background-color: beige;
text-align: center;
font-size: 20px;
font-weight: 700;
float: right;
margin-right: 1%;
margin-top:0.5%;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Power Balls</title>
<link rel="stylesheet" type="text/css" href="css/style.css">
</head>
<body>
<canvas id="canvas"></canvas>
<input type="button" value="⤼ Bounciness" id="btn-bounciness"></input>
<input type="button" onclick="c+=10" value="+ Speed" id="btn-speed-up"></input>
<input type="button" value="◾" id="btn-gravity"></input>
<input type="button" onclick="c+= -10" value=" - Speed" id="btn-speed-down"></input>
<script src="js/main.js"></script>
</body>
</html>
I see two problems:
ball.onclick will not get triggered, as ball it is not a DOM object. Instead, you need to work with canvas.onclick. Check whether the user clicked on a ball or on empty space to decide whether to delete or create a ball.
To delete the ball, ctx.clearRect is not sufficient. This will clear the ball from the currently drawn frame, but the object still remains in the array balls and will therefore be drawn again in the next frame via balls[i].draw();. Instead, you need to remove the clicked ball entirely from the array, e. g. by using splice.
Otherwise, nice demo! :)
This cannot be done because the canvas is an immediate mode API. All you can do is draw over the top but this is not reliable.
https://en.wikipedia.org/wiki/Immediate_mode_(computer_graphics)
You will have to store each item in a separate data structure, then re-draw whenever a change occurs. In your case there is an array of balls, so you should remove the one that was clicked, before redrawing the entire array.
Each time you remove something, clear the canvas then re-draw each ball.
There are optimisations you can make if this is too slow.

Resize text to fit slice in drawn circle HTML canvas

So I am creating a Wheel of Fortune in an HTML canvas. Because of how many results I have in my query, I will create a slice for each result so they together add up to 360 degrees.
With a few results, I have managed to center the text, however when more results are returned (such as 20-25) each slice is not given more than 14.4 degrees in the circle. The text then starts to overlap each other.
I am looking for help on how to have the font-size of the text as big as possible, but at the same time make sure that it is within its slice border.
function rand(min, max) {
return Math.random() * (max - min) + min;
}
var color = [];
var words = ["Restaurant", "Shop", "Coffe Shop", "Store"];
var label = [];
var nWordsToBeAdded = 40; //Modify this to add or remove n slices to the circle
for(var i = 0; i < nWordsToBeAdded; i++){
label.push(words[Math.floor(Math.random() * words.length)]);
if(i % 2 == 0){
color.push("black");
}else{
color.push("red");
}
}
var slices = color.length;
var sliceDeg = 360/slices;
var deg = rand(0, 360);
var speed = 0;
var slowDownRand = 0;
var ctx = canvas.getContext('2d');
var width = canvas.width; // size
var center = width/2; // center
var isStopped = false;
var lock = false;
function deg2rad(deg) {
return deg * Math.PI/180;
}
function drawSlice(deg, color) {
ctx.beginPath();
ctx.fillStyle = color;
ctx.moveTo(center, center);
ctx.arc(center, center, width/2, deg2rad(deg), deg2rad(deg+sliceDeg));
ctx.lineTo(center, center);
ctx.fill();
}
function drawText(deg, text) {
ctx.save();
ctx.translate(center, center);
ctx.rotate(deg2rad(deg));
ctx.textAlign = "center";
ctx.fillStyle = "#fff";
ctx.font = 'bold 30px sans-serif';
ctx.fillText(text, 130, 10);
ctx.restore();
}
function drawImg() {
ctx.clearRect(0, 0, width, width);
for(var i=0; i<slices; i++){
drawSlice(deg, color[i]);
drawText(deg+sliceDeg/2, label[i]);
deg += sliceDeg;
}
}
(function anim() {
deg += speed;
deg %= 360;
// Increment speed
if(!isStopped && speed<3){
speed = speed+1 * 0.1;
}
// Decrement Speed
if(isStopped){
if(!lock){
lock = true;
slowDownRand = rand(0.994, 0.998);
}
speed = speed>0.2 ? speed*=slowDownRand : 0;
}
// Stopped!
if(lock && !speed){
var ai = Math.floor(((360 - deg - 90) % 360) / sliceDeg); // deg 2 Array Index
ai = (slices+ai)%slices; // Fix negative index
return alert("You got:\n"+ label[ai] ); // Get Array Item from end Degree
}
drawImg();
window.requestAnimationFrame( anim );
}());
document.getElementById("spin").addEventListener("mousedown", function(){
isStopped = true;
}, false);
body{text-align:center;}
#wheel{
display:inline-block;
position:relative;
overflow:hidden;
}
#wheel:after{
content:"";
background:red;
border:2px solid white;
position:absolute;
top:-7px;
left:50%;
width:10px;
height:10px;
margin-left:-7px;
transform: rotate(45deg)
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>jPOT by Roko CB</title>
</head>
<body>
<div id="wheel">
<canvas id="canvas" width="450" height="450"></canvas>
</div>
<br>
<button id="spin">Stop!</button>
</body>
</html>

How can i add a Start button to this function?

I'm trying to figure out how I can add a start button to play a javascript game by replacing the audio in the background. I came across this game, the way it works is as soon as you load the page the music plays in the background and the games already started. When I removed the audio link, the game paused after the players 3 lives are up, if I leave the audio in, then when the 3 lives are up you can see your points and a pop up message, can someone please help me understand this
here is a link to the game so you can look at the code and understand what I'm trying to say : https://jsfiddle.net/74nbrdak/embedded/result/
<div>
<canvas id="canvas" width="1000" height="500"></canvas>
</div>
<audio id="background-music" preload="auto" autoplay loop>
<source
src="https://dl.dropbox.com/s/5r3iu7kjsl0mx81/Wildfire%20Cut%20Loopable.wav" type="audio/wav">
function ShowGamesFinished() {
var message = gamesfinished[Math.floor(Math.random() * gamesfinished.length)];
document.getElementById("background-music").pause();
When I removed the audio link, the game paused after the players 3 lives are up, if I leave the audio in, then when the 3 lives are up you can see your points and a pop up message, can someone please help me understand this
So, In the second scenario when the audio element is on the page, the game works just as the creator intended.
In the first scenario when the audio element isn't on the page, the game works fine until the function that handles the game over is called. What causes the problem in that function is this line document.getElementById("background-music").pause();. Since the audio element doesn't exist, it throws an error and the game over screen isn't drawn. Hope that this helps
If you are using pure javascript Without any external libraries, you can initialize your canvas and on a click of the button you can start animating the canvas and your game starts.
let me know If you don't get my answer.
At first glance, removing the audio tag should not have any effect at all on the javascript. The audio plays upon openeing the page because the audio tag has the autoplay attribute.
All of the javascript code seems to be just within a script tag, so it will also autorun once the page gets opened. What you could try is wrapping the entire code from the fiddle into a function and just bind it to your button.
Something like:
<!DOCTYPE html>
<html lang="en">
<head>
<style>
h1 {
font-family: Architects Daughter;
text-align: center;
font-size: 48pt;
margin-top: 50px;
margin-bottom: 0px;
}
h2 {
font-family: Architects Daughter;
text-align: center;
font-size: 28pt;
margin-top: 0px;
margin-bottom: 50px;
}
span {
display: block;
font-family: Arial;
text-align: center;
margin-bottom: 2px;
}
div {
display: flex;
justify-content: space-around;
}
canvas {
border: 2px solid #CC3333;
}
</style>
</head>
<body>
<div>
<canvas id="canvas" width="640" height="360"></canvas>
</div>
<button id="start_game">Start</button>
<script>
var run_game = function() {
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var WIDTH = canvas.width;
var HEIGHT = canvas.height;
var updateTime = 20; // Milliseconds
var keys = [false, false, false];
var score = 0;
var kills = 0;
// Player Size = 50x18
var playerHealth = 3;
var playerX = WIDTH / 2;
var playerY = HEIGHT - 20;
var playerSpeed = 6;
var lazerSpeed = 16;
var lazerReloadDistance = playerY - 120;
var lazerLoaded = true;
var lazers = [];
var letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var maxEnemies = 12;
var enemySpeed = 4;
var enemies = [];
function Clear() {
ctx.fillStyle = "#404040";
ctx.fillRect(0, 0, WIDTH, HEIGHT);
}
function DrawHealth(health) {
ctx.fillStyle = "#E52B50";
ctx.shadowColor = "#E52B50";
ctx.shadowBlur = 15;
ctx.font = "18px Arial";
ctx.textAlign = "start";
var hearts = "";
if (health == 3) {
hearts = "<3 <3 <3";
}
else if (health == 2) {
hearts = "<3 <3 X";
}
else if (health == 1) {
hearts = "<3 X X";
}
else {
hearts = "X X X";
}
ctx.fillText(hearts, 10, 25);
}
function DrawScore() {
ctx.fillStyle = "#FFFF00";
ctx.shadowColor = "#FFFF00";
ctx.shadowBlur = 15;
ctx.font = "18px Arial";
ctx.textAlign = "end";
ctx.fillText(score, WIDTH - 10, 25);
}
function DrawPlayer(x, y) {
ctx.fillStyle = "#1E90FF";
ctx.shadowColor = "#1E90FF";
ctx.shadowBlur = 15;
ctx.font = "24px Arial";
ctx.textAlign = "center";
ctx.fillText("</^\\>", x, y);
}
function Lazer() {
this.x = playerX;
this.y = playerY - 38;
this.draw = function() {
ctx.fillStyle = "#FFFF00";
ctx.shadowColor = "#FFFF00";
ctx.shadowBlur = 15;
this.y -= lazerSpeed;
ctx.fillRect(this.x, this.y, 2, 18);
}
}
function DrawLazers() {
// Check if the last lazer fired is far enough away to fire another
if (lazers.length != 0) {
if (lazers[lazers.length - 1].y <= lazerReloadDistance) {
lazerLoaded = true;
}
}
else {
lazerLoaded = true;
}
for (var i = 0; i < lazers.length; i++) {
var currentLazer = lazers[i];
// Still on screen
if (currentLazer.y > -20) {
currentLazer.draw();
}
else {
lazers.splice(i, 1);
}
}
}
function Enemy(x) {
this.x = x;
this.y = 0;
this.health = Math.ceil(Math.random() * 4);
this.speed = enemySpeed / this.health;
var letterIndex = Math.floor(Math.random() * letters.length);
this.letter = letters.substr(letterIndex, 1);
this.size = 24 + (this.health * 4); // Font size based on health
ctx.font = this.size+"px Arial";
this.width = ctx.measureText(this.letter).width;
this.height = this.size * 0.75; // Approximate height;
this.draw = function() {
ctx.fillStyle = "#FF0040";
ctx.shadowColor = "#FF0040";
ctx.shadowBlur = 15;
ctx.font = this.size+"px Arial";
ctx.textAlign = "center";
this.y += this.speed;
ctx.fillText(this.letter, this.x, this.y);
}
}
function DrawEnemies() {
// Spawn new enemies
if (Math.random() <= 0.05 && enemies.length < maxEnemies) {
var randX = 40 + Math.floor(Math.random() * (WIDTH - 80));
enemies.push(new Enemy(randX));
}
for (var i = 0; i < enemies.length; i++) {
var currentEnemy = enemies[i];
if (currentEnemy.health <= 0) {
enemies.splice(i, 1);
score += 25;
kills++;
continue;
}
// Put enemies that passed the player back at the top
if (currentEnemy.y > HEIGHT + currentEnemy.height) {
currentEnemy.y = 0;
continue;
}
currentEnemy.draw();
}
}
var gameOverMessages = [
"You're in a better place",
"You're Cooked!",
"You gave it your all",
"At least you tried",
"You're Ruined!",
"You're Finished!"
];
function DrawGameOver() {
var message = gameOverMessages[Math.floor(Math.random() * gameOverMessages.length)];
// after deleting the audio element, this doesnt work anymore.
// document.getElementById("background-music").pause();
ctx.fillStyle = "#505050";
ctx.shadowColor = "#505050";
ctx.shadowBlur = 15;
ctx.fillRect(50, (HEIGHT / 2) - 100, WIDTH - 100, 200)
ctx.fillStyle = "#FFFFFF";
ctx.shadowColor = "#FFFFFF";
ctx.shadowBlur = 15;
ctx.textAlign = "center";
ctx.font = "36pt Arial";
ctx.fillText(message, WIDTH / 2, HEIGHT / 2 - 40);
ctx.textAlign = "end";
ctx.font = "18pt Arial";
ctx.fillText("Final Score - ", WIDTH / 2, HEIGHT / 2 + 30);
ctx.textAlign = "start";
ctx.fillStyle = "#FFFF00";
ctx.shadowColor = "#FFFF00";
ctx.fillText(score, WIDTH / 2, HEIGHT / 2 + 30);
ctx.fillStyle = "#FFFFFF";
ctx.shadowColor = "#FFFFFF";
ctx.textAlign = "end";
ctx.font = "18pt Arial";
ctx.fillText("Total Kills - ", WIDTH / 2, HEIGHT / 2 + 60);
ctx.textAlign = "start";
ctx.fillStyle = "#FF0040";
ctx.shadowColor = "#FF0040";
ctx.fillText(kills, WIDTH / 2, HEIGHT / 2 + 60);
}
////////////////////
// Core Functions //
////////////////////
var collidedEnemyIndex = -1;
function CheckCollision() {
for (var i = 0; i < enemies.length; i++) {
var currentEnemy = enemies[i];
// Check if enemy hits player. The 2 is to account for the text width of the player
if (
currentEnemy.x <= playerX - 2 + 25 + (currentEnemy.width / 2) &&
currentEnemy.x >= playerX - 2 - 25 - (currentEnemy.width / 2) &&
currentEnemy.y >= playerY - 18 &&
currentEnemy.y <= playerY + currentEnemy.height &&
collidedEnemyIndex != enemies.indexOf(currentEnemy)
)
{
collidedEnemyIndex = enemies.indexOf(currentEnemy);
playerHealth--;
}
// Reset the index of the enemy colliding with the player
if (collidedEnemyIndex == enemies.indexOf(currentEnemy) && currentEnemy.y < HEIGHT / 2) {
collidedEnemyIndex = -1;
}
for (var j = 0; j < lazers.length; j++) {
var currentLazer = lazers[j];
if (
currentLazer.x <= currentEnemy.x + (currentEnemy.width / 2) &&
currentLazer.x >= currentEnemy.x - (currentEnemy.width / 2) &&
currentLazer.y <= currentEnemy.y
)
{
currentEnemy.health--;
score += 10;
lazers.splice(lazers.indexOf(currentLazer), 1);
}
}
}
}
function HandleInput() {
if (keys[0] == true && keys[1] == false && playerX <= WIDTH - 30) {
playerX += playerSpeed;
}
if (keys[1] == true && keys[0] == false && playerX >= 30) {
playerX -= playerSpeed;
}
if (keys[2]) {
if (lazerLoaded) {
lazers.push(new Lazer());
lazerLoaded = false;
}
}
}
function KeysDown(e) {
e.preventDefault();
// Right
if (e.keyCode == 39) {
keys[0] = true;
}
// Left
else if (e.keyCode == 37) {
keys[1] = true;
}
// Up/Fire
if (e.keyCode == 38) {
keys[2] = true;
}
}
function KeysUp(e) {
// Right
if (e.keyCode == 39) {
keys[0] = false;
}
// Left
else if (e.keyCode == 37) {
keys[1] = false;
}
// Up/Fire
if (e.keyCode == 38) {
keys[2] = false;
}
}
document.addEventListener("keydown", KeysDown, true);
document.addEventListener("keyup", KeysUp, true);
function Update() {
Clear();
HandleInput();
CheckCollision();
DrawEnemies();
DrawLazers();
DrawPlayer(playerX, playerY);
DrawHealth(playerHealth);
DrawScore();
if (playerHealth <= 0) {
clearInterval(gameLoop);
DrawGameOver();
}
}
var gameLoop = setInterval(Update, updateTime);
};
document.querySelector( '#start_game' ).addEventListener( 'click', run_game );
</script>
</body>
</html>

Can't figure out where to draw image in Javascript code

I am having issues trying to place an image as an object for an "asteroid avoidance" game. I was able to get the game itself to work based on what was written in my book "Foundation: HTML5 Canvas for Games and Entertainment". I want to go one step beyond what was written in the book. I want to replace the triangle shaped ship with that of an image. However, I am unable to figure out where to put the code for this.draw. My professor showed us a way to do it. When I try to implement it into my code it doesn't want to work properly. May I ask for some advice on how to place the image as the ship?
Here is my working code from the book, before I made any this.draw edits:(http://jsbin.com/tukejopofo/1/)
$(document).ready(function() {
var canvas = $("#gameCanvas");
var context = canvas.get(0).getContext("2d");
//canvas dimensions
var canvasWidth = canvas.width();
var canvasHeight = canvas.height();
var playGame;
var asteroids;
var numAsteroids;
var player;
var score;
var scoreTimeout;
var arrowUp = 38;
var arrowRight = 39;
var arrowDown = 40;
var arrowLeft = 37;
//game UI
var ui = $("#gameUI");
var uiIntro = $("#gameIntro");
var uiStats = $("#gameStats");
var uiComplete = $("#gameComplete");
var uiPlay = $("#gamePlay");
var uiReset = $(".gameReset");
var uiScore = $(".gameScore");
var soundBackground = $("#gameSoundBackground").get(0);
var soundThrust = $("#gameSoundThrust").get(0);
var soundDeath = $("#gameSoundDeath").get(0);
var Asteroid = function(x, y, radius, vX) {
this.x = x;
this.y = y;
this.radius = radius;
this.vX = vX;
};
var Player = function(x, y) {
this.x = x;
this.y = y;
this.width = 24;
this.height = 24;
this.halfWidth = this.width / 2;
this.halfHeight = this.height / 2;
this.flameLength1 = 20;
this.flameLength2 = 20;
this.vX = 0;
this.vY = 0;
this.moveRight = false;
this.moveUp = false;
this.moveDown = false;
this.moveLeft = false;
};
//Reset and start the game
function startGame() {
//Reset game stats
uiScore.html("0");
uiStats.show();
//set up initial game settings
playGame = false;
asteroids = new Array();
numAsteroids = 10;
score = 0;
player = new Player(150, canvasHeight / 2, 50, 50);
for (var i = 0; i < numAsteroids; i++) {
var radius = 5 + (Math.random() * 10);
var x = canvasWidth + radius + Math.floor(Math.random() * canvasWidth);
var y = Math.floor(Math.random() * canvasHeight);
var vX = -5 - (Math.random() * 5);
asteroids.push(new Asteroid(x, y, radius, vX));
};
$(window).keydown(function(e) {
var keyCode = e.keyCode;
if (!playGame) {
playGame = true;
soundBackground.currentTime = 0;
soundBackground.play();
animate();
timer();
};
if (keyCode == arrowRight) {
player.moveRight = true;
if (soundThrust.paused) {
soundThrust.currentTime = 0;
soundThrust.play();
}
} else if (keyCode == arrowLeft) {
player.moveLeft = true;
} else if (keyCode == arrowUp) {
player.moveUp = true;
} else if (keyCode == arrowDown) {
player.moveDown = true;
}
});
$(window).keyup(function(e) {
var keyCode = e.keyCode;
if (!playGame) {
playGame = true;
animate();
};
if (keyCode == arrowRight) {
player.moveRight = false;
if (keyCode == arrowRight) {
player.moveRight = false;
soundThrust.pause();
}
} else if (keyCode == arrowUp) {
player.moveUp = false;
} else if (keyCode == arrowDown) {
player.moveDown = false;
} else if (keyCode == arrowLeft) {
player.moveLeft = false;
}
});
//start the animation loop
animate();
};
//initialize the game environment
function init() {
uiStats.hide();
uiComplete.hide();
uiPlay.click(function(e) {
e.preventDefault();
uiIntro.hide();
startGame();
});
uiReset.click(function(e) {
e.preventDefault();
uiComplete.hide();
$(window).unbind("keyup");
$(window).unbind("keydown");
soundThrust.pause();
soundBackground.pause();
clearTimeout(scoreTimeout);
startGame();
});
};
function timer() {
if (playGame) {
scoreTimeout = setTimeout(function() {
uiScore.html(++score);
if (score % 5 == 0) {
numAsteroids += 5;
}
timer();
}, 1000);
};
};
//Animation loop that does all the fun stuff
function animate() {
//Clear
context.clearRect(0, 0, canvasWidth, canvasHeight);
var asteroidsLength = asteroids.length;
for (var i = 0; i < asteroidsLength; i++) {
var tmpAsteroid = asteroids[i];
tmpAsteroid.x += tmpAsteroid.vX;
if (tmpAsteroid.x + tmpAsteroid.radius < 0) { //creates bounderies to prevent player from leaving the canvas
tmpAsteroid.radius = 5 + (Math.random() * 10);
tmpAsteroid.x = canvasWidth + tmpAsteroid.radius;
tmpAsteroid.y = Math.floor(Math.random() * canvasHeight);
tmpAsteroid.vX = -5 - (Math.random() * 5);
}
var dX = player.x - tmpAsteroid.x;
var dY = player.y - tmpAsteroid.y;
var distance = Math.sqrt((dX * dX) + (dY * dY));
if (distance < player.halfWidth + tmpAsteroid.radius) { //checks for collision
soundThrust.pause()
soundDeath.currentTime = 0;
soundDeath.play();
//Game over
playGame = false;
clearTimeout(scoreTimeout);
uiStats.hide();
uiComplete.show();
soundBackground.pause();
$(window).unbind("keyup"); //unbinds keys to stop player movement at the end of the game
$(window).unbind("keydown");
};
context.fillStyle = "rgb(255, 255, 255)";
context.beginPath();
context.arc(tmpAsteroid.x, tmpAsteroid.y, tmpAsteroid.radius, 0, Math.PI * 2, true);
context.fill();
};
player.vX = 0;
player.vY = 0;
if (player.moveRight) {
player.vX = 3;
};
if (player.moveLeft) {
player.vX = -3;
};
if (player.moveUp) {
player.vY = -3;
};
if (player.moveDown) {
player.vY = 3;
};
player.x += player.vX;
player.y += player.vY;
if (player.x - player.halfWidth < 20) {
player.x = 20 + player.halfWidth;
} else if (player.x + player.halfWidth > canvasWidth - 20) {
player.x = canvasWidth - 20 - player.halfWidth;
}
if (player.y - player.halfHeight < 20) {
player.y = 20 + player.halfHeight;
} else if (player.y + player.halfHeight > canvasHeight - 20) {
player.y = canvasHeight - 20 - player.halfHeight;
}
if (player.moveRight) {
context.save();
context.translate(player.x - player.halfWidth, player.y);
if (player.flameLength1 == 20) {
player.flameLength1 = 15;
(player.flameLength2 == 20)
player.flameLength2 = 15;
} else {
player.flameLength1 = 20;
player.flameLength2 = 20;
};
context.fillStyle = "orange";
context.beginPath();
context.moveTo(0, -12);
context.lineTo(-player.flameLength1, -7);
context.lineTo(0, -5);
context.closePath();
context.fill();
context.fillStyle = "orange";
context.beginPath();
context.moveTo(0, 12);
context.lineTo(-player.flameLength2, 7);
context.lineTo(0, 5);
context.closePath();
context.fill();
context.restore();
};
//draw ship
context.fillStyle = "rgb(255, 0, 0)";
context.beginPath();
context.moveTo(player.x + player.halfWidth, player.y);
context.lineTo(player.x - player.halfWidth, player.y - player.halfHeight);
context.lineTo(player.x - player.halfWidth, player.y + player.halfHeight);
context.closePath();
context.fill();
while (asteroids.length < numAsteroids) { //adds asteroids as the difficulty increases
var radius = 5 + (Math.random() * 10)
var x = Math.floor(Math.random() * canvasWidth) + canvasWidth + radius;
var y = Math.floor(Math.random() * canvasHeight);
var vX = -5 - (Math.random() * 5);
asteroids.push(new Asteroid(x, y, radius, vX));
}
if (playGame) {
//run the animation loop again in 33 milliseconds
setTimeout(animate, 24);
};
};
init();
});
* {
margin: 0;
padding: 0;
}
html,
body {
height: 100%;
width: 100%;
}
canvas {
display: block;
}
body {
background: #000;
color: #fff;
font-family: Verdana, Arial, sans-serif;
font-size: 18px;
}
h1 {
font-size: 30px;
}
h6 {
font-size: 15px;
}
p {
margin: 0 20px;
}
a {
color: #fff;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
a.button {
background: #185da8;
border-radius: 5px;
display: block;
font-size: 30px;
margin: 40px 0 0 350px;
padding: 10px;
width: 200px;
text-align: center;
}
a.button:hover {
background: #2488f5;
color: #fff;
text-decoration: none;
}
#game {
height: 600px;
left: 50%;
margin: -250px 0 0 -500px;
position: relative;
top: 50%;
width: 980px;
}
#gameCanvas {
background: #001022;
border: 5px solid green;
background-image: url(../images/space.jpg);
background-position: center top;
background-repeat: no-repeat;
background-size: cover;
}
#gameUI {
height: 600px;
position: absolute;
width: 980px;
}
#gameIntro,
#gameComplete {
background: rgba(0, 0, 0, 0.5);
margin: 100px 0 0 10px;
padding: 40px 0;
text-align: center;
}
#gameStats {
font-size: 14px;
margin: 20px 0;
}
#gameStats .gameReset {
margin: 20px 20px 0 0;
position: absolute;
right: 0;
top: 0;
}
<body>
<div id="game">
<div id="gameUI">
<div id="gameIntro">
<h1>Debris Fields of Spiral Galaxy</h1>
<h6>A <i>Galaxy Smuggler's Run</i> Game</h6>
<hr>
<p>You are Captain Amadaeus delivering goods to a dependent planet on the other side of a debris field</p>
<p>Click <i>"Play"</i> and then press any key to start.</p>
<p><a id="gamePlay" class="button" href="">Play!</a>
</p>
</div>
<div id="gameStats">
<p><b>Time: </b><span class="gameScore"></span> seconds</p>
<p><a class="gameReset" href="">Reset</a>
</p>
</div>
<div id="gameComplete">
<h1>Game Over!</h1>
<p>You survived for <span class="gameScore"></span> seconds.</p>
<p>Would you like to give it another go?</p>
<p><a class="gameReset button" href="">Play Again?</a>
</p>
</div>
</div>
<canvas id="gameCanvas" width="980" height="600">
</canvas>
<audio id="gameSoundBackground" loop>
<source src="sounds/background.ogg">
<source src="sounds/background.mp3">
</audio>
<audio id="gameSoundThrust" loop>
<source src="sounds/thrust.ogg">
<source src="sounds/thrust.mp3">
</audio>
<audio id="gameSoundDeath">
<source src="sounds/death.ogg">
<source src="sounds/death.mp3">
</audio>
</div>
</body>
and here is my Professor's code for drawing an image:(http://jsbin.com/rapayufafe/1/)
// JS file for the ship
function Ship() {
this.x = 100;
this.y = 100;
this.color = "yellow";
this.fillStyle = "white";
this.vx = 0;
this.vy = 0;
this.ax = 1;
this.ay = 1;
//function "move" that will add velocity to the position of the ship
this.move = function() {
this.x += this.vx;
this.y += this.vy;
}//end move function
//draw the ship
this.draw=function () {
//ship var
var imageObj = new Image();
imageObj.src = "images/ship.png";
//save the current state of the canvas
context.save();
//moving the point of origin (0,0) to the ships x and y coordinates
context.translate(this.x,this.y);
context.lineStyle = this.color;
context.fillStyle = this.fillStyle;
/*context.beginPath();
context.moveTo(25,0);
context.lineTo(-25,25)
context.lineTo(-25,-25)*/
//draw ship
context.drawImage(imageObj,-25,-25,50,50);
context.closePath();
context.stroke();
context.fill();
context.restore();
}//end of draw ship
}//end ship function
/*var asteroidsLength = asteroids.length;
for (var i = 0; i < asteroidsLength; i++) {
var tmpAsteroid = asteroids[i];
context.fillStyle = "gray";
context.beginPath();
context.arc(tmpAsteroid.x, tmpAsteroid.y, tmpAsteroid.radius, 0, Math.PI*2, true);
context.closePath();
context.fill();
};*/
As you can see in your starting code, you have a section looking like this:
//draw ship
context.fillStyle = "rgb(255, 0, 0)";
context.beginPath();
context.moveTo(player.x + player.halfWidth, player.y);
context.lineTo(player.x - player.halfWidth, player.y - player.halfHeight);
context.lineTo(player.x - player.halfWidth, player.y + player.halfHeight);
context.closePath();
context.fill();
Just replace that code with the code for drawing an image.
var imageObj = new Image();
imageObj.src = "images/ship.png";
context.drawImage(imageObj,player.x,player.y);
Although, I'd recommend declaring the imageObj and setting the source at the top of your code where you declare the rest of your variables so that you don't load the image every time you want to draw the ship.

changing image color while animating it in javascript

I have an image drawn on a canvas. The image for now is doing a simple circular rotation on each frame.
The image scaling is based on the value entered in the text box.
I put the jsfiddle as suggested below
var canvas = null;
var ctx = null;
var image = null;
var slider = null;
var vBox = null;
var x = 50;
var y = 50;
var scaleX;
var scaleY;
var center = {
x: 0,
y: 0
};
var radius = 50.0;
var angle = 0;
var result = false;
var textActive = false;
var imgArr = null;
var imageData;
var data;
function start() {
ctx = getCtxReference();
image = getImageReference();
result = setOtherReferences();
imgArr = getStarImages();
imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
data = imageData.data;
for (var i = 0; i < imgArr.length; i++) {
imgArr[i].addEventListener('load', drawBackgroundStar)
}
if (image != null && result && imgArr != null) {
Loop();
}
}
function checkKeyPressed(e) {
if (e.keyCode == "65") {
changeImgColorToBlue();
}
}
function getCtxReference() {
canvas = document.getElementById("canvas");
ctx = canvas.getContext('2d');
return ctx;
}
function getImageReference() {
image = new Image();
image.src = "star.png";
image.addEventListener('load', drawImg);
return image;
}
function setOtherReferences() {
slider = document.getElementById("rangeInput");
vBox = document.getElementById("textbox");
scaleX = 100;
scaleY = 100;
center.x = canvas.width / 3;
center.y = canvas.height / 3;
return true;
}
function getStarImages() {
var arr = new Array();
for (var i = 0; i < 500; i++) {
var img = new Image();
img.src = "star.png";
arr.push(img);
}
return arr;
}
function drawImg() {
ctx.drawImage(image, x, y, scaleX, scaleY);
return true;
}
function drawBackgroundStar() {
for (var i = 0; i < imgArr.length; i++) {
ctx.drawImage(imgArr[i], getRandomArbitrary(0, canvas.width), getRandomArbitrary(0, canvas.height), getRandomArbitrary(5, 15), getRandomArbitrary(5, 15));
}
}
function Loop() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
window.setTimeout(Loop, 100);
angle += Math.PI * 0.05;
x = center.x + radius * Math.cos(angle);
y = center.y + radius * Math.sin(angle);
vBox.value = slider.value;
updateStarScale();
drawImg();
//drawBackgroundStar();
}
function updateStarScale() {
if (vBox.value > 0) {
scaleX += vBox.value / 10;
scaleY += vBox.value / 10;
changeImgColorToBlue();
} else if (vBox.value < 0) {
scaleX -= Math.abs(vBox.value / 10);
scaleY -= Math.abs(vBox.value / 10);
changeImgColorToRed();
}
if (scaleX > 600 || scaleY > 600) {
scaleX = 600;
scaleY = 600;
} else if (scaleX < 50 || scaleY < 50) {
scaleX = 50;
scaleY = 50;
}
}
function changeImgColorToBlue() {
for (var i = 0; i < data.length; i += 4) {
data[i] = 0; // red
data[i + 1] = 0; // green
data[i + 2] = 255; // blue
}
ctx.putImageData(imageData, 0, 0);
}
function changeImgColorToRed() {
}
function getRandomArbitrary(min, max) {
return Math.random() * (max - min) + min;
}
<html>
<style type="text/css">
body {
text-align: center;
background-image: url("stars.png");
}
#container {
position: fixed;
color: red;
top: 0px;
left: 0px;
}
#textBox {
position: absolute;
top: 25px;
left: 5px;
}
#slider {
position: absolute;
top: 25px;
left: 200px;
}
</style>
<body onload="start()">
<canvas id="canvas" width="1024" height="768"></canvas>
<div id="container">
<div id="textBox">
Velocity:
<input type="text" id="textbox" value="0">
</div>
<div id="slider">
Slider:
<form oninput="amount.value=rangeInput.value">
<input type="range" id="rangeInput" name="rangeInput" min="-100" max="100" step="3" value="">
<output name="amount" for="rangeInput">0</output>
</form>
</div>
</div>
<script type="text/javascript" src="main.js">
</script>
</body>
</html>
So in my Loop(), I am updating the position of my image. In the updateStarScale() I am scaling the image size based on the value given in the text box by the user. All of this works fine. My only concern is the changeImgColorToBlue() which does nothing to the image color. I want the image color to be changed to blue but this doesn't work. What am I doing wrong?
**
UPDATE 1.0:
**
After suggestions from the last post, I changed the code to below. There are two yellow stars on the screen now and they scale up based on the sliders but alongside scaling I want their colors to change ie when they are scaled up they turn blue and when they are scaled down they turn red but the colors don't change.
//Create the images(Using a canvas for CORS issues)
function createStars() {
var imgCanvas = document.createElement('canvas');
imgCanvas.height = "500";
imgCanvas.width = "500";
var imgCtx = imgCanvas.getContext('2d');
imgCtx.fillStyle = 'black';
imgCtx.fillRect(0, 0, 500, 500)
imgCtx.fillStyle = '#FF0';
for (i = 0; i < Math.floor(Math.random() * 500) + 250; i++) {
imgCtx.fillRect(Math.random() * 500, Math.random() * 500, 1, 1)
}
document.body.style.backgroundImage = 'url(' + imgCanvas.toDataURL() + ')';
}
createStars();
var canvas = null;
var ctx = null;
var image = null;
var slider = null;
var vBox = null;
var x = 50;
var y = 50;
var scaleX;
var scaleY;
var center = {
x: 0,
y: 0
};
var radius = 50.0;
var angle = 0;
var result = false;
var imageData;
var data;
var backgroundImg = null;
function start() {
ctx = getCtxReference();
result = setOtherReferences();
image = getStarImages();
if (image != null)
image.addEventListener('load', Loop);
}
function getCtxReference() {
canvas = document.getElementById("canvas");
ctx = canvas.getContext('2d');
return ctx;
}
function setOtherReferences() {
slider = document.getElementById("rangeInput");
vBox = document.getElementById("textbox");
scaleX = 150;
scaleY = 150;
center.x = canvas.width / 3;
center.y = canvas.height / 3;
return true;
}
function getStarImages() {
var img = new Image();
img.src = createStar();
return img;
}
function createStar() {
ctx.fillStyle = '#FF0';
ctx.fillRect(Math.random() * 45, Math.random() * 45, scaleX, scaleY);
return canvas.toDataURL();
}
function drawImg() {
ctx.drawImage(image, x, y, scaleX, scaleY);
}
function Loop() {
window.setTimeout(Loop, 100);
ctx.clearRect(0, 0, canvas.width, canvas.height);
angle += Math.PI * 0.05;
x = center.x + radius * Math.cos(angle);
y = center.y + radius * Math.sin(angle);
vBox.value = slider.value;
updateStarScale();
drawImg();
}
function updateStarScale() {
if (vBox.value > 0) {
scaleX += vBox.value / 10;
scaleY += vBox.value / 10;
changeImgColorToBlue();
} else if (vBox.value < 0) {
scaleX -= Math.abs(vBox.value / 10);
scaleY -= Math.abs(vBox.value / 10);
changeImgColorToRed();
}
if (scaleX > 600 || scaleY > 600) {
scaleX = 600;
scaleY = 600;
} else if (scaleX < 50 || scaleY < 50) {
scaleX = 50;
scaleY = 50;
}
}
function changeImgColorToBlue() {
imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
data = imageData.data;
for (var i = 0; i < data.length; i += 4) {
//is our data black?
if (data[i] > 0 || data[i + 1] > 0 || data[i + 2] > 0) {
data[i] = 0; // red
data[i + 1] = 0; // green
data[i + 2] = 255; // blue
}
}
ctx.putImageData(imageData, 0, 0);
}
function changeImgColorToRed() {
imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
data = imageData.data;
for (var i = 0; i < data.length; i += 4) {
if (data[i] > 0 || data[i + 1] > 0 || data[i + 2] > 0) {
data[i] = 255; // red
data[i + 1] = 0; // green
data[i + 2] = 0; // blue
}
}
ctx.putImageData(imageData, 0, 0);
}
function getRandomArbitrary(min, max) {
return Math.random() * (max - min) + min;
}
start();
Edit
Ok, so if you only need to draw those moving stars, you can simplify a lot your code, especially about the changing color :
As each star is only a colored rectangle, you only have to store a color value (i.e hex) and update it when you want to the desired color. No bitmap calculation needed.
However, as your code is right now, if you try to create new stars, they will all follow the same path and scale update.
I think that you will have to rethink the way you update the position.
Here is an update, with simplification of the code and example showing the issue
function createStars() {
var imgCanvas = document.createElement('canvas');
imgCanvas.height = "500";
imgCanvas.width = "500";
var imgCtx = imgCanvas.getContext('2d');
imgCtx.fillStyle = 'black';
imgCtx.fillRect(0, 0, 500, 500)
imgCtx.fillStyle = '#FF0';
for (i = 0; i < Math.floor(Math.random() * 500) + 250; i++) {
imgCtx.fillRect(Math.random() * 500, Math.random() * 500, 1, 1)
}
document.body.style.backgroundImage = 'url(' + imgCanvas.toDataURL() + ')';
}
createStars();
var canvas = null;
var ctx = null;
var slider = null;
var vBox = null;
var x = 50;
var y = 50;
var center = {
x: 0,
y: 0
};
var radius = 50.0;
var angle = 0;
var result = false;
var color = "FF0"; // set the color as a global variable, avoiding a function to set it
var stars = []; // set an array that will contain all our moving stars
function start() {
canvas = document.getElementById("canvas");
ctx = canvas.getContext('2d');
result = setOtherReferences();
// append new stars to our array
stars.push(createStar());
stars.push(createStar());
stars.push(createStar());
// start the Loop()
Loop();
}
function setOtherReferences() {
slider = document.getElementById("rangeInput");
vBox = document.getElementById("textbox");
center.x = canvas.width / 3;
center.y = canvas.height / 3;
return true;
}
function createStar() {
// set moving stars as object, with their own x,y,width and height properties.
var star = {
xStart: Math.random() * 150, // used in order to avoid the exact
yStart: Math.random() * 150, // same position of your stars
x: this.xStart,
y: this.yStart,
w: 50,
h: 50
}
return star;
}
function drawImg() {
// set the moving stars color to the actual growing/shrinking state
ctx.fillStyle = color;
// for each of our moving stars, draw a rect
for (i = 0; i < stars.length; i++) {
ctx.fillRect(stars[i].x, stars[i].y, stars[i].w, stars[i].h);
}
}
function Loop() {
window.setTimeout(Loop, 100);
ctx.clearRect(0, 0, canvas.width, canvas.height);
angle += Math.PI * 0.05;
/*
Here is the main issue
as each of our stars x/y pos are updated with the same function,
they will follow each others.
I added the xStart property so they're not
exactly at the same position for you beeing able to see it.
*/
for (i = 0; i < stars.length; i++) {
stars[i].x = center.x + radius * Math.cos(angle) + stars[i].xStart;
stars[i].y = center.y + radius * Math.sin(angle) + stars[i].yStart;
}
vBox.value = slider.value;
updateStarScale();
drawImg();
}
function updateStarScale() {
//same as above, each of our stars will have the same scale update
for (i = 0; i < stars.length; i++) {
if (vBox.value > 0) {
stars[i].w += vBox.value / 10;
stars[i].h += vBox.value / 10;
color = "#00F";
} else if (vBox.value < 0) {
stars[i].w -= Math.abs(vBox.value / 10);
stars[i].h -= Math.abs(vBox.value / 10);
color = "#F00";
}
if (stars[i].w > 600 || stars[i].h > 600) {
stars[i].w = 600;
stars[i].h = 600;
} else if (stars[i].w < 5 || stars[i].h < 5) {
stars[i].w = 5;
stars[i].h = 5;
}
}
}
// Only call it if you haven't already done (i.e in a load event)
start();
body {
text-align: center;
background-image: url("stars.png");
}
#container {
position: fixed;
color: red;
top: 0px;
left: 0px;
}
#textBox {
position: absolute;
top: 25px;
left: 5px;
}
#slider {
position: absolute;
top: 25px;
left: 200px;
}
<canvas id="canvas" width="1024" height="768"></canvas>
<div id="container">
<div id="textBox">
Velocity:
<input type="text" id="textbox" value="0">
</div>
<div id="slider">
Slider:
<form oninput="amount.value=rangeInput.value">
<input type="range" id="rangeInput" name="rangeInput" min="-100" max="100" step="3" value="0">
<output name="amount" for="rangeInput">0</output>
</form>
</div>
</div>
Original answer
First, You will need to update your imageData each time you call changeImgColorToBlue.
Secondly, in order to not change all your pixels into blue, you will have to check if each pixel is in some range of color.
Assuming your star.png does look like a black background with colored dots over it, you can do:
for (var i = 0; i < data.length; i += 4) {
if( data[i]>0 || data[i+1]>0 || data[i+2]>0 ){
//is our pixel black?
data[i] = 0;// red
data[i + 1] = 0; // green
data[i + 2] = 255; // blue
}
}
Of course, you can change those conditions to match for the actual color of your dots with more precision by using e.g if your dots are yellow
if( data[i]>=200 && data[i+1]>=200 && data[i+2]<100 )
Also, I did some changes in your code as you had redundant calls to some functions.
//Create the images(Using a canvas for CORS issues)
function createStars(){
var imgCanvas = document.createElement('canvas');
imgCanvas.height="500";
imgCanvas.width="500";
var imgCtx = imgCanvas.getContext('2d');
imgCtx.fillStyle= 'black';
imgCtx.fillRect(0,0,500,500)
imgCtx.fillStyle= '#FF0';
for(i=0; i<Math.floor(Math.random()*500)+250; i++){
imgCtx.fillRect(Math.random()*500, Math.random()*500, 1,1)
}
document.body.style.backgroundImage='url('+imgCanvas.toDataURL()+')';
}
createStars();
function createStar(){
var imgCanvas = document.createElement('canvas');
imgCanvas.height="50";
imgCanvas.width="50";
var imgCtx = imgCanvas.getContext('2d');
imgCtx.fillStyle= '#FF0';
imgCtx.fillRect(Math.random()*45,Math.random()*45, 5,5);
return imgCanvas.toDataURL();
}
var canvas = null;
var ctx = null;
var image = null;
var slider = null;
var vBox = null;
var x = 50;
var y = 50;
var scaleX;
var scaleY;
var center = {
x: 0,
y: 0
};
var radius = 50.0;
var angle = 0;
var result = false;
var textActive = false;
var imgArr = null;
var imageData;
var data;
var backgroundImg = null;
function start() {
ctx = getCtxReference();
result = setOtherReferences();
image = getStarImages();
if (image != null && result && imgArr != null) {
Loop();
}
}
function getCtxReference() {
canvas = document.getElementById("canvas");
ctx = canvas.getContext('2d');
return ctx;
}
function setOtherReferences() {
slider = document.getElementById("rangeInput");
vBox = document.getElementById("textbox");
scaleX = 100;
scaleY = 100;
center.x = canvas.width / 3;
center.y = canvas.height / 3;
return true;
}
function drawImg() {
ctx.drawImage(image, x, y, scaleX, scaleY);
return true;
}
function Loop() {
window.setTimeout(Loop, 100);
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.drawImage(backgroundImg, 0,0);
angle += Math.PI * 0.05;
x = center.x + radius * Math.cos(angle);
y = center.y + radius * Math.sin(angle);
vBox.value = slider.value;
updateStarScale();
drawImg();
}
function getStarImages() {
//as they're all the same image, you don't need to make an array of them, simply make a loop below
var img = new Image();
img.addEventListener('load', drawBackgroundStar)
img.src = createStar();
return img;
}
function drawBackgroundStar() {
for (var i=0; i<500; i++) {
ctx.drawImage(image, getRandomArbitrary(0, canvas.width), getRandomArbitrary(0, canvas.height), getRandomArbitrary(5, 15), getRandomArbitrary(5, 15));
}
backgroundImg = new Image();
backgroundImg.addEventListener('load', Loop);
backgroundImg.src = canvas.toDataURL();
}
function updateStarScale() {
if (vBox.value > 0) {
scaleX += vBox.value / 10;
scaleY += vBox.value / 10;
changeImgColorToBlue();
} else if (vBox.value < 0) {
scaleX -= Math.abs(vBox.value / 10);
scaleY -= Math.abs(vBox.value / 10);
changeImgColorToRed();
}
if (scaleX > 600 || scaleY > 600) {
scaleX = 600;
scaleY = 600;
} else if (scaleX < 50 || scaleY < 50) {
scaleX = 50;
scaleY = 50;
}
}
function changeImgColorToBlue() {
imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
data = imageData.data;
for (var i = 0; i < data.length; i += 4) {
//is our data black?
if(data[i]>0||data[i+1]>0||data[i+2]>0){
data[i] = 0;// red
data[i + 1] = 0; // green
data[i + 2] = 255; // blue
}
}
ctx.putImageData(imageData, 0, 0);
}
function changeImgColorToRed() {
imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
data = imageData.data;
for (var i = 0; i < data.length; i += 4) {
if(data[i]>0||data[i+1]>0||data[i+2]>0){
data[i] = 255;// red
data[i + 1] = 0; // green
data[i + 2] = 0; // blue
}
}
ctx.putImageData(imageData, 0, 0);
}
function getRandomArbitrary(min, max) {
return Math.random() * (max - min) + min;
}
start();
body {
text-align: center;
}
#container {
position: fixed;
color: red;
top: 0px;
left: 0px;
}
#textBox {
position: absolute;
top: 25px;
left: 5px;
}
#slider {
position: absolute;
top: 25px;
left: 200px;
}
<canvas id="canvas" width="1024" height="768"></canvas>
<div id="container">
<div id="textBox">
Velocity:
<input type="text" id="textbox" value="0">
</div>
<div id="slider">
Slider:
<form oninput="amount.value=rangeInput.value">
<input type="range" id="rangeInput" name="rangeInput" min="-100" max="100" step="3" value="">
<output name="amount" for="rangeInput">0</output>
</form>
</div>
</div>
As you wrote it, the changeImgColorToBlue functions are only changing the background stars of your canvas. I'm not sure it is what you want to achieve so here is a way to only change this one dot :
function createStars(){
var imgCanvas = document.createElement('canvas');
imgCanvas.height="500";
imgCanvas.width="500";
var imgCtx = imgCanvas.getContext('2d');
imgCtx.fillStyle= 'black';
imgCtx.fillRect(0,0,500,500)
imgCtx.fillStyle= '#FF0';
for(i=0; i<Math.floor(Math.random()*500)+250; i++){
imgCtx.fillRect(Math.random()*500, Math.random()*500, 1,1)
}
document.body.style.backgroundImage='url('+imgCanvas.toDataURL()+')';
}
createStars();
function createStar(){
var imgCanvas = document.createElement('canvas');
imgCanvas.height="50";
imgCanvas.width="50";
var imgCtx = imgCanvas.getContext('2d');
imgCtx.fillStyle= '#FF0';
imgCtx.fillRect(Math.random()*45,Math.random()*45, 5,5);
return imgCanvas.toDataURL();
}
var canvas = null;
var ctx = null;
var starCanvas = null;
var starCtx = null;
var image = null;
var slider = null;
var vBox = null;
var x = 50;
var y = 50;
var scaleX;
var scaleY;
var center = {
x: 0,
y: 0
};
var radius = 50.0;
var angle = 0;
var result = false;
var textActive = false;
var imgArr = null;
var imageData;
var data;
var backgroundImg = null;
function start() {
ctx = getCtxReference();
starCtx = getStarReference();
result = setOtherReferences();
image = getStarImages();
if (image != null && result && imgArr != null && backgroundImg != null) {
Loop();
}
}
function getCtxReference() {
canvas = document.getElementById("canvas");
return canvas.getContext('2d');
}
function getStarReference() {
starCanvas = document.createElement("canvas");
starCanvas.height = 50;
starCanvas.width = 50;
starCanvas.id=('star');
document.body.appendChild(starCanvas);
return starCanvas.getContext('2d');
}
function setOtherReferences() {
slider = document.getElementById("rangeInput");
vBox = document.getElementById("textbox");
scaleX = 100;
scaleY = 100;
center.x = canvas.width / 3;
center.y = canvas.height / 3;
return true;
}
function drawImg() {
ctx.drawImage(starCanvas, x, y, scaleX, scaleY);
return true;
}
function Loop() {
window.setTimeout(Loop, 100);
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.drawImage(backgroundImg, 0,0);
angle += Math.PI * 0.05;
x = center.x + radius * Math.cos(angle);
y = center.y + radius * Math.sin(angle);
vBox.value = slider.value;
updateStarScale();
drawImg();
}
function getStarImages() {
//as they're all the same image, you don't need to make an array of them, simply make a loop below
var img = new Image();
img.addEventListener('load', drawBackgroundStar)
img.src = createStar();
return img;
}
function drawBackgroundStar() {
for (var i=0; i<500; i++) {
ctx.drawImage(image, getRandomArbitrary(0, canvas.width), getRandomArbitrary(0, canvas.height), getRandomArbitrary(5, 15), getRandomArbitrary(5, 15));
}
backgroundImg = new Image();
backgroundImg.addEventListener('load', Loop);
backgroundImg.src = canvas.toDataURL();
starCtx.drawImage(image, 0,0,50,50)
}
function updateStarScale() {
if (vBox.value > 0) {
scaleX += vBox.value / 10;
scaleY += vBox.value / 10;
changeImgColorToBlue();
} else if (vBox.value < 0) {
scaleX -= Math.abs(vBox.value / 10);
scaleY -= Math.abs(vBox.value / 10);
changeImgColorToRed();
}
if (scaleX > 600 || scaleY > 600) {
scaleX = 600;
scaleY = 600;
} else if (scaleX < 50 || scaleY < 50) {
scaleX = 50;
scaleY = 50;
}
}
function changeImgColorToBlue() {
imageData = starCtx.getImageData(0, 0, 50, 50);
data = imageData.data;
for (var i = 0; i < data.length; i += 4) {
//is our data black?
if(data[i]>0||data[i+1]>0||data[i+2]>0){
data[i] = 0;// red
data[i + 1] = 0; // green
data[i + 2] = 255; // blue
}
}
starCtx.putImageData(imageData, 0, 0);
}
function changeImgColorToRed() {
imageData = starCtx.getImageData(0, 0, 50, 50);
data = imageData.data;
for (var i = 0; i < data.length; i += 4) {
if(data[i]>0||data[i+1]>0||data[i+2]>0){
data[i] = 255;// red
data[i + 1] = 0; // green
data[i + 2] = 0; // blue
}
}
starCtx.putImageData(imageData, 0, 0);
}
function getRandomArbitrary(min, max) {
return Math.random() * (max - min) + min;
}
start();
body {
text-align: center;
}
#container {
position: fixed;
color: red;
top: 0px;
left: 0px;
}
#textBox {
position: absolute;
top: 25px;
left: 5px;
}
#slider {
position: absolute;
top: 25px;
left: 200px;
}
<canvas id="canvas" width="1024" height="768"></canvas>
<div id="container">
<div id="textBox">
Velocity:
<input type="text" id="textbox" value="0">
</div>
<div id="slider">
Slider:
<form oninput="amount.value=rangeInput.value">
<input type="range" id="rangeInput" name="rangeInput" min="-100" max="100" step="3" value="">
<output name="amount" for="rangeInput">0</output>
</form>
</div>
</div>

Categories