Skip to content

Added Orbs project #53

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions Orbs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# p5.Orbs
## Class Description
A class to provide a reusable waveform component, specifically a sine wave comprised of four sub-waves made of individual particles.
The wave object has properties to control its dimensions, propagation speed , frequency and the size of the particles. In addition to this the colour of each particle stream can be customised individually or all the stream colours can be randomised at once.

### Constructor
An object of the class can be created using the constructor method and providing values for the speed, num, loLimit, hiLimit, size, frequency and initial palette.
speed: float
num: int
loLimit: int
hiLimit: int
size: int
frequency: float
palette: array of four colour objects
From these attributes the remaining data values can be calculated.

## Web Page Example Description
To demonstrate my sketch I have embedded it into an html web page and have provided controls to alter the variious properties of the object.
There are sliders present to control the speed, num, size, frequency, loLimit and hiLimit properties of the waveform which is rendered to the right of the controls.
The sketch is updated in real time using the various set methods within the class and a series of elemtent listeners to trigger these changes when the user interacts with the controls.
There are four colour picker elements assigned to the four individual particle streams within the wave which may be used to alter the colours of each stream.
A button labelled randomise colours is also present to enable the user to change the colours of all four particle streams to new, random values.


### Fields
speed:
The rate at which the wave propagates across the page.

num:
The number of particles present in each stream.

loLimit:
The limit for the greatest negative amplitude.

hiLimit:
The limit for the greatest positive amplitude.

theta:
The angle by which the wave position will be incremented each page.

size:
The size of each particle.

edge:
The distance between the wave and the left and right edges of the canvas.

step:
The amount by which the x coordinate is increaesd each frame.

palette:
An array containing the colour of each particle stream.

f:
A colour variable used to store the colour of the stream currently being processed.

frequency:
The rate at which the wave oscillates.

### Methods
get:
Used to retrive the values of the speed, num, loLimit, hiLimit, size, palette and frequency attributes.
Most get methods take no parameters.
The get palette method takes a single parameter to determine which stream's colour will be returned.

set:
Used to change the values of the speed, num, loLimit, hiLimit, size, palette and frequency attributes.
Most methods take a single parameter of the new value for the attribute.
The set palette method requires two parameters: One to set which stream's colour should be altereed and the second to store the value of the desired new colour.
When changing some attributes the values of other properties must also be altered to reflec tthis change in the sketch. This is the case for the num attribute which affects the value of step which must be recalculated accordingly when the num value is set.


randomise:
This method interates through the four streams within the wave and randomises the colour of each one.
Individual values between 0 and 255 are generated for the red, green and blue components and are then converted into their corresponding hexadecimal components
For single digit values an additional 0 is added at the start to ensure the format of the colour code is correct.
These three values are then combined and a colour object is initialised using this data.
The colour of the stream's corresponding html colour picker element is then adjusted to reflect this change.
45 changes: 45 additions & 0 deletions Orbs/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<!DOCTYPE html><html><head>
<script src="http://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.6/p5.js"></script>
<script type="text/javascript" src="orbs.js"></script>
<script type="text/javascript" src="index.js"></script>
<link rel="stylesheet" type="text/css" href="style.css">
<meta charset="utf-8">
</head>
<body>
<div id="sketch-holder"> </div>
<div class="slidecontainer">
<p> <strong>Speed: </strong> <br/>
Control the rate at which the wave travels across the canvas.</p>
<input type="range" min="4" max="20" value="12" class="slider" id="slSpeed">
<p> <strong>Number: </strong> <br/>
Control the number of particles present in the wave.</p>
<input type="range" min="10" max="100" value="20" class="slider" id="slNum">
<p> <strong>Size: </strong> <br/>
Control the size of each particle within the wave.</p>
<input type="range" min="2" max="25" value="10" class="slider" id="slSize">
<p> <strong>Frequency: </strong> <br/>
Control the rate at which the wave oscillates</p>
<input type="range" min="10" max="38" value="10" class="slider" id="slFreq">
<p><strong>Amplitude:</strong></p>
<p> <strong>Top: </strong> <br/>
Control the position of the upper limit of the wave</p>
<input type="range" min="50" max="250" value="100" class="slider" id="slTop">
<p> <strong>Bottom: </strong> <br/>
Control the position of the lower limit of the wave</p>
<input type="range" min="250" max="450" value="400" class="slider" id="slBot">
</div>

<div>
<p><strong>Colour:</strong> <br/>
Edit the colour of each particle strand individually or randomise all colours.</p>
<input type="color" value="#A0ECD0" id="colour3">
<input type="color" value="#ECD893" id="colour2">
<input type="color" value="#E7AF7E" id="colour1">
<input type="color" value="#B78376" id="colour0">
</div>

<div>
<button type="button" id="randomC">Randomise Colours</button>
</div>
<a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by-sa/3.0/88x31.png" /></a><br />This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-ShareAlike 3.0 Unported License</a>.
</body></html>
94 changes: 94 additions & 0 deletions Orbs/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
var o; //Initialise variable for object of sketch
//var pg;
function setup() {
document.getElementById("colour0").value = "#A0ECD0"; //Reset colour picker values to defaults
document.getElementById("colour1").value = "#ECD893";
document.getElementById("colour2").value = "#E7AF7E";
document.getElementById("colour3").value = "#B78376";

var canvas = createCanvas(500,500);
canvas.parent("sketch-holder"); //Set parent property to enable CSS transformations to be applied to canvas
//pg = createGraphics(500, 500);
noStroke();
//Create Orbs object
o = new Orbs(120, 20, 400, 100, 10.0, PI / 3.8, [color('#A0ECD0'), color('#ECD893'), color('#E7AF7E'), color('#B78376')]);
}

function draw() {
background('#676E81');
o.draw();

}
document.addEventListener("DOMContentLoaded", function(){ //Wait for all page content to load before initialising listener functions

//Set up listener functions
var slSpeed = document.getElementById("slSpeed");
slSpeed.oninput = function() {
o.setSpeed(int(this.value) * 10);
if (o.getSpeed() == 200) //Set speed value to be such that the sketch stops moving when the slider is positioned fully to the left
o.setSpeed(10000000000000);
}

var slNum = document.getElementById("slNum");
slNum.oninput = function() {
o.setNum(this.value);

}

var slTop = document.getElementById("slTop");
slTop.oninput = function() {
o.setHiLimit(this.value);
}

var slBot = document.getElementById("slBot");
slBot.oninput = function() {
o.setLoLimit(int(this.value));
}

var slSize = document.getElementById("slSize");
slSize.oninput = function() {
o.setSize(int(this.value));
}

var slFreq = document.getElementById("slFreq");
slFreq.oninput = function() {
o.setFreq(PI / (int(this.value) / 10));
}

window.addEventListener("load", startup, false);
function startup() {
//Initialise colour picker inputs
colour0 = document.getElementById("colour0");
colour0.addEventListener("change", changeC0, false);
colour1 = document.getElementById("colour1");
colour1.addEventListener("change", changeC1, false);
colour2 = document.getElementById("colour2");
colour2.addEventListener("change", changeC2, false);
colour3 = document.getElementById("colour3");
colour3.addEventListener("change", changeC3, false);
}
//Functions for changing individual stream colours
var colour0;
function changeC0(event){
o.setPalette(0, color(this.value));
}
var colour1;
function changeC1(event){
o.setPalette(1, color(this.value));
}
var colour2;
function changeC2(event){
o.setPalette(2, color(this.value));
}
var colour3;
function changeC3(event){
o.setPalette(3, color(this.value));
}
//Initialise button listener for random colour function
var randomC = document.getElementById("randomC");
randomC.addEventListener("click", randomiseColours);
function randomiseColours(){
o.randomiseColours()
}

})
1 change: 1 addition & 0 deletions Orbs/license.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This work is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/ or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
139 changes: 139 additions & 0 deletions Orbs/orbs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@

class Orbs {
constructor(s, n, lL, hL, sz, fr, p) {
//Initialise object variables
this.speed = s;
this.num = n;
this.loLimit = lL;
this.hiLimit = hL;
this.theta = 0.0;
this.size = sz;
this.edge = 100;
this.step = (width - 2 * this.edge) / this.num;
this.palette = p;
this.f = color(0)
this.frequency = fr;
}

draw(g) {
//If a p5.renderer object is present render to this instead of the canvas
if (g) {
var i = 0;
//Each stream of particles is processed serparately
for (var j = 0; j < 4; j++) {
//Iterate through each x coordinate, rightmost coordinate determined by 401 multiplied by the frequency of the function.
//The frequency will determine how many repetitions of the wave will be compressed into the 300 pixel coordinate range
//Each loop the x coordinate will be increased by the amount step, determined by the canvas width and number of particles
for (var x = 100; x < 401 * this.frequency; x += this.step) {
//Y values follow a sine wave, giving the impression that the wave is moving across the page
var y = map(sin(j * PI / 8 + this.theta + (TWO_PI / this.num * i)), -1, 1, this.loLimit, this.hiLimit);
for (var h = 0; h < 7; h++) {
this.f = this.palette[j % 4]; //The colour of each stream is extracted from the palette array
g.fill(this.f, h * 30);
if (y >= this.hiLimit - 100 && y <= this.loLimit) //If the particle is in a valid position on the page
//As particles move up and down the page their size changes relative to their distance from the top and bottom limits
var scal = map(y, this.loLimit - 100, this.hiLimit, 1, 2.8 - h * 0.3);
g.ellipse(x / this.frequency, y, this.size * scal, this.size * scal);
}
g.fill(this.f);
g.ellipse(x / this.frequency, y, this.size, this.size); //x position must be corrected to account for wave frequency
i++;
}
}
//As the function follows a sine wave, reducing the angle by which the wave steps through each frame will appear to slow down the rate at which the wave moves across the page
this.theta += TWO_PI / this.speed;
}
else
{
var i = 0;
for (var j = 0; j < 4; j++) {
for (var x = 100; x < 401 * this.frequency; x += this.step) {
var y = map(sin(j * PI / 8 + this.theta + (TWO_PI / this.num * i)), -1, 1, this.loLimit, this.hiLimit);
for (var h = 0; h < 7; h++) {
this.f = this.palette[j % 4];
fill(this.f, h * 30);
if (y >= this.hiLimit - 100 && y <= this.loLimit)
var scal = map(y, this.loLimit - 100, this.hiLimit, 1, 2.8 - h * 0.3);
ellipse(x / this.frequency, y, this.size * scal, this.size * scal);
}
fill(this.f);
ellipse(x / this.frequency, y, this.size, this.size);
i++;
}
}
this.theta += TWO_PI / this.speed;

}

}

getSpeed() {
return this.speed;
}
setSpeed(s) {
this.speed = s;
}

getNum() {
return this.num;
}
setNum(n) {
this.num = n;
//When the number of particles is changed the step value must also be corrected to ensure that wave adjusts to this change
this.step = (width - 2 * this.edge) / this.num;
}

getHiLimit() {
return this.hiLimit;
}
setHiLimit(hL) {
this.hiLimit = hL;
}

getLoLimit() {
return this.loLimit;
}
setLoLimit(lL) {
this.loLimit = lL;
}

getSize() {
return this.size;
}
setSize(sz) {
this.size = sz;
}

getFreq() {
return this.frequency;
}
setFreq(freq) {
//In order to produce accurate waveforms the frequency must be divided by PI
this.frequency = PI / freq;
}

setPalette(i, col) {
this.palette[i] = col;
}

randomiseColours(){
//Iterate through each colour stream
for (var i = 0; i < 4; i++) {
//Result must be an integer
var r = (Math.floor((255 * Math.random()) + 1)).toString(16);
//If a single digit hex value is returned a zero must be added to ensure a 6 digit colour code is obtained
if (r.length == 1)
r = 0 + r
var g = (Math.floor((255 * Math.random()) + 1)).toString(16);
if (g.length == 1)
g = 0 + g
var b = (Math.floor((255 * Math.random()) + 1)).toString(16);
if (b.length == 1)
b = 0 + b
var c = "#" + r + g + b;
var C = color(c);
//Set stream colour
this.setPalette(i, C);
}
}
}
Loading