I wrote the following HTML5 canvas code on a text editor:
window.onload = function() {
var canvasPlanet = document.getElementById("canvasPlanet");
var contextPlanet = canvasPlanet.getContext("2d");
var canvasBG = document.getElementById("canvasBackground");
var contextBG = canvasBackground.getContext("2d");
var change = .6;
var interval = 33;
var radius = 0;
var radiusMin = 100;
var numStars1 = 2000;
var numStars2 = 400;
var numStars3 = 30;
var planetSize = 12;
var imageCount = 0;
var xPos = canvasPlanet.width / 2;
var yPos = canvasPlanet.height / 2;
var angle = 0;
var radiusMax = 175;
var colorStar1 = "white";
var colorStar2 = "gray";
var colorStar3 = "darkgray";
var sunSize = 45;
var imageQuant = 2;
contextBG.fillStyle = "black";
contextBG.fillRect(0, 0, canvasBG.width, canvasBG.height);
for (var n = 0; n < numStars1; n++) {
var xStar = Math.random() * canvasBG.width;
var yStar = Math.random() * canvasBG.height;
contextBG.fillStyle = colorStar2;
contextBG.fillRect(xStar, yStar, 1, 1);
}
for (var n = 0; n < numStars2; n++) {
var xStar = Math.random() * canvasBG.width;
var yStar = Math.random() * canvasBG.height;
contextBG.fillStyle = colorStar2;
contextBG.fillRect(xStar, yStar, 2, 2);
}
for (var n = 0; n < numStars3; n++) {
var xStar = Math.random() * canvasBG.width;
var yStar = Math.random() * canvasBG.height;
contextBG.fillStyle = colorStar3;
contextBG.fillRect(xStar, yStar, 3, 3);
}
var planet = new Image();
planet.src = "https://vignette.wikia.nocookie.net/future/images/3/34/PLANET.png/revision/latest?cb=20120319180022";
var sun = new image();
sun.src = "https://vignette.wikia.nocookie.net/vsbattles/images/c/ca/Render_sun.png/revision/latest?cb=20160310013337";
sun.onload() {
contextBG.drawImage(sun, 200, 175, sunSize, sunSize);
imageCount++;
if (imageCount == imageQuant)
{
var intervalID = setInterval(drawPlanet, interval)
}
}
planet.onload = function() {
contextPlanet.translate(xPos, yPos);
imageCount++;
if (imageCount == imageQuant)
{
var intervalID = setInterval(drawPlanet, interval)
}
}
function drawPlanet() {
contextPlanet.clearRect(-canvasPlanet.width / 2, -canvasPlanet.height / 2, canvasPlanet.width, canvasPlanet.height);
var angleR = (Math.Pi / 180) * angle;
var calcAS = radiusMax * Math.sin(angleR);
var calcBC = radiusMax * Math.cos(angleR);
radius = (radiusMax * radiusMin) / Math.sqrt((calcAS * calcAS) + (calcBC * calcBC));
contextPlanet.rotate(((Math.PI) / 180 * ) - change);
angle = angle + change;
cantextPlanet.drawImage(planet, radius, 0, planetSize, planetSize);
}
}
<div>
<canvas id="canvasPlanet" width="400" height="400" style="border:2px solid black; position:absolute;
left:auto; top:auto; z-index: 2">
Your browser doesn't currently support HTML5 Canvas.
</canvas>
<canvas id="canvasBackground" width="400" height="400" style="border:2px solid black; position:absolute;
left:auto; top:auto; z-index: 1">
Your browser doesn't currently support HTML5 Canvas.
</canvas>
</div>
The code is supposed to create an oscillating motion which displays a planet orbiting around the sun in space with lots of stars, but the canvas is not display for some reason. If anyone can tell me what i did wrong, i would appreciate it. Please and thank you,
I've updated the code to display the canvas and the objects.
window.onload = function() {
var canvasPlanet = document.getElementById("canvasPlanet");
var contextPlanet = canvasPlanet.getContext("2d");
var canvasBG = document.getElementById("canvasBackground");
var contextBG = canvasBackground.getContext("2d");
var change = .006;
var interval = 33;
var radius = 1000;
var radiusMin = 100;
var numStars1 = 2000;
var numStars2 = 400;
var numStars3 = 30;
var planetSize = 12;
var imageCount = 0;
var xPos = canvasPlanet.width/2;
var yPos = canvasPlanet.height/2;
var angle = 0;
var radiusMax = 175;
var colorStar1 = "white";
var colorStar2 = "gray";
var colorStar3 = "darkgray";
var sunSize = 45;
var imageQuant = 2;
contextBG.fillStyle = "black";
contextBG.fillRect(0, 0, canvasBG.width, canvasBG.height);
for(var n=0; n<numStars1; n++)
{
var xStar = Math.random()*canvasBG.width;
var yStar = Math.random()*canvasBG.height;
contextBG.fillStyle = colorStar2;
contextBG.fillRect(xStar, yStar, 1, 1);
}
for(var n=0; n<numStars2; n++)
{
var xStar = Math.random()*canvasBG.width;
var yStar = Math.random()*canvasBG.height;
contextBG.fillStyle = colorStar2;
contextBG.fillRect(xStar, yStar, 2, 2);
}
for(var n=0; n<numStars3; n++)
{
var xStar = Math.random()*canvasBG.width;
var yStar = Math.random()*canvasBG.height;
contextBG.fillStyle = colorStar3;
contextBG.fillRect(xStar, yStar, 3, 3);
}
var planet = new Image();
planet.src = "https://vignette.wikia.nocookie.net/future/images/3/34/PLANET.png/revision/latest?cb=20120319180022";
var sun = new Image();
sun.src = "https://vignette.wikia.nocookie.net/vsbattles/images/c/ca/Render_sun.png/revision/latest?cb=20160310013337";
sun.onload = function()
{
contextBG.drawImage(sun, 200, 175, sunSize, sunSize);
imageCount ++;
if(imageCount == imageQuant)
{var intervalID = setInterval(drawPlanet, interval)}
}
planet.onload = function ()
{
contextPlanet.translate(xPos, yPos);
imageCount ++;
if(imageCount == imageQuant)
{var intervalID = setInterval(drawPlanet, interval)}
}
function drawPlanet()
{
contextPlanet.clearRect(-canvasPlanet.width / 2, -canvasPlanet.height / 2, canvasPlanet.width, canvasPlanet.height);
var angleR = (Math.PI / 180) * angle;
var calcAS = radiusMax * Math.sin(angleR);
var calcBC = radiusMax * Math.cos(angleR);
radius = (radiusMax * radiusMin) / Math.sqrt((calcAS * calcAS) + (calcBC * calcBC));
contextPlanet.rotate(((Math.PI) / 180) - change);
angle = angle + change;
contextPlanet.drawImage(planet, radius, 0, planetSize, planetSize);
}
}
<!DOCTYPE HTML>
<html>
<head>
</head>
<body>
<div>
<canvas id ="canvasPlanet" width="400" height="400"
style ="border:2px solid black; position:absolute;
left:auto; top:auto; z-index: 2">
Your browser doesn't currently support HTML5 Canvas.
</canvas>
<canvas id ="canvasBackground" width="400" height="400"
style ="border:2px solid black; position:absolute;
left:auto; top:auto; z-index: 1">
Your browser doesn't currently support HTML5 Canvas.
</canvas>
</div>
</body>
</html>
Related
I've written this quick script for random moving lines for the background for my portfolio. It works smoothly alone but when I start working with other CSS animations and stuff, there's a frame drop at the beginning (later it runs smooth). At least on my PC, struggles on low-end PC.
Some tips to optimize it would be helpful.
Here's my code:
/*Random Line Render Script aka Mini Browser Crasher */
/*XD Can't Revise This Script. Rofl Drains Memory. May crash low-end pc :V */
var c = document.getElementById("graph");
var dimension = [document.documentElement.clientWidth, document.documentElement.clientHeight];
c.width = dimension[0];
var ctx = c.getContext("2d");
var ctx2 = c.getContext("2d");
var posx = [100, 200, 150, 100, 0];
var posy = [100, 200, 300, 100, -100];
var posx2 = [600, 400, 200, 600];
var posy2 = [500, 200, 100, 150, 500, 500];
var posx3 = [];
var posy3 = [];
/*Generate random values for array( random starting point ) */
for (var i = 0; i < 2; i++) {
posx2.push(500 + Math.round(Math.random() * 700));
posy2.push(Math.round(Math.random() * 900));
}
for (var i = 0; i < 5; i++) {
posx3.push(1000 + Math.round(Math.random() * 300));
posy3.push(0 + Math.round(Math.random() * 1000));
}
var posx_len = posx.length;
var posx2_len = posx2.length;
var posx3_len = posx3.length;
var xa, ya;
var opa = 1;
var amount = 0.01;
var sinang = 0;
var distance1 = 0;
var distance2 = 0;
document.body.addEventListener('mousemove', (function(event) {
xa = event.clientX;
ya = event.clientY;
}));
/*Render Lines */
function draw() {
ctx.clearRect(0, 0, 10000, 10000);
ctx.beginPath();
ctx.moveTo(posx[0], posy[0]);
for (var i = 0; i < posx_len; i++) {
ctx.lineTo(posx[i], posy[i]);
ctx.strokeStyle = 'rgba(255,255,255,' + opa + ')';
ctx.stroke();
ctx.arc(posx[i], posy[i], 5, 0, 2 * Math.PI, false);
}
if (opa > 1) {
amount = -0.01 * Math.random();
}
if (opa < 0) {
amount = 0.01 * Math.random();
}
opa = opa + amount;
ctx.moveTo(posx2[0], posy2[0]);
for (var i = 0; i < posx2_len; i++) {
ctx.lineTo(posx2[i], posy2[i]);
ctx.strokeStyle = 'rgba(255,255,255,' + opa + ')';
ctx.stroke();
ctx.arc(posx2[i], posy2[i], 5, 0, 2 * Math.PI, false);
}
ctx.moveTo(posx3[0], posy3[0]);
for (var i = 0; i < posx3_len; i++) {
ctx.lineTo(posx3[i], posy3[i]);
ctx.strokeStyle = 'rgba(255,255,255,' + opa + ')';
ctx.stroke();
ctx.arc(posx3[i], posy3[i], 5, 0, 2 * Math.PI, false);
}
sinang = sinang + 0.01;
/*Frame Render Ends here*/
/*Calculation for next frame*/
for (var i = 0; i < posx_len; i++) {
posx[i] = posx[i] + (Math.cos(sinang) * i) / 2; /* Sin curve for smooth value transition. Smooth assss Butter */
posy[i] = posy[i] + (Math.cos(sinang) * i) / 2;
/* Can't believe Distance Formula is useful ahaha */
distance1 = Math.sqrt(Math.pow((posx[i] - xa), 2) + Math.pow((posy[i] - ya), 2));
if (distance1 <= 500) {
ctx.moveTo(posx[i], posy[i]);
ctx.lineTo(xa, ya);
}
for (var j = 0; j < posx2_len; j++) {
distance12 = Math.sqrt(Math.pow((posx[i] - posx2[j]), 2) + Math.pow((posy[i] - posy2[j]), 2));
if (distance12 <= 500) {
ctx.moveTo(posx[i], posy[i]);
ctx.lineTo(posx2[j], posy2[j]);
}
}
for (var j = 0; j < posx3_len; j++) {
distance13 = Math.sqrt(Math.pow((posx[i] - posx3[j]), 2) + Math.pow((posy[i] - posy3[j]), 2));
if (distance13 <= 500) {
ctx.moveTo(posx[i], posy[i]);
ctx.lineTo(posx3[j], posy3[j]);
}
}
}
posx[posx.length - 1] = posx[0];
posy[posy.length - 1] = posy[0];
/*Repeat Above Steps. Should have done this in Multi-dimensional array. Ugh I feel sad now*/
for (var i = 0; i < posx2_len; i++) {
posx2[i] = posx2[i] + (Math.sin(sinang) * i) / 2;
posy2[i] = posy2[i] - (Math.sin(sinang) * i) / 2;
distance2 = Math.sqrt(Math.pow((posx2[i] - xa), 2) + Math.pow((posy2[i] - ya), 2));
if (distance2 <= 500) {
ctx.moveTo(posx2[i], posy2[i]);
ctx.lineTo(xa, ya);
}
for (var j = 0; j < posx3_len; j++) {
distance22 = Math.sqrt(Math.pow((posx2[i] - posx3[j]), 2) + Math.pow((posy2[i] - posy3[j]), 2));
if (distance22 <= 500) {
ctx.moveTo(posx2[i], posy2[i]);
ctx.lineTo(posx3[j], posy3[j]);
}
}
}
posx2[posx2.length - 1] = posx2[0];
posy2[posy2.length - 1] = posy2[0];
for (var i = 0; i < posx3_len; i++) {
posx3[i] = posx3[i] - (Math.sin(sinang) * i) / 1.2;
posy3[i] = posy3[i] - (Math.sin(sinang) * i) / 1.2;
distance2 = Math.sqrt(Math.pow((posx3[i] - xa), 2) + Math.pow((posy3[i] - ya), 2));
if (distance2 <= 500) {
ctx.moveTo(posx3[i], posy3[i]);
ctx.lineTo(xa, ya);
}
}
posx3[posx3.length - 1] = posx3[0];
posy3[posy3.length - 1] = posy3[0];
ctx.restore();
ctx.stroke();
window.requestAnimationFrame(draw);
}
window.requestAnimationFrame(draw);
body {
background: #1f1f1f;
}
<canvas height="1080px" width="1100px" id="graph">
</canvas>
So, what I've done is used square colliders instead of circular(distance formula) and it has faster runtime now. (not much but still)
<html>
<head>
</head>
<style>
body{
background: #1f1f1f;
}
canvas{
}
</style>
<body >
<canvas height="1080px" width="1100px" id="graph">
</canvas>
</body>
<script>
/*Random Line Render Script aka Mini Browser Crasher */
/*XD Can't Revise This Script. Rofl Drains Memory. May crash low-end pc :V */
var c = document.getElementById("graph");
var dimension = [document.documentElement.clientWidth, document.documentElement.clientHeight];
c.width = dimension[0];
var ctx = c.getContext("2d");
var posx = [100,200,150,100,0];
var posy = [100,200,300,100,-100];
var posx2 = [600,400,200,600];
var posy2 = [500,200,100,150,500,500];
var posx3 = [];
var posy3 = [];
/*Generate random values for array( random starting point ) */
for(var i=0; i<2;i++){
posx2.push(500+Math.round(Math.random()*700));
posy2.push(Math.round(Math.random()*900));
}
for(var i=0; i<5;i++){
posx3.push(1000+Math.round(Math.random()*300));
posy3.push(0+Math.round(Math.random()*1000));
}
var posx_len = posx.length;
var posx2_len = posx2.length;
var posx3_len = posx3.length;
var xa,ya;
var opa =1;
var amount = 0.01;
var sinang = 0;
var distance1 = 0;
var distance2 = 0;
var t1, t2;
document.body.addEventListener('mousemove', (function (event) {
xa = event.clientX;
ya = event.clientY;
}));
/*Render Lines */
function draw(){
t1 =performance.now();
ctx.clearRect(0, 0, 1920,1080);
ctx.beginPath();
ctx.moveTo(posx[0], posy[0]);
for(var i= 0; i<posx_len;i++){
ctx.lineTo(posx[i], posy[i]);
ctx.arc(posx[i],posy[i], 5, 0, 2 * Math.PI, false);
}
if(opa>1){
amount = -0.01*Math.random();
}
if(opa<0){
amount =0.01*Math.random();
}
opa =opa +amount;
ctx.moveTo(posx2[0], posy2[0]);
for(var i = 0; i<posx2_len;i++){
ctx.lineTo(posx2[i], posy2[i]);
ctx.arc(posx2[i],posy2[i], 5, 0, 2 * Math.PI, false);
}
ctx.moveTo(posx3[0], posy3[0]);
for(var i = 0; i<posx3_len;i++){
ctx.lineTo(posx3[i], posy3[i]);
ctx.arc(posx3[i],posy3[i], 5, 0, 2 * Math.PI, false);
}
sinang = sinang+0.01;
/*Frame Render Ends here*/
/*Calculation for next frame*/
for(var i = 0;i<posx_len;i++){
posx[i] = posx[i]+ (Math.cos(sinang)*i)/2;/* Sin curve for smooth value transition. Smooth assss Butter */
posy[i] = posy[i]+ (Math.cos(sinang)*i)/2;
/* Can't believe Distance Formula is useful ahaha */
if(Math.abs(posx[i]-xa)<500 && Math.abs(posy[i]-ya)<500){
ctx.moveTo(posx[i],posy[i]);
ctx.lineTo(xa, ya);
}
for(var j = 0;j<posx2_len;j++){
if(Math.abs(posx[i]-posx2[j])<500 && Math.abs(posy[i]-posy2[j])<500){
ctx.moveTo(posx[i],posy[i]);
ctx.lineTo(posx2[j], posy2[j]);
}
}
for(var j = 0;j<posx3_len;j++){
if(Math.abs(posx[i]-posx3[j])<500 && Math.abs(posy[i]-posy3[j])<500){
ctx.moveTo(posx[i],posy[i]);
ctx.lineTo(posx3[j], posy3[j]);
}
}
}
posx[posx.length-1]=posx[0];
posy[posy.length-1] = posy[0];
/*Repeat Above Steps. Should have done this in Multi-dimensional array. Ugh I feel sad now*/
for(var i = 0;i<posx2_len;i++){
posx2[i] = posx2[i]+ (Math.sin(sinang)*i)/2;
posy2[i] = posy2[i]-(Math.sin(sinang)*i)/2;
if(Math.abs(posx2[i]-xa)<500 && Math.abs(posy2[i]-ya)<500){
ctx.moveTo(posx2[i],posy2[i]);
ctx.lineTo(xa, ya);
}
for(var j = 0;j<posx3_len;j++){
if(Math.abs(posx2[i]-posx3[j])<500 && Math.abs(posy2[i]-posy3[j])<500){
ctx.moveTo(posx2[i],posy2[i]);
ctx.lineTo(posx3[j], posy3[j]);
}
}
}
posx2[posx2.length-1]=posx2[0];
posy2[posy2.length-1] = posy2[0];
for(var i = 0;i<posx3_len;i++){
posx3[i] = posx3[i]- (Math.sin(sinang)*i)/1.2;
posy3[i] = posy3[i]-(Math.sin(sinang)*i)/1.2;
if(Math.abs(posx3[i]-xa)<500 && Math.abs(posy3[i]-ya)<500){
ctx.moveTo(posx3[i],posy3[i]);
ctx.lineTo(xa, ya);
}
}
posx3[posx3.length-1]=posx3[0];
posy3[posy3.length-1] = posy3[0];
ctx.restore();
ctx.strokeStyle = 'rgba(255,255,255,'+opa+')';
ctx.stroke();
window.requestAnimationFrame(draw);
t2=performance.now();
console.log(t2-t1);
}
window.requestAnimationFrame(draw);
</script>
</html>
I have some code which works perfect from a tutorial site. It shows RSVP and updates the text when you type in the input box. This is the code working:
https://jsfiddle.net/spadez/7gyrd08w/6/
Current it works with an input box as such:
<input id="input" type="text" value="EDIT ME">
And then the following JS:
function initInput() {
input = document.getElementById('input');
input.addEventListener('keyup', updateText);
input.value = 'RSVP';
}
I wanted to change it to pull the value from the radio box when one was selected. So I changed the html to this:
<input id="input" type="radio" name="rsvp" value="Yay!">
<input id="input" type="radio" name="rsvp" value="Oh no!">
And the JavaScript to this (line 167):
function initInput() {
input = document.getElementById('input');
input.addEventListener('change', updateText);
input.value = 'RSVP';
}
However, this doesn't work, and when I select a radio box the text doesn't update. Is there any obvious reason why? This code can be seen here (not working with the radio field):
https://jsfiddle.net/spadez/7gyrd08w/7/
Use the following code. This should help you solve the problem.
var height,
width,
container,
scene,
camera,
renderer,
particles = [],
mouseVector = new THREE.Vector3(0, 0, 0),
mousePos = new THREE.Vector3(0, 0, 0),
cameraLookAt = new THREE.Vector3(0, 0, 0),
cameraTarget = new THREE.Vector3(0, 0, 800),
textCanvas,
textCtx,
textPixels = [],
input;
var colors = ['#F7A541', '#F45D4C', '#FA2E59', '#4783c3', '#9c6cb7'];
function initStage() {
width = window.innerWidth;
height = window.innerHeight;
container = document.getElementById('stage');
window.addEventListener('resize', resize);
container.addEventListener('mousemove', mousemove);
}
function initScene() {
scene = new THREE.Scene();
renderer = new THREE.WebGLRenderer({
alpha: true,
antialias: true
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(width, height);
container.appendChild(renderer.domElement);
}
function randomPos(vector) {
var radius = width * 3;
var centerX = 0;
var centerY = 0;
// ensure that p(r) ~ r instead of p(r) ~ constant
var r = width + radius * Math.random();
var angle = Math.random() * Math.PI * 2;
// compute desired coordinates
vector.x = centerX + r * Math.cos(angle);
vector.y = centerY + r * Math.sin(angle);
}
function initCamera() {
fieldOfView = 75;
aspectRatio = width / height;
nearPlane = 1;
farPlane = 3000;
camera = new THREE.PerspectiveCamera(
fieldOfView,
aspectRatio,
nearPlane,
farPlane);
camera.position.z = 800;
console.log(camera.position);
console.log(cameraTarget);
}
function createLights() {
shadowLight = new THREE.DirectionalLight(0xffffff, 2);
shadowLight.position.set(20, 0, 10);
shadowLight.castShadow = true;
shadowLight.shadowDarkness = 0.01;
scene.add(shadowLight);
light = new THREE.DirectionalLight(0xffffff, .5);
light.position.set(-20, 0, 20);
scene.add(light);
backLight = new THREE.DirectionalLight(0xffffff, 0.8);
backLight.position.set(0, 0, -20);
scene.add(backLight);
}
function Particle() {
this.vx = Math.random() * 0.05;
this.vy = Math.random() * 0.05;
}
Particle.prototype.init = function(i) {
var particle = new THREE.Object3D();
var geometryCore = new THREE.BoxGeometry(20, 20, 20);
var materialCore = new THREE.MeshLambertMaterial({
color: colors[i % colors.length],
shading: THREE.FlatShading
});
var box = new THREE.Mesh(geometryCore, materialCore);
box.geometry.__dirtyVertices = true;
box.geometry.dynamic = true;
particle.targetPosition = new THREE.Vector3((textPixels[i].x - (width / 2)) * 4, (textPixels[i].y) * 5, -10 * Math.random() + 20);
particle.position.set(width * 0.5, height * 0.5, -10 * Math.random() + 20);
randomPos(particle.position);
for (var i = 0; i < box.geometry.vertices.length; i++) {
box.geometry.vertices[i].x += -10 + Math.random() * 20;
box.geometry.vertices[i].y += -10 + Math.random() * 20;
box.geometry.vertices[i].z += -10 + Math.random() * 20;
}
particle.add(box);
this.particle = particle;
}
Particle.prototype.updateRotation = function() {
this.particle.rotation.x += this.vx;
this.particle.rotation.y += this.vy;
}
Particle.prototype.updatePosition = function() {
this.particle.position.lerp(this.particle.targetPosition, 0.02);
}
function render() {
renderer.render(scene, camera);
}
function updateParticles() {
for (var i = 0, l = particles.length; i < l; i++) {
particles[i].updateRotation();
particles[i].updatePosition();
}
}
function setParticles() {
for (var i = 0; i < textPixels.length; i++) {
if (particles[i]) {
particles[i].particle.targetPosition.x = (textPixels[i].x - (width / 2)) * 4;
particles[i].particle.targetPosition.y = (textPixels[i].y) * 5;
particles[i].particle.targetPosition.z = -10 * Math.random() + 20;
} else {
var p = new Particle();
p.init(i);
scene.add(p.particle);
particles[i] = p;
}
}
for (var i = textPixels.length; i < particles.length; i++) {
randomPos(particles[i].particle.targetPosition);
}
}
function initCanvas() {
textCanvas = document.getElementById('text');
textCanvas.style.width = width + 'px';
textCanvas.style.height = 200 + 'px';
textCanvas.width = width;
textCanvas.height = 200;
textCtx = textCanvas.getContext('2d');
textCtx.font = '700 100px Arial';
textCtx.fillStyle = '#555';
}
//function initInput() {
// input = document.getElementById('input');
// input.addEventListener('keyup', updateText);
// input.value = 'RSVP';
//}
function initInput() {
radios = document.getElementsByName('rsvp');
for (radio in radios) {
(radios[radio]).onclick = updateText;
}
//input.value = 'RSVP';
}
function updateText() {
var value = (this.value != undefined) ? this.value : '';
var fontSize = (width / (value * 1.3));
if (fontSize > 120) fontSize = 120;
textCtx.font = '700 ' + fontSize + 'px Arial';
textCtx.clearRect(0, 0, width, 200);
textCtx.textAlign = 'center';
textCtx.textBaseline = "middle";
textCtx.fillText(value.toUpperCase(), width / 2, 50);
var pix = textCtx.getImageData(0, 0, width, 200).data;
textPixels = [];
for (var i = pix.length; i >= 0; i -= 4) {
if (pix[i] != 0) {
var x = (i / 4) % width;
var y = Math.floor(Math.floor(i / width) / 4);
if ((x && x % 6 == 0) && (y && y % 6 == 0)) textPixels.push({
x: x,
y: 200 - y + -120
});
}
}
setParticles();
}
function animate() {
requestAnimationFrame(animate);
updateParticles();
camera.position.lerp(cameraTarget, 0.2);
camera.lookAt(cameraLookAt);
render();
}
function resize() {
width = window.innerWidth;
height = window.innerHeight;
camera.aspect = width / height;
camera.updateProjectionMatrix();
renderer.setSize(width, height);
textCanvas.style.width = width + 'px';
textCanvas.style.height = 200 + 'px';
textCanvas.width = width;
textCanvas.height = 200;
updateText();
}
function mousemove(e) {
//var x = e.pageX - width/2;
//var y = e.pageY - height/2;
//cameraTarget.x = x*-1;
//cameraTarget.y = y;
}
initStage();
initScene();
initCanvas();
initCamera();
createLights();
initInput();
animate();
setTimeout(function() {
updateText();
}, 40);
body {
overflow: hidden;
}
div,
canvas {
position: absolute;
}
#text {
z-index: 200;
display: none;
}
form {
z-index: 400;
position: absolute;
text-transform: uppercase;
font-size: 30px;
color: #222;
font-weight: bold;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r71/three.min.js"></script>
<div id="stage"></div>
<canvas id="text" width="700" height="150"></canvas>
<form>
<!--<input id="input" type="text" value="EDIT ME">-->
<input id="input" type="radio" name="rsvp" value="Yay!">
<input id="input" type="radio" name="rsvp" value="Oh no!">
</form>
The Problem
I am creating a game where you have to move away from or dodge projectiles coming towards you, I have enabled the user to move the image they are controlling but at the moment the user can place the image anywhere on the canvas.
The Question
How can I only allow the user to move along designated part of the canvas and only along the X axis? for example:
Here is my game, "working progress":
The user is in control of the ship, they should only be able to move left or right like this for example:
The Code
<script>
var game = create_game();
game.init();
//music
var snd = new Audio("menu.mp3");
snd.play();
document.getElementById('mute').addEventListener('click', function (evt) {
if ( snd.muted ) {
snd.muted = false
evt.target.innerHTML = 'mute'
}
else {
snd.muted = true
evt.target.innerHTML = 'unmute'
}
})
function create_game() {
debugger;
var level = 1;
var projectiles_per_level = 1;
var min_speed_per_level = 1;
var max_speed_per_level = 2;
var last_projectile_time = 0;
var next_projectile_time = 0;
var width = 600;
var height = 500;
var delay = 1000;
var item_width = 30;
var item_height = 30;
var total_projectiles = 0;
var projectile_img = new Image();
var projectile_w = 30;
var projectile_h = 30;
var player_img = new Image();
var c, ctx;
var projectiles = [];
var player = {
x: 200,
y: 400,
score: 0
};
function init() {
projectile_img.src = "apple.png";
player_img.src = "basket.png";
level = 1;
total_projectiles = 0;
projectiles = [];
c = document.getElementById("c");
ctx = c.getContext("2d");
ctx.fillStyle = "#ff6600";
ctx.fillRect(0, 0, 500, 600);
c.addEventListener("mousemove", function (e) {
//moving over the canvas.
var bounding_box = c.getBoundingClientRect();
player.x = (e.clientX - bounding_box.left) * (c.width / bounding_box.width) - player_img.width / 2;
player.y = (e.clientY - bounding_box.top) * (c.height / bounding_box.height) - player_img.height / 2;
}, false);
setupProjectiles();
requestAnimationFrame(tick);
}
function setupProjectiles() {
var max_projectiles = level * projectiles_per_level;
while (projectiles.length < max_projectiles) {
initProjectile(projectiles.length);
}
}
function initProjectile(index) {
var max_speed = max_speed_per_level * level;
var min_speed = min_speed_per_level * level;
projectiles[index] = {
x: Math.round(Math.random() * (width - 2 * projectile_w)) + projectile_w,
y: -projectile_h,
v: Math.round(Math.random() * (max_speed - min_speed)) + min_speed,
delay: Date.now() + Math.random() * delay
}
total_projectiles++;
}
function collision(projectile) {
if (projectile.y + projectile_img.height < player.y + 74) {
return false;
}
if (projectile.y > player.y + 74) {
return false;
}
if (projectile.x + projectile_img.width < player.x + 177) {
return false;
}
if (projectile.x > player.x + 177) {
return false;
}
return true;
}
function maybeIncreaseDifficulty() {
level = Math.max(1, Math.ceil(player.score / 10));
setupProjectiles();
}
function tick() {
var i;
var projectile;
var dateNow = Date.now();
c.width = c.width;
for (i = 0; i < projectiles.length; i++) {
projectile = projectiles[i];
if (dateNow > projectile.delay) {
projectile.y += projectile.v;
if (collision(projectile)) {
initProjectile(i);
player.score++;
} else if (projectile.y > height) {
initProjectile(i);
} else {
ctx.drawImage(projectile_img, projectile.x, projectile.y);
}
}
}
ctx.font = "bold 24px sans-serif";
ctx.fillStyle = "#ff6600";
ctx.fillText(player.score, c.width - 50, 50);
ctx.fillText("Level: " + level, 20, 50);
ctx.drawImage(player_img, player.x, player.y);
maybeIncreaseDifficulty();
requestAnimationFrame(tick);
}
return {
init: init
};
}
</script>
JSFiddle (Broken)
https://jsfiddle.net/3oc4jsf6/10/
If your ship is tied to mouse movement, and you want to only allow movement across the X-axis you can simply avoid changing its .y property in your mousemove listener.
Remove this line:
player.y = (e.clientY - bounding_box.top) * (c.height / bounding_box.height) - player_img.height / 2;
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>
particlesDepthBlur isn't working?
<canvas id="canvas"></canvas>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
var num = 20000;
var canvas = document.getElementById("canvas");
var width = canvas.width = 960;
var height = canvas.height = 500;
var ctx = canvas.getContext("2d");
var particles = d3.range(num).map(function(i) {
return [Math.round(width*Math.random()), Math.round(height*Math.random())];
});
var particlesDepthBlur = (function() { Math.random();})();
d3.timer(step);
function step() {
ctx.fillStyle = "rgba(0,0,0,1)";
ctx.fillRect(0,0,width,height);
ctx.fillStyle = "rgba(255,255,255,particlesDepthBlur)";
particles.forEach(function(p) {
p[0] += Math.round(2*Math.random()-1);
p[1] += Math.round(2*Math.random()-1) + 2;
if (p[0] < 0) p[0] = width;
if (p[0] > width) p[0] = 0;
if (p[1] < 0) p[1] = height;
if (p[1] > height) p[1] = 0;
drawPoint(p);
});
};
function drawPoint(p) {
ctx.fillRect(p[0],p[1],1,1);
};
</script>
<style>
html, body { margin: 0; padding: 0; }
</style>
var particlesDepthBlur = function() {
return Math.random();
};
ctx.fillStyle = "rgba(255,255,255," + particlesDepthBlur() + ")";