Mark Mo
Mark Mo

Reputation: 55

How to change the color of this (pure js)?

I am attempting to implement this mousefollow into my website:

http://codepen.io/hakimel/pen/KanIi

But I would like my own custom colors instead of what is default displayed. I changed the fillcolor value and was able to change to one specific color but I would like 4 different colors. So I have tried adding specific colors to this function next to fillColor: but no such luck. I also created a fillcolor2: property like:

    for (var i = 0; i < QUANTITY; i++) {
    var particle = {
        size: 1,
        position: { x: mouseX, y: mouseY },
        offset: { x: 0, y: 0 },
        shift: { x: mouseX, y: mouseY },
        speed: 0.01+Math.random()*0.04,
        targetSize: 1,
        fillColor: '#bf3e27',
        fillColor2: '#1c305c',
        orbit: RADIUS*.1 + (RADIUS * .5 * Math.random())
    };

and added:

    context.fillStyle = particle.fillColor2;
    context.strokeStyle = particle.fillColor2;

But that did not work either. I have also tried to copy and paste the same js code just to see if it would work, and just changed the fillcolor, but it would only display the last one pasted.

Can anyone show me how to get 4 separate colors the easiest way, I feel like I am vastly over-complicating this but obviously a beginner and getting rather frustrated with this?

Lastly, I would like the 4 different colors to span different radii and I messed around with the different RADIUS variables but it is pretty much impossible to figure out how to accomplish what I would like while only having one color. So there will be 4 of each color, I changed the QUANTITY to:

var QUANTITY = 16;

I need the first 4 colors radius of 10 so for the first one I set:

var RADIUS = 10;

Ideally I need the first 4 to be color (#AAAAAA) radius of 10 like it is, but need the second 4 to be color (#BBBBBBB) between radius 10 and 30, the third color (#CCCCCC) to be between radius of 30-50, and the last fourth color (#DDDDDD) to be between 50 and 70.

Any suggestions?

Upvotes: 4

Views: 162

Answers (3)

trincot
trincot

Reputation: 350760

You could replace the definition of QUANTITY, COLOR and RADIUS with an array of these, and at the same time define ranges for RADIUS:

var GROUPS = [
    {
        QUANTITY: 4,
        RADIUS: [ 5, 10],
        COLOR: 0x888888
    },
    {
        QUANTITY: 4,
        RADIUS: [10, 30],
        COLOR: 0xAA80AA
    },
    {
        QUANTITY: 4,
        RADIUS: [30, 50],
        COLOR: 0xA0A0CC
    },
    {
        QUANTITY: 4,
        RADIUS: [50, 70],
        COLOR: 0xFFE0E0
    }
];

Then inside the createParticles function you would iterate over those GROUPS:

for (var g = 0; g < GROUPS.length; g++) {
    var attribs = GROUPS[g];
    for (var i = 0; i < attribs.QUANTITY; i++) {
        var particle = {
            size: 1,
            position: { x: mouseX, y: mouseY },
            offset: { x: 0, y: 0 },
            shift: { x: mouseX, y: mouseY },
            speed: 0.01+Math.random()*0.04,
            targetSize: 1,
            fillColor: '#' + attribs.COLOR.toString(16),
            orbit: attribs.RADIUS[0] + 
                   (attribs.RADIUS[1]-attribs.RADIUS[0]) * Math.random()
        };

        particles.push( particle );
    }
}

Here is a snippet:

// One of my first <canvas> experiments, woop! :D 

var SCREEN_WIDTH = window.innerWidth;
var SCREEN_HEIGHT = window.innerHeight;

var GROUPS = [
    {
        QUANTITY: 4,
        RADIUS: [ 5, 10],
        COLOR: 0x888888
    },
    {
        QUANTITY: 4,
        RADIUS: [10, 30],
        COLOR: 0xAA80AA
    },
    {
        QUANTITY: 4,
        RADIUS: [30, 50],
        COLOR: 0xA0A0CC
    },
    {
        QUANTITY: 4,
        RADIUS: [50, 70],
        COLOR: 0xFFE0E0
    }
];

var RADIUS_SCALE = 1;
var RADIUS_SCALE_MIN = 1;
var RADIUS_SCALE_MAX = 1.5;

var canvas;
var context;
var particles;

var mouseX = SCREEN_WIDTH * 0.5;
var mouseY = SCREEN_HEIGHT * 0.5;
var mouseIsDown = false;

function init() {

  canvas = document.getElementById( 'world' );
  
  if (canvas && canvas.getContext) {
		context = canvas.getContext('2d');
		
		// Register event listeners
		window.addEventListener('mousemove', documentMouseMoveHandler, false);
		window.addEventListener('mousedown', documentMouseDownHandler, false);
		window.addEventListener('mouseup', documentMouseUpHandler, false);
		document.addEventListener('touchstart', documentTouchStartHandler, false);
		document.addEventListener('touchmove', documentTouchMoveHandler, false);
		window.addEventListener('resize', windowResizeHandler, false);
		
		createParticles();
		
		windowResizeHandler();
		
		setInterval( loop, 1000 / 60 );
	}
}

function createParticles() {
	particles = [];
	
	for (var g = 0; g < GROUPS.length; g++) {
	    var attribs = GROUPS[g];
	    for (var i = 0; i < attribs.QUANTITY; i++) {
		    var particle = {
			    size: 1,
			    position: { x: mouseX, y: mouseY },
			    offset: { x: 0, y: 0 },
			    shift: { x: mouseX, y: mouseY },
			    speed: 0.01+Math.random()*0.04,
			    targetSize: 1,
			    fillColor: '#' + attribs.COLOR.toString(16),
			    orbit: attribs.RADIUS[0] + 
			           (attribs.RADIUS[1]-attribs.RADIUS[0]) * Math.random()
		    };
		
		    particles.push( particle );
	    }
	}
}

function documentMouseMoveHandler(event) {
	mouseX = event.clientX - (window.innerWidth - SCREEN_WIDTH) * .5;
	mouseY = event.clientY - (window.innerHeight - SCREEN_HEIGHT) * .5;
}

function documentMouseDownHandler(event) {
	mouseIsDown = true;
}

function documentMouseUpHandler(event) {
	mouseIsDown = false;
}

function documentTouchStartHandler(event) {
	if(event.touches.length == 1) {
		event.preventDefault();

		mouseX = event.touches[0].pageX - (window.innerWidth - SCREEN_WIDTH) * .5;;
		mouseY = event.touches[0].pageY - (window.innerHeight - SCREEN_HEIGHT) * .5;
	}
}

function documentTouchMoveHandler(event) {
	if(event.touches.length == 1) {
		event.preventDefault();

		mouseX = event.touches[0].pageX - (window.innerWidth - SCREEN_WIDTH) * .5;;
		mouseY = event.touches[0].pageY - (window.innerHeight - SCREEN_HEIGHT) * .5;
	}
}

function windowResizeHandler() {
	SCREEN_WIDTH = window.innerWidth;
	SCREEN_HEIGHT = window.innerHeight;
	
	canvas.width = SCREEN_WIDTH;
	canvas.height = SCREEN_HEIGHT;
}

function loop() {
	
	if( mouseIsDown ) {
		RADIUS_SCALE += ( RADIUS_SCALE_MAX - RADIUS_SCALE ) * (0.02);
	}
	else {
		RADIUS_SCALE -= ( RADIUS_SCALE - RADIUS_SCALE_MIN ) * (0.02);
	}
	
	RADIUS_SCALE = Math.min( RADIUS_SCALE, RADIUS_SCALE_MAX );
	
	context.fillStyle = 'rgba(0,0,0,0.05)';
		 context.fillRect(0, 0, context.canvas.width, context.canvas.height);
	
	for (i = 0, len = particles.length; i < len; i++) {
		var particle = particles[i];
		
		var lp = { x: particle.position.x, y: particle.position.y };
		
		// Rotation
		particle.offset.x += particle.speed;
		particle.offset.y += particle.speed;
		
		// Follow mouse with some lag
		particle.shift.x += ( mouseX - particle.shift.x) * (particle.speed);
		particle.shift.y += ( mouseY - particle.shift.y) * (particle.speed);
		
		// Apply position
		particle.position.x = particle.shift.x + Math.cos(i + particle.offset.x) * (particle.orbit*RADIUS_SCALE);
		particle.position.y = particle.shift.y + Math.sin(i + particle.offset.y) * (particle.orbit*RADIUS_SCALE);
		
		// Limit to screen bounds
		particle.position.x = Math.max( Math.min( particle.position.x, SCREEN_WIDTH ), 0 );
		particle.position.y = Math.max( Math.min( particle.position.y, SCREEN_HEIGHT ), 0 );
		
		particle.size += ( particle.targetSize - particle.size ) * 0.05;
		
		if( Math.round( particle.size ) == Math.round( particle.targetSize ) ) {
			particle.targetSize = 1 + Math.random() * 7;
		}
		
		context.beginPath();
		context.fillStyle = particle.fillColor;
		context.strokeStyle = particle.fillColor;
		context.lineWidth = particle.size;
		context.moveTo(lp.x, lp.y);
		context.lineTo(particle.position.x, particle.position.y);
		context.stroke();
		context.arc(particle.position.x, particle.position.y, particle.size/2, 0, Math.PI*2, true);
		context.fill();
	}
}

window.onload = init;
body { 
  background-color: #000000; 
  padding: 0; 
  margin: 0; 
  overflow: hidden;
}
<canvas id='world'></canvas>

Upvotes: 3

Jasper
Jasper

Reputation: 833

You could define the colors in an array since you are using a for loop you can index them like this:

var colors = ['#AAAAAA', '#BBBBBB', '#CCCCCC', '#DDDDDD'];
var particle = {
   ...
   fillColor: colors[i],
   ...
}

This will now only work for the first four colors, but since you stated you have a quantity of 16, you could use 2 for loops to achieve this. Something like this:

//will run 16 times
for(var i = 0; i < QUANTITY; i++) {
    for(var x = 0; x < 4; x++) {
        var particle = {
            //note that i'm using x here since the array has only 4 keys.
            fillColor: colors[x];
        }
    }
}

Upvotes: 0

Andreas
Andreas

Reputation: 21911

Define the settings for the particles in an array

// I've changed the color for better visibility
var ParticleSettings = [
  {color: "#f00", radiusMin: 10, radiusMax: 10},
  {color: "#0f0", radiusMin: 10, radiusMax: 30},
  {color: "#00f", radiusMin: 30, radiusMax: 50}
];

To get the correct settings for a particle (in this case its index) use this function

function getParticleSettings(particleIndex) {
  var settingsIndex = Math.floor(particleIndex / 4) % ParticleSettings.length,
      settings = ParticleSettings[settingsIndex];

  return {
    color: settings.color,
    radius: getRandom(settings.radiusMin, settings.radiusMax)
  };
}

getRandom is just a small helper function to get a random number between two boundaries

function getRandom(min, max) {
  return Math.floor((Math.random() * (max - min)) + min)
}

In createParticle we then have to change the for loop to get the settings for the current particle

for (var i = 0; i < QUANTITY; i++) {
    // get the settings for the current particle
    var particleSettings = getParticleSettings(i);

    var particle = {
        size: 1,
        position: { x: mouseX, y: mouseY },
        offset: { x: 0, y: 0 },
        shift: { x: mouseX, y: mouseY },
        speed: 0.01+Math.random()*0.04,
        targetSize: 1,
        fillColor: particleSettings.color,    // <--
        orbit: particleSettings.radius        // <--
    };

    particles.push( particle );
}

This would be the result of the changes above.

Upvotes: 3

Related Questions