Typewriter effect P5.JS - p5.js

js and trying to animate a text for it to look as if it was being typed, but I am stuck with this...
var palabra= "Hola!"; =
var pos = 0;
function setup() {
createCanvas(canvasWH, canvasWH);
frameRate(10);
}
function draw() {
textFont('Georgia');
textSize(20);
text(palabra.substring(pos, pos + 1), pos+++, canvasWH/2, canvasWH, 100);
pos = +++
// Check if we are at the end to restart animation
if () {
//restart animation
}
}```

pos++ is the way to increment.
restartDelay controls how many frames to wait before clearing after drawing is complete
var palabra= "Hola!";
var pos = 0;
var restartDelay = 5;
function setup() {
createCanvas(500, 500);
frameRate(10);
}
function draw() {
background(255);
textFont('Georgia');
textSize(20);
text(palabra.substring(0, pos + 1), 50, 50);
pos++;
// Check if we are at the end to restart animation
if (pos > palabra.length + restartDelay) {
//restart animation
pos = 0;
}
}

Related

How could I make a rotating image alternate in p5.js?

I'm trying to make a rotating image move with mouseX and mouseY and interact with key-commands: When the left or right arrow keys are pressed, the images should alternate between each other; the up arrow increases the rotation speed, while the down arrow should decrease rotation speed.
Applied some edits based on responses, but nothing displays when I run the code.
Amended code listed below:
var angle = 0.0;
var angleSpeed = 0.0;
var imageSwitcher = 0;
var images = [];
var img1;
var img2;
var img3;
function preload() {
images[0] = loadImage(image1);
images[1] = loadImage(image2);
images[2] = loadImage(image3);
function setup() {
createCanvas(900, 500);
background(100);
}
function draw() {
translate(mouseX, mouseY);
rotate(angle);
images(imageSwitcher % 2,-15, -15, 30, 30);
angle += angleSpeed;
}
function keyPressed() {
if (keyCode == LEFT_ARROW) {
images = img1;
}
else if (keyCode == RIGHT_ARROW) {
images = img2;
}
else if (keyCode == LEFT_ARROW) {
images = img3;
}
else if (keyCode == UP_ARROW) {
angleSpeed += 1.0;
}
else if (keyCode == DOWN_ARROW) {
angleSpeed -= 1.0;
}
}
}
var angle = 0.0;
var angleSpeed = 0.0;
var images = [];
var imageSwitcher = 0;
function preload() {
images[0] = loadImage("ToyStoryLogo.png");
images[1] = loadImage("CarsLogo.png");
images[2] = loadImage("Incredibles.png");
}
function setup() {
createCanvas(900, 500);
background(204);
}
function draw() {
background(204);
translate(mouseX, mouseY);
rotate(angle);
image(images[abs(imageSwitcher) % 3], -15, -15, 30, 30);
angle += angleSpeed;
}
function keyPressed() {
if (keyCode == LEFT_ARROW) {
imageSwitcher--;
} else if (keyCode == RIGHT_ARROW) {
imageSwitcher++;
} else if (keyCode == UP_ARROW) {
angleSpeed += 0.1;
} else if (keyCode == DOWN_ARROW) {
angleSpeed -= 0.1;
}
}
There are a few issues that I see.
The first has to do with the rotation speed control.
You want to add a variable to control the incrementation of the angle variable.
Create a variable, lets say angleSpeed.
var angle = 0.0;
var angleSpeed = 0.0;
...
In the draw function, change the line
angle += 0.1;
to
angle += angleSpeed;
This allows you to control the rotation in keyPressed( );
if keycode Up
angleSpeed += 1.0;
If keycode Down
angleSpeed -= 1.0;
Switching through the images would be a little more complicated. I would look into creating a array of images,
var images = [ ];
Then cycling through the array with a key press right or left.
var image = [ ]
var ImageSwitcher = 0
Then in preload
images[0] = loadImage (image1);
images[1] = loadImage (image2);
images[2] = loadImage (image3);
In draw
image(images[imageSwitcher % 3], x,y,...);
For keycode right arrow
ImageSwitcher++;
For keycode left arrow
ImageSwitcher--

p5.js Add a dissapearing ellipse trail to Lissajous curve line

I have a simple code that traces the Liss cruve with a small ellipse. I was wondering how to add a fading trail to this shape so it represents the cruve more clearly. I only know a bit about adding trails that follows the mouse but I'm not sure how to do this one.
Any help is appreciated, here is the code:
var t = 0;
function setup() {
createCanvas(500, 500);
fill(255);
}
function draw() {
background(0);
for (i = 0; i < 1; i++) {
y = 160*sin(3*t+PI/2);
x = 160*sin(1*t);
fill(255);
ellipse(width/2+x, height/2+y, 5, 5);
t += .01;
}
}
Try changing background(0) to background(0, 0, 0, 4) :)
Here is a working example:
https://editor.p5js.org/chen-ni/sketches/I-FbLFDXi
Edit:
Here is another solution that doesn't use the background trick:
https://editor.p5js.org/chen-ni/sketches/HiT4Ycd5U
Basically, it keeps track of each point's position and redraws them in every frame with updated alpha to create the "fading out" effect.
var t = 0;
var particleArray = [];
function setup() {
createCanvas(500, 500);
}
function draw() {
background(0);
y = width / 2 + 160 * sin(3 * t + PI / 2);
x = height / 2 + 160 * sin(1 * t);
particleArray.push(new Particle(x, y, t));
for (i=0; i<particleArray.length; i++) {
particleArray[i].show(t);
}
//keep the array short, otherwise it runs very slow
if (particleArray.length > 800) {
particleArray.shift();
}
t += .01;
}
function Particle(x, y, t) {
this.x = x;
this.y = y;
this.t = t;
this.show = function(currentT) {
var _ratio = t / currentT;
_alpha = map(_ratio, 0, 1, 0, 255); //points will fade out as time elaps
fill(255, 255, 255, _alpha);
ellipse(x, y, 5, 5);
}
}

The line move with position in clmtrackr. How to create line with not moving by p5.js

I'm new to p5.js and I'm trying to create a horizontal line by using p5.js with the position 21 clmtrackr.js. But the line is moving. I want to create the line with not moving. Here my code.
var ctracker;
var trigHeight = 0;
var ypos = 0;
var button;
var test = false;
function setup() {
var videoInput = createCapture();
videoInput.size(400, 300);
videoInput.position(0, 0);
var cnv = createCanvas(400, 300);
cnv.position(0, 0);
ctracker = new clm.tracker();
ctracker.init(pModel);
ctracker.start(videoInput.elt);
noStroke();
button = createButton("set height");
button.position(150, 260);
button.mousePressed(showLine)
background(100);
}
function draw() {
clear();
noStroke();
var positions = ctracker.getCurrentPosition();
for (var i = 0; i < positions.length; i++) {
fill(0, 255, 0);
rect(positions[i][0], positions[i][1], 3, 3);
if (i == 21) {
ypos = positions[i][1];
}
}
stroke("rgb(0,255,0)");
strokeWeight(4);
test && line(0, trigHeight, width * 2, trigHeight
}
function showLine() {
test = true;
}
Thank you.

"Interactive overlay" in p5.js

I would like to do the following in p5.js. Say I have a canvas roughly like this:
Let's say I have given those red squares some interactivity using the function mouseClicked() and their respective coordinates in the canvas (as in, if I click on a square, change its color).
Now I'd like to use that blue "i"-button to display some sort of info box, and it should look approximately like this:
I want that "info dialog" to go away if the user clicks on that "OK-button" (whcih is not really a button, but also just a square in a p5 canvas).
Question: Is there an elegant way of deactivating the "square interactivity" and activating that "OK button interactivity" and to have the interactivity the other way around whenever the info box is not being displayed?
The only way I can think of to achieve this goes like this:
function mouseClicked(){
if(infoBoxIsBeingDisplayed){
do something
}else{
do something else
}
}
However, this seems a little convoluted.
I'd appreciate any suggestions on how to do this better.
Your solution seems fine, and it also seems much less "convoluted" than any of the other options. Keep it simple.
You might be able to clean up your code by splitting up your logic into smaller utility functions. Something like this:
function mouseClicked(){
if(infoBoxIsBeingDisplayed){
mouseClickedInfoBox();
}else{
mouseClickedSquaresCanvas();
}
}
Then your logic would be in those utility functions, specific to each screen. You could further split it up to generalize your bounds-checking, but the idea is the same.
I've run into a similar problem to this before, the best way I came up with to solve this (which is a fairly patchy way to do it) is to move the squares outside of the canvas. sorry my code is probably really messy but look at the function game and you will see what i did
If you run the game make it full screen.
example:(to play the game use A and D or use the arrow keys but i suggest A and D because the way the code snippet is set up the game doesn't fit on the page and the page moves around when you press the arrow keys)
var bs = [];
var speed;
var ship1;
var num = 40;
var d;
var gscore = 0;
var highscore = 0;
var cap = 0;
function setup() {
createCanvas(windowWidth,windowHeight- 4);
for(var i = 0; i < num; i++) {
bs[i] = new Box(random(0, width), random(-600,-30));
}
ship1 = new ship();
button1 = new button();
}
function draw() {
background(0);
if(cap == 0){
gscore = gscore + 0.1;
}
if(highscore < gscore){
highscore = gscore;
}
speed = map(gscore,4,100,4,5);
ship1.show();
ship1.update();
for(var i = 0; i < num; i++) {
bs[i].update();
bs[i].show();
if(bs[i].y >= height){
bs[i].x = random(0, width);
bs[i].y = random(-600,-30);
}
for(var j = 0; j < num; j++) {
if(bs[i].touch(bs[j])){
if(bs[i] != bs[j]){
bs[j].x = random(0, width);
bs[j].y = random(-600,-30);
}
}
}
if(bs[i].touch(ship1)){
game();
}
}
push();
fill(255,0,0);
textSize(36);
text("score: "+ floor(gscore),0,36);
text("highscore: "+floor(highscore),0,72);
pop();
}
function Box(x, y) {
this.x = x;
this.y = y;
this.show = function() {
fill(255);
noStroke();
rect(this.x, this.y, 30, 30);
}
this.update = function() {
this.y = this.y + speed;
}
this.touch = function(other){
d = dist(this.x, this.y, other.x, other.y);
if(d < 15/*half of the squares*/+15/*the total area of the ship*/){
return true;
}else {
return false;
}
}
}
function game(){//look here, game is the end game screen
for(var i = 0; i < num; i++) {
bs[i].x = -200;//making all squares x value -200
bs[i].y = -200;//making all squares y value -200
}
ship1.x = -200;//making ship x value -200
ship1.y = -200;//making ship y value -200
cap = 1;//cap is a variable made to stop the score from increasing when the end game screen is shown its "capping" the score
push();
fill(255,0,0);
textAlign(CENTER);
textSize(64);
text("You lose", width/2, height/2);
fill(255);
text("Try again?", width/2,height/2+64);
button1.touch();//touch checks if the mouse is over the button(the button sucks ass btw the hitbox for it is a square not a rectangle)
button1.show();//showing the button
button1.update();//updates the text and button color when highlighted
fill(texthover);
textSize(48);
text("Yes",width/2, height/2+145);
pop();
}
function button(){
this.x = width/2;
this.y = height/2+128;
this.d;
this.update = function() {
this.x = width/2;
this.y = height/2+128;
}
this.show = function(){
push();
rectMode(CENTER);
fill(hover);
rect(this.x, this.y, 128, 64, 50);
pop();
}
this.touch = function(){
this.d = dist(this.x, this.y, mouseX, mouseY);
if(this.d <32){
hover = 51;
texthover = 255;
if(mouseIsPressed){
for(var i = 0; i < num; i++) {
bs[i].x = random(0, width);
bs[i].y = random(-600,-30);
}
ship1.x = width/2;
ship1.y = 450;
gscore = 0;
cap = 0;
}
}else {
hover = 200;
texthover = 0;
}
}
}
function ship() {
this.x = width/2;
this.y = 450;
this.update = function() {
if(keyIsDown(LEFT_ARROW) || keyIsDown(65)) {
if(this.x>14){
this.x = this.x - map(gscore,2,100,2,3);
}
}
if(keyIsDown(RIGHT_ARROW) || keyIsDown(68)) {
if(this.x<width- 15){
this.x = this.x + map(gscore,2,100,2,3);
}
}
}
this.show = function() {
push();
rectMode(CENTER);
fill(200,200,0);
rect(this.x+15, this.y+5, 5, 30);
fill(150,100,200);
rect(this.x+15, this.y + 15,30, 15)
pop();
}
}
function windowResized() {
createCanvas(windowWidth,windowHeight- 4);
button1.update();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.14/addons/p5.dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.14/p5.js"></script>

Why won't my canvas clear between animation frames?

I decided to start playing around with dart again today and for some reason I can't get my viewport to clear between frames. I've tried to use clearRect and fillRect to draw a white rectangle over the entire canvas element. Here is my code.
import 'dart:html';
void main() {
var canvasFun = new CanvasFun(query("#Game"));
}
class CanvasFun{
CanvasElement canvas;
num _width;
num _height;
Square square;
CanvasFun(this.canvas){
this.square = new Square(10,10, new Point(50,50));
requestRedraw();
}
void draw(num _){
var ctx = canvas.context2d;
//clear the viewport
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.fillStyle = "white";
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
//draw the square
this.square.draw(ctx);
requestRedraw();
}
void requestRedraw() {
window.requestAnimationFrame(draw);
}
}
class Point {
num x, y;
Point(this.x, this.y);
}
class Square{
num width;
num height;
num vectorX;
num vectorY;
Point location;
Square(this.width, this.height, this.location){
vectorX = 1;
vectorY = 1;
}
void draw(CanvasRenderingContext2D context){
context.save(); //I thought this might fix the blue viewport problem
this.update(context);
context.rect(this.location.x, this.location.y, this.width, this.height);
context.fillStyle = "blue";
context.fill();
}
void update(CanvasRenderingContext2D context)
{
num xBound = context.canvas.width;
num yBound = context.canvas.height;
if((this.location.x + this.width) > xBound){
this.vectorX = -1;
}
else if(this.location.x < 0){
this.vectorX = 1;
}
if((this.location.y + this.height) > yBound){
this.vectorY = -1;
}
else if(this.location.y < 0){
this.vectorY = 1;
}
this.location.x += (this.vectorX * 10);
this.location.y += (this.vectorY * 20);
}
}
The resulting animation draws a rectangle at the correct location but as it moves about the canvas the previous instance of the rectangle is still drawn. I'd like the rectangle to only appear once on the canvas and to look like it is moving about the screen.
Here is a screenshot of the output (notice the blue square is never cleared):
I simplified your code to get it working:
In CanvasFun:
void draw(num _){
var ctx = canvas.context2d;
//clear the viewport
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
//draw the square
this.square.draw(ctx);
requestRedraw();
}
In Square:
void draw(CanvasRenderingContext2D context){
this.update(context);
context.fillStyle = "blue";
context.fillRect(this.location.x, this.location.y, this.width, this.height);
}
I'm not sure what the exact problem was with the original version though. :)

Resources