Jessica Timczyk – Project 12 – Project Proposal

My sketch of my project.

For my final project, I would like to create an interactive animation. As I drew in my sketch of my final project, I would like to create a jungle- like scene with elephants, fish and possibly another animal. To make it interactive, many aspects of the photo will move or change in some way when the user clicks on them, for example, clicking on the elephants makes them either raise their trunk or move their ears, the leaves of the trees rustle, the fish fins move when they’re clicked, and etc. Some of the interaction will also depend on the movements of the user’s mouse rather than simply a click, for example, the sun will rotate and the rays will change size as the mouse moves across the screen, or the cattails will move when the mouse grazes over them. To additionally make it interesting, I will include sounds with the scene, making jungle-esque music play in the background, but then depending on what is clicked on, different sounds will play. Elephants will make their horn sounds when clicked on, leaves rustling and others. I hope to add a few more details than what is just on the drawing, but that is the basis for now.

Jessica Timczyk – Looking Outwards 12

A screenshot from the 3D interactive doodle
A screenshot of the first shot of Solace, an interactive animation.

In preparation for making my own final project, which will be an interactive animation, I researched some other interactive animations and found these two very interesting projects. The first project is a VR and 3D interactive animated doodle by Fx Goby and Google Doodle artist Hélène Leroux made in 2018, in tribute to filmmaker Georges Méliès called ‘Back to the Moon‘. The doodle allows the viewer to move around and look at the animated environment in 360 degrees. The second project, called ‘Solace’ is also an interactive film created in 2017 by Evan Boehm and Jeff Noon in collaboration with Nexus Interactive Studios. The project takes the viewer through a narrated story in which the viewer can interact with almost all of the shapes and pictures making up the story with their mouse. Unlike the first interactive animation, ‘Solace‘ allows the viewer to actually interact with the images and shapes that make up the characters and etc of the story, whereas ‘Back to the Moon’ only allows the viewer to move around in the frame. Though I really enjoy the interactivity of ‘Solace’, I think I personally am partial to the 3D environment of ‘Back to the Moon’ and also the story line that accompanies it. I think that ‘Back to the Moon’, though very innovative in itself, missed an opportunity to make the actual story line and images interactive. Overall, I very much enjoyed both. You can play with both of them in the link or video below.

 

John Legelis – Final Project Proposal

The goal for my final project is to make an oscillator/synthesizer with a record and playback function. The user interface will resemble the following sketch.

The components of this software are a keyboard as well as a drum machine. I will aim to automatically quantize the rhythms in order to give the playback a better sound and buff out difficulty with keyboard delay etc.

The keyboard functionality will be linked to actual keys on the computer of the user and the pitch bend function will be actuated by the mouse. The drum pad will be actuated in a similar way to the keyboard with the number keys. I am a bit apprehensive about all the levels of interaction the user is intended to have in the end in terms of clickable buttons etc. I hope this product will be fully functional as a fun musical instrument.

Lan Wei-Looking Outwards-12

The project ‘Rotary tumble’ was created by Muharrem Yildirim and David Tinapple in 2012. The amazing part of the project is that both human action and physical principles are integrated into it. The blurring boundary of the physical world and the virtual world is also one idea that I want to achieve in my final project. In addition, the use of sound in the project also strengthens the visual effect. Thinking about how to improve the project, I feel it’s even better to make the screen touchable, meaning that people can move the shapes with their hands, and more sound effects can be added.

The second project is Dream Catcher created by Oggy (full name and date unknown). The amazing beauty of processing can be fully seen in this project. The common feature of this project with the first one and also what interests me the most is that they both imitate natural principles, which in this one is the flow of wind. What I feel missing in the project is sound. Compared to the first one, this one can be seen both as an interactive project and merely a visual project. But both of the projects are very inspiring to my final project.

Looking Outwards 12, John Legelis

The MiniMoog and the Casio VL-1 are two synthesizers from the 1970’s. The MiniMoog is an analog synthesizer while the Casio VL-1 is a digital synthesizer. They are both some of the first of their respective kinds. The MiniMoog was a instrument that became an instant success and was used by well known performers of every genre and defined the sound of an era. The VL-1 on the other hand was developed 9 years after the MiniMoog. By this time, synthesizers were less novel and were ready to enter the consumer market and Casio decided to develop a product to fill this market. The VL-1, unlike the MiniMoog, was digital and therefore was not competitive with the MiniMoog. Instead the VL-1 synthesizer took advantage of developments in computing with digital synthesis that allowed miniaturization and portability. Some argue that the Casio product is moreso a toy rather than a practical instrument.

The MiniMoog (left) and the Casio VL-1 (right)

For my final project I am aiming to emulate something of the nature of these instruments, I think it is likely that I will end up creating something closer to the toy-like  LV-1 rather than the professional revolutionary MiniMoog

Jessica Timczyk – Project 11

sketch

// Jessica Timczyk
// Section D
// jtimczyk@andrew.cmu.edu
// Project-

var turtle 

function setup() {
    createCanvas(480, 480);
    background(0);

    frameRate(10);
}


function draw() { 
    turtle = makeTurtle(mouseX, mouseY); // make turtle variables
    angle = turtle.angleTo(mouseX, mouseY);
    turtle.right(angle);
    turtle.forward(40);

   
    turtle.setWeight(6) // setting the specifications for the turtles lines
    strokeJoin(MITER);
    strokeCap(PROJECT);
    turtle.setColor(random(255)); //random colors

   
      turtle.penDown(); // make swirl shape
        turtle.forward(3);
        turtle.left(90);
        turtle.forward(50);
        turtle.right(90);
        turtle.forward(50);
        turtle.right(90);
        turtle.forward(37.5);
        turtle.right(90);
        turtle.forward(25);
        turtle.right(90);
        turtle.forward(12.5);
        turtle.right(90);
        turtle.forward(12.5);
        turtle.left(90);
        turtle.forward(12.5);
        turtle.left(90);
        turtle.forward(25);
        turtle.left(90);
        turtle.forward(37.5);
        turtle.left(90);
        turtle.forward(47);
        turtle.goto(mouseX,mouseY);



}

function turtleLeft(d) {
    this.angle -= d;
}


function turtleRight(d) {
    this.angle += d;
}


function turtleForward(p) {
    var rad = radians(this.angle);
    var newx = this.x + cos(rad) * p;
    var newy = this.y + sin(rad) * p;
    this.goto(newx, newy);
}


function turtleBack(p) {
    this.forward(-p);
}


function turtlePenDown() {
    this.penIsDown = true;
}


function turtlePenUp() {
    this.penIsDown = false;
}


function turtleGoTo(x, y) {
    if (this.penIsDown) {
      stroke(this.color);
      strokeWeight(this.weight);
      line(this.x, this.y, x, y);
    }
    this.x = x;
    this.y = y;
}


function turtleDistTo(x, y) {
    return sqrt(sq(this.x - x) + sq(this.y - y));
}


function turtleAngleTo(x, y) {
    var absAngle = degrees(atan2(y - this.y, x - this.x));
    var angle = ((absAngle - this.angle) + 360) % 360.0;
    return angle;
}


function turtleTurnToward(x, y, d) {
    var angle = this.angleTo(x, y);
    if (angle < 180) {
        this.angle += d;
    } else {
        this.angle -= d;
    }
}


function turtleSetColor(c) {
    this.color = c;
}


function turtleSetWeight(w) {
    this.weight = w;
}


function turtleFace(angle) {
    this.angle = angle;
}


function makeTurtle(tx, ty) {
    var turtle = {x: tx, y: ty,
                  angle: 0.0, 
                  penIsDown: true,
                  color: color(128),
                  weight: 1,
                  left: turtleLeft, right: turtleRight,
                  forward: turtleForward, back: turtleBack,
                  penDown: turtlePenDown, penUp: turtlePenUp,
                  goto: turtleGoTo, angleto: turtleAngleTo,
                  turnToward: turtleTurnToward,
                  distanceTo: turtleDistTo, angleTo: turtleAngleTo,
                  setColor: turtleSetColor, setWeight: turtleSetWeight,
                  face: turtleFace};
    return turtle;
}

I really enjoyed doing this project. I had originally intended for the swirls to make a continuous line across the screen but after multiple tries I couldn’t seem to get them to follow each other. I think using turtle to create visuals is very fun and makes it a lot easier because it allows me to create individual shapes and patterns, like these swirls that can be moved all together without having to individually put in each value. next time I would like to try to figure out to create these patterns but have them be all connected with each other in a nice line.

Project 11 – Turtle Freestyle – John Legelis

sketch

// John Legelis
// Section D


var t // turtle
var yF = 273// Winning Y value
var w // State of play (Play, Win, or Lose)
var s // osilator incriment

//load background image
function preload() {
    maze = loadImage("https://i.imgur.com/OPGsUjg.png")
}

function setup() {
    createCanvas(400, 300);
    background(0);
    image(maze,0,0)
    
    fill(0,255,0)
    noStroke()
    rectMode(CORNER)
    rect(361, yF, 33,10)

    // initialize t
    t = makeTurtle(20,0)
    t.setWeight(4)
    mouseX = 20
    mouseY = 1 
    s = 0
    w = 0
    yF = 263
}

function draw() {
    //Oscilate between colors at winning and loosing screens
    s = s + 1
    if (s % 3 == 1){
        var lcol = [255,255,255]
        var wcol = [0,255,0]
    }
    else {
        var lcol = [255,0,0]
        var wcol = [255,255,255]
    }

    // retrive brightness at turtle location
    var p = maze.get(t.x, t.y)
    var Tbright = brightness(p)
    // If in "play" mode, move turtle towards the mouse
    if (w == 0) {
        theta = t.angleTo(mouseX, mouseY)
        t.right(theta)
        t.forward(1)
    }


    //if hit wall, lost
    if (Tbright < 100){
        w = -1
    }
    // if below "win line", won
    if (t.y > yF) {
        w = 1
    }
   
    // if lost...
    if (w == -1){
        background(lcol)
        stroke(255)
        textSize(50)
        text("G A M E O V E R", 10, 150)
        textSize(25)
        text("mouse in box to restart", 40, 30)
        noStroke()
        fill(0)
        rectMode(CENTER)
        rect(25,25, 10,10)
    }
    //if won...
    if (w == 1){
        background(wcol)
        stroke(255)
        textSize(50)
        text("! Y O U W O N !", 10, 150)
        stroke(255)
        textSize(25)
        text("mouse in box to restart", 40, 30)
        noStroke()
        fill(0)
        rectMode(CENTER)
        rect(25,25, 10,10)
    }

    //If lost or won and mouse is in box initialize and go back to "play" mode
    if (((w==-1) || w==1) & (mouseX > 25 - 10) && (mouseX < 25 + 10) && 
    (mouseY > 25 - 10) && (mouseY < 25 + 10)) {
        w = 0
        setup()
    }

    if (mouseIsPressed){
        w = 1
    }
}


function turtleLeft(d) {
    this.angle -= d;
}


function turtleRight(d) {
    this.angle += d;
}


function turtleForward(p) {
    var rad = radians(this.angle);
    var newx = this.x + cos(rad) * p;
    var newy = this.y + sin(rad) * p;
    this.goto(newx, newy);
}


function turtleBack(p) {
    this.forward(-p);
}


function turtlePenDown() {
    this.penIsDown = true;
}


function turtlePenUp() {
    this.penIsDown = false;
}


function turtleGoTo(x, y) {
    if (this.penIsDown) {
      stroke(this.color);
      strokeWeight(this.weight);
      line(this.x, this.y, x, y);
    }
    this.x = x;
    this.y = y;
}


function turtleDistTo(x, y) {
    return sqrt(sq(this.x - x) + sq(this.y - y));
}


function turtleAngleTo(x, y) {
    var absAngle = degrees(atan2(y - this.y, x - this.x));
    var angle = ((absAngle - this.angle) + 360) % 360.0;
    return angle;
}


function turtleTurnToward(x, y, d) {
    var angle = this.angleTo(x, y);
    if (angle < 180) {
        this.angle += d;
    } else {
        this.angle -= d;
    }
}


function turtleSetColor(c) {
    this.color = c;
}


function turtleSetWeight(w) {
    this.weight = w;
}


function turtleFace(angle) {
    this.angle = angle;
}


function makeTurtle(tx, ty) {
    var turtle = {x: tx, y: ty,
                  angle: 0.0, 
                  penIsDown: true,
                  color: color(128),
                  weight: 1,
                  left: turtleLeft, right: turtleRight,
                  forward: turtleForward, back: turtleBack,
                  penDown: turtlePenDown, penUp: turtlePenUp,
                  goto: turtleGoTo, angleto: turtleAngleTo,
                  turnToward: turtleTurnToward,
                  distanceTo: turtleDistTo, angleTo: turtleAngleTo,
                  setColor: turtleSetColor, setWeight: turtleSetWeight,
                  face: turtleFace};
    return turtle;
}

When approaching this project I had an idea instantly to use the turtle to make some sort of maze game. Given our recent experience in using brightness and get image I was able to analyze a maze image and detect the walls very efficiently. I polished the game with a win and lose screen and a quick restart function based on mouse position.

Han Yu Project 11 Composition

click on Canvas to make spirals!

sketch

// Han Yu
// Section D
// hyu1@andrew.cmu.edu
// Project 11 Compostion

var ttl;

function setup() {
    createCanvas(400, 400);
    background(255, 200, 200);
    ttl = makeTurtle(width/2, height/2);
    ttl.setColor(255);
    ttl.setWeight(2);
    ttl.penDown();
    frameRate(50);
}

function draw() {
	var step = (frameCount/150);
	ttl.forward(step);
	ttl.left(5);
}

function mousePressed() {
	ttl = makeTurtle(mouseX, mouseY);
	var c = [255, 'purple', 255, 155]; //maximize the chances of getting a white stroke
	ttl.setColor(c[floor(random(0,4))]);
	ttl.setWeight((random(0,2)));

}

function turtleLeft(d){this.angle-=d;}function turtleRight(d){this.angle+=d;}
function turtleForward(p){var rad=radians(this.angle);var newx=this.x+cos(rad)*p;
var newy=this.y+sin(rad)*p;this.goto(newx,newy);}function turtleBack(p){
this.forward(-p);}function turtlePenDown(){this.penIsDown=true;}
function turtlePenUp(){this.penIsDown = false;}function turtleGoTo(x,y){
if(this.penIsDown){stroke(this.color);strokeWeight(this.weight);
line(this.x,this.y,x,y);}this.x = x;this.y = y;}function turtleDistTo(x,y){
return sqrt(sq(this.x-x)+sq(this.y-y));}function turtleAngleTo(x,y){
var absAngle=degrees(atan2(y-this.y,x-this.x));
var angle=((absAngle-this.angle)+360)%360.0;return angle;}
function turtleTurnToward(x,y,d){var angle = this.angleTo(x,y);if(angle< 180){
this.angle+=d;}else{this.angle-=d;}}function turtleSetColor(c){this.color=c;}
function turtleSetWeight(w){this.weight=w;}function turtleFace(angle){
this.angle = angle;}function makeTurtle(tx,ty){var turtle={x:tx,y:ty,
angle:0.0,penIsDown:true,color:color(128),weight:1,left:turtleLeft,
right:turtleRight,forward:turtleForward, back:turtleBack,penDown:turtlePenDown,
penUp:turtlePenUp,goto:turtleGoTo, angleto:turtleAngleTo,
turnToward:turtleTurnToward,distanceTo:turtleDistTo, angleTo:turtleAngleTo,
setColor:turtleSetColor, setWeight:turtleSetWeight,face:turtleFace};
return turtle;}

Spirals are my favorite patterns so I wanted to make my project with them. It was fun making variations in color and stroke but setting the steps for spirals are hard. Overall, doing this project has definitely made me more familiarized with turtles.

Screenshot of project.

Lan Wei-Project 11-Composition

my-sketch.js

//Lan wei
//Section D
//lanw@andrew.cmu.edu
//Project-11

var img;
var repeatTime = 1; // time repeated before the painting is finished
var numEachTime = 10; // number of turtles in each repeat time
var randomYArrays = []; //nested arrays including Y in each repeat time
var randomY = []; //arrays of Y in each repeat time
var bri; //brightness of the pixel

function preload(){
    img = loadImage("https://i.imgur.com/9e7ATQI.jpg?1.jpg");
}

function setup() {
    createCanvas(450, 450);
    img.loadPixels();
    background(0);
    for (var i = 0; i < repeatTime; i ++){
        for (var j = 0; j < numEachTime; j ++){ //add "numEachTime" values in randomY
            randomY.push(random(0, height));
        }
        randomYArrays.push(randomY);
        randomY = [];
    }
    frameRate(1);
}

function draw() {
    for (var i = 0; i < repeatTime; i ++){
        randomY = randomYArrays[i];
        for (var n = 0; n < numEachTime; n ++){
            drawTurtle(-100, randomY[n]);
        }
    }
}

function drawTurtle(tx, ty){
    var ttl = makeTurtle(tx, ty);
    ttl.penDown();

    //step 1
    bri = brightness(img.get(ttl.x, ttl.y)); //brightness of the pixels
    ttl.setColor(map(bri, 0, 100, 255, 70));
    ttl.setWeight(map(bri, 0, 100, 1, 2)); //change light weight according to brightness
    ttl.forward(random(20, 50));

    //step 2
    for(var i = 0; i < 15; i ++){
        var angle = 0;
        while (angle < 30){
            var angleSingleTime = random(0, 20);
            ttl.left(angleSingleTime);
            bri = brightness(img.get(ttl.x, ttl.y)); //brightness of the pixels
            ttl.setColor(map(bri, 0, 100, 255, 70));
            ttl.setWeight(map(bri, 0, 100, 1, 2)); //change light weight according to brightness
            ttl.forward(random(1, 3));
            angle += angleSingleTime;
        }

        //step 3
        while (angle < 90){
            var angleSingleTime = random(0, 20);
            ttl.right(angleSingleTime);
            bri = brightness(img.get(ttl.x, ttl.y)); //brightness of the pixels
            ttl.setColor(map(bri, 0, 100, 255, 70));
            ttl.setWeight(map(bri, 0, 100, 1, 2)); //change light weight according to brightness
            ttl.forward(random(1, 3));
            angle += angleSingleTime;
        }

        //step 4
        while (angle < 120){
            var angleSingleTime = random(0, 20);
            ttl.left(angleSingleTime);
            bri = brightness(img.get(ttl.x, ttl.y)); //brightness of the pixels
            ttl.setColor(map(bri, 0, 100, 255, 70));
            ttl.setWeight(map(bri, 0, 100, 1, 2)); //change light weight according to brightness
            ttl.forward(random(1, 3));
            angle += angleSingleTime;
        }

        //step 5
        bri = brightness(img.get(ttl.x, ttl.y)); //brightness of the pixels
        ttl.setColor(map(bri, 0, 100, 255, 70));
        ttl.setWeight(map(bri, 0, 100, 1, 2)); //change light weight according to brightness
        ttl.forward(random(20, 50));
    }
}

/////////////////////////////////////////////////////////
function turtleLeft(d){this.angle-=d;}function turtleRight(d){this.angle+=d;}
function turtleForward(p){var rad=radians(this.angle);var newx=this.x+cos(rad)*p;
var newy=this.y+sin(rad)*p;this.goto(newx,newy);}function turtleBack(p){
this.forward(-p);}function turtlePenDown(){this.penIsDown=true;}
function turtlePenUp(){this.penIsDown = false;}function turtleGoTo(x,y){
if(this.penIsDown){stroke(this.color);strokeWeight(this.weight);
line(this.x,this.y,x,y);}this.x = x;this.y = y;}function turtleDistTo(x,y){
return sqrt(sq(this.x-x)+sq(this.y-y));}function turtleAngleTo(x,y){
var absAngle=degrees(atan2(y-this.y,x-this.x));
var angle=((absAngle-this.angle)+360)%360.0;return angle;}
function turtleTurnToward(x,y,d){var angle = this.angleTo(x,y);if(angle< 180){
this.angle+=d;}else{this.angle-=d;}}function turtleSetColor(c){this.color=c;}
function turtleSetWeight(w){this.weight=w;}function turtleFace(angle){
this.angle = angle;}function makeTurtle(tx,ty){var turtle={x:tx,y:ty,
angle:0.0,penIsDown:true,color:color(128),weight:1,left:turtleLeft,
right:turtleRight,forward:turtleForward, back:turtleBack,penDown:turtlePenDown,
penUp:turtlePenUp,goto:turtleGoTo, angleto:turtleAngleTo,
turnToward:turtleTurnToward,distanceTo:turtleDistTo, angleTo:turtleAngleTo,
setColor:turtleSetColor, setWeight:turtleSetWeight,face:turtleFace};
return turtle;}

I planned to draw abstract ‘Sherlock’ with turtles. The process didn’t go smoothly. I tested different moving modes of the turtles and finally decided to use the one with some randomness but generally moving from the left of the canvas to the right. There are some aspects of the project that don’t reach my expectation (for example the nested loop might have some problems), but the result is good and the effect of old movie is kind of surprising.

Process Sherlock 1
Process Sherlock 2

Yoo Jin Shin-Project-11-Composition

Project-11

// Yoo Jin Shin
// Section D
// yoojins@andrew.cmu.edu
// Project 11 Turtle Freesytle

function turtleLeft(d) {
    this.angle -= d;
}

function turtleRight(d) {
    this.angle += d;
}

function turtleForward(p) {
    var rad = radians(this.angle);
    var newx = this.x + cos(rad) * p;
    var newy = this.y + sin(rad) * p;
    this.goto(newx, newy);
}

function turtleBack(p) {
    this.forward(-p);
}

function turtlePenDown() {
    this.penIsDown = true;
}

function turtlePenUp() {
    this.penIsDown = false;
}

function turtleGoTo(x, y) {
    if (this.penIsDown) {
      stroke(this.color);
      strokeWeight(this.weight);
      line(this.x, this.y, x, y);
    }
    this.x = x;
    this.y = y;
}

function turtleDistTo(x, y) {
    return sqrt(sq(this.x - x) + sq(this.y - y));
}

function turtleAngleTo(x, y) {
    var absAngle = degrees(atan2(y - this.y, x - this.x));
    var angle = ((absAngle - this.angle) + 360) % 360.0;
    return angle;
}

function turtleTurnToward(x, y, d) {
    var angle = this.angleTo(x, y);
    if (angle < 180) {
        this.angle += d;
    } else {
        this.angle -= d;
    }
}

function turtleSetColor(c) {
    this.color = c;
}

function turtleSetWeight(w) {
    this.weight = w;
}

function turtleFace(angle) {
    this.angle = angle;
}

function makeTurtle(tx, ty) {
    var turtle = {x: tx, y: ty,
                  angle: 0.0, 
                  penIsDown: true,
                  color: color(128),
                  weight: 1,
                  left: turtleLeft, right: turtleRight,
                  forward: turtleForward, back: turtleBack,
                  penDown: turtlePenDown, penUp: turtlePenUp,
                  goto: turtleGoTo, angleto: turtleAngleTo,
                  turnToward: turtleTurnToward,
                  distanceTo: turtleDistTo, angleTo: turtleAngleTo,
                  setColor: turtleSetColor, setWeight: turtleSetWeight,
                  face: turtleFace};
    return turtle;
}

var particles = [];

function setup() {
    createCanvas(480, 480);

    // Making particles/"rain"
    for (var i = 0; i < np; i++) {
        var p = makeParticle(200, 200,
                             random(-50, 50), random(-50, 50));
        particles.push(p);
    }
    frameRate(10);
}

function draw() { 
    // Gradient green/grass background based on mouse
    var r = map(mouseX, 0, width, 70, 120); 
    var b = map(mouseY, 0, height, 90, 120);
    background(r, 170, b);

    // Center rose on mouse
    var ttl = makeTurtle(mouseX, mouseY);
    ttl.penDown();
    ttl.setColor("pink");
    ttl.setWeight(1);
    ttl.left(frameCount);
    ttl.face(190);

    for (var i = 0; i < 25; i++) {
        ttl.face(225 - i * 100);
        for (var j = 0; j < 6; j++) {
            ttl.forward(3 + i * 2);
            ttl.left(80);
        }
    }
    ttl.penUp();

    /// Left smaller rose 
    var ttl2 = makeTurtle(mouseX - 50, mouseY);
    ttl2.penDown();
    ttl2.setColor(150);
    ttl2.setWeight(1);
    ttl2.left(frameCount);
    ttl2.face(190);

    for (var i = 0; i < 10; i++) {
        ttl2.face(225 - i * 100);
        for (var j = 0; j < 6; j++) {
            ttl2.forward(2 + i * 2);
            ttl2.left(70);
        }
    }
    ttl.penUp();

    /// Right smaller rose 
    var ttl2 = makeTurtle(mouseX + 50, mouseY);
    ttl2.penDown();
    ttl2.setColor(150);
    ttl2.setWeight(1);
    ttl2.left(frameCount);
    ttl2.face(190);

    for (var i = 0; i < 10; i++) {
        ttl2.face(225 - i * 100);
        for (var j = 0; j < 6; j++) {
            ttl2.forward(2 + i * 2);
            ttl2.left(70);
        }
    }
    ttl.penUp();

    // Draw all particles in the array
    if (mouseIsPressed) {
        var newp = makeParticle(mouseX, mouseY,
                                random(-10, 10), random(-10, 0));
        particles.push(newp);
    }

    newParticles = [];
    for (var i = 0; i < particles.length; i++) { 
        var p = particles[i];
        p.step();
        p.draw();
        if (p.age < 200) {
            newParticles.push(p);
        }
    }
    particles = newParticles;

}

var gravity = 0.3; // downward acceleration
var springy = 0.7; // how much velocity is retained after bounce
var drag = 0.0001; // drag causes particles to slow down
var np = 100;      // how many particles
var COLORS = ["White", "#86E3F2", "#37A3B5", "#357CA8", "#14608E"];

function particleStep() {
    this.age++;
    this.x += this.dx;
    this.y += this.dy;
    if (this.x > width) { // bounce off right wall
        this.x = width - (this.x - width);
        this.dx = -this.dx * springy;
    } else if (this.x < 0) { // bounce off left wall
        this.x = -this.x;
        this.dx = -this.dx * springy;
    }
    if (this.y > height) { // bounce off bottom
        this.y = height - (this.y - height);
        this.dy = -this.dy * springy;
    } else if (this.y < 0) { // bounce off top
        this.y = -this.y;
        this.dy = -this.dy * springy;
    }
    this.dy = this.dy + gravity; // force of gravity
    var vs = Math.pow(this.dx, 2) + Math.pow(this.dy, 2);
    var d = vs * drag;
    d = min(d, 1);

    // Repelling force from center rose
    var rpx = mouseX;
    var rpy = mouseY;
    var d2 = dist(rpx, rpy, this.x, this.y);
    var rpc = 9000;
    var f = rpc / (Math.pow(d2, 2));
    var dirx = (this.x - rpx) / d2;
    var diry = (this.y - rpy) / d2;
    // scale dx and dy to include drag effect
    this.dx *= (1 - d);
    this.dx += dirx * f;
    this.dy *= (1 - d)
    this.dy +=  diry * f;
}

function particleDraw() {
  fill(this.particleColor);
  noStroke();
  ellipse(this.x, this.y, this.particleSize, this.particleSize);
  point(this.x, this.y);
}

function pickColor() {
  return COLORS[int(random(COLORS.length))];
}

function pickSize() {
  return random(5, 30);
}

// create a "Particle" object with position and velocity
function makeParticle(px, py, pdx, pdy) {
    p = {x: px,
       y: py,
         dx: pdx, 
         dy: pdy,
         age: 0,
         step: particleStep,
         draw: particleDraw,
         particleColor : pickColor(),
         particleSize : pickSize(),
        }
    return p;
}

I created this project with a flower garden in mind: there are rose-like shapes created using turtle, a green, grass-like background, and many blue, rain-like particles. There is a force around the center rose that repels the rain.

Repelling force