qr code

Glidare, inmatningsrutor och knappar

Glidare, inmatningsrutor och knappar

En hemsida kan innehålla olika objekt förutom text. När man använder p5.js (Javascript-biblioteket för Processing) skapar man i regel ett ritområde med funktionen createCanvas(). Detta ritområde är ett exempel på ett objekt som en hemsida kan innehålla. Man kan också skapa

  • glidare med funktionen createSlider(),
  • inmatningsrutor med funktionen createInput()
  • och knappar med funktionen createButton().

Detta är ett exempel på ett ritområde:

Detta är ett exempel på en glidare:

Dra i glidaren för att ändra färg på ritområdet!

Detta är ett exempel på en inmatningsruta:

Detta är ett exempel på en knapp:

Skriv ditt namn i inmatningsrutan och klicka på knappen!

 

OpenProcessing är inte gjort för att skapa hemsidor, istället handlar programmeringen mestadels om att programmera vad som ska hända i ritområdet. För att göra hantering av glidare, inmatningsrutor och knappar så enkel som möjligt, ska vi placera alla objekt ovanpå ritområdet. Så hade man troligen inte gjort om man skapat en egen hemsida men så länge man håller på med OpenProcessing är detta ett enkelt sätt att ta emot indata med de standardmetoder som glidare, inmatningsrutor och knappar erbjuder.

Biblioteket p5.dom

Alla objekt som används på en hemsida struktureras internt i en trädliknande hierarki med en modell som kallas DOM, vilket står för Document Object Model. För att kunna skapa glidare, inmatningsrutor och knappar i p5.js, måste du använda ett Javascriptbibliotek kallat p5.dom.

När du är inne i editorn på OpenProcessing kan du visa en meny längst till höger. Om menyn inte syns klickar du på menyikonen.

ikon

Sedan markerar du p5.dom under tabben Settings.

p5.dom

Nu kommer biblioteket p5.dom att användas och du kan skapa glidare, inmatningsrutor och knappar.

En beskrivning av biblioteket p5.dom hittar du på sidan Reference p5.dom library.

Glidare

Funktionen createSlider(<min>, <max>, <värde>, <steg>) skapar och returnerar en glidare där parametrarna

  • <min> och <max> är gränserna för glidarens värde,
  • <värde> är det värde glidaren har från början,
  • <steg> anger hur mycket glidarens värde ska ändras i varje steg.

Vi kan exempelvis skapa en glidare med denna kod

färgGld = createSlider(0, 255, 100, 1);

inuti setup-funktionen. Det går inte att skapa en glidare innan setup.

Glidaren färgGld representerar en färgs värde. Glidaren har värdet 100 från början

En glidare har ett antal metoder som skrivs med punktnotation efter glidarens namn.

  • färgGld.position(<x>, <y>) anger var glidaren ska placeras.
  • färgGld.changed(<funktionsnamn>) tar emot ett argument som är ett funktionsnamn. Funktionen definierar man själv och i definitionen av funktionen skriver man den kod som ska utföras när glidaren ändrar värde.
  • färgGld.value() returnerar det värde glidaren har.

Man kan också ange hur lång en glidare ska vara genom att använda följande metod som ändrar glidarens stil:

  • färgGld.style("width", "300px") ger egenskapen width värdet 300 pixlar. Notera att enheten px måste stå med och att både argumenten är textsträngar, dvs de skrivs mellan citationstecken.
Exempel 1

Kopiera in följande kod i OpenProcessing och se till att biblioteket p5.dom används.

var färgGld;

function setup() {
	createCanvas(windowWidth, windowHeight);
	färgGld = createSlider(0, 255, 100, 1);
	färgGld.position(50, 100);
	färgGld.changed(hanteraGlidare);
	fill(255, 0, 0);
	textSize(24);
	text("Gråskalan = 100", 50, 200);
}

function hanteraGlidare() {
	var färg = färgGld.value();
	background(färg);
	text("Gråskalan = " + färg, 50, 200);
}

Ändra på glidarens stil så att den blir längre.

Lista av glidare

Om vi vill använda glidare för att ange en RGB-färg istället för en gråskala, behövs det tre glidare. Det går att göra tre glidar-variabler men det går också att lägga in de tre glidarna i en lista. Genom att lägga in glidarna i en lista blir koden för att skapa och initiera glidarna kortare

Exempel 2

Kopiera in följande kod i OpenProcessing och se till att biblioteket p5.dom används.

var glid = [], menyX = 340;

function setup() {
	var i;
	createCanvas(windowWidth, windowHeight);
	background(255);
	textSize(20);
	noStroke();
	for (i = 0; i < 3; i += 1) {
		glid[i] = createSlider(0, 255, 100, 1);
		glid[i].style('width', '300px');
		glid[i].position(20, 150 + 50 * i);
		glid[i].changed(visaVal);
	}
	visaVal();
}

function draw() {
	fill(glid[0].value(), glid[1].value(), glid[2].value());
	if (mouseX > menyX && mouseIsPressed) {
		ellipse(mouseX, mouseY, 20);
	}
}

function visaVal() {
	fill(50); 
	rect(0, 0, menyX, height); //rita över menyn men inte det som ritats
	fill(200);
	text("Fyllnadsfärg = ("+glid[0].value() + ", " + glid[1].value() + ", " + glid[2].value() + ")", 20, 300);
}

Ändra storleken på glidarna och värdet på variabeln menyX så att du får en meny som är lagom bred.

Glidarna ligger som objekt ovanför canvas. När du ändrar utseende på canvas påverkar detta alltså inte glidarnas utseende.

Inmatningsrutor

Funktionen createInput() skapar och returnerar en inmatningsruta.

Vi kan exempelvis skapa en inmatningsruta med denna kod

inm = createInput();

En inmatningsruta har ett antal metoder som skrivs med punktnotation efter inmatningsrutans namn.

  • inm.position(<x>, <y>) anger var inmatningsrutan ska placeras.
  • inm.input(<funktionsnamn>) tar emot ett argument som är ett funktionsnamn. Funktionen definierar man själv och i definitionen av funktionen skriver man den kod som ska utföras när inmatningsrutan ändrar värde.
  • inm.size(<storlek>) anger hur stor inmatningsrutan ska vara.
  • inm.value() returnerar den text som finns i inmatningsrutan.
  • inm.value(<textsträng>) gör texten i inmatningsrutan till den textsträng som anges som argument.

Man kan också ange hur stor texten i inmatningsrutan ska vara med hjälp av följande metod:

  • inm.style("font-size", "24px") ger egenskapen font-size (dvs textstorleken) värdet 24 pixlar. Notera att enheten px måste stå med och att både argumenten är textsträngar, dvs de skrivs mellan citationstecken.
Exempel 3

Följande kod skriver ut inmatningsrutans innehåll i ritområdet varje gång inmatningsrutans innehåll ändras:

var inm;

function setup() {
	createCanvas(windowWidth, windowHeight);
	background(100);
	textSize(24);
	inm = createInput();
	inm.position(100,100);
	inm.style("font-size", "24px");
	inm.size(100);
	inm.input(hanteraInmatning);
}

function hanteraInmatning() {
	background(100);
	text("Inmatning: "+ inm.value(), 100, 200);
}

Prova att ändra teckenstorleken i både den text som skrivs ut i ritområdet och i inmatningsrutan.

I normala fall händer det ingenting i ett program medan användaren skriver i en inmatningsruta. Oftast händer det ingenting förrän användaren klickar på en knapp eller avslutar inmatningen genom att klicka på enter.

Exempel 4

Med denna kod visas ett meddelande när användaren trycker på enter

var inm;

function setup() {
	createCanvas(windowWidth, windowHeight);
	background(100);
	textSize(24);
	text("Skriv in ditt namn:", 100, 100);
	inm = createInput();
	inm.position(320,100);
	inm.style("font-size", "24px");
	inm.size(100);
}


function keyPressed() {
	if (keyCode == ENTER) {
		background(100);
		text("Skriv in ditt namn:", 100, 100);
		text("Hej "+ inm.value() + "!", 100, 200);
		inm.value("");
	}
}

Efter det att hälsningsmeddelandet visas töms inmatningsrutans innehåll genom att innehållet sätts till en tom textsträng.

Testkör koden. Texten som skrivs ut i ritområdet skrivs på positionen y = 100, vilket är samma y-position som inmatningsrutan har. Positionen för text i ritområdet anges med det hörn som ligger i det vänstra nedre hörnet, för inmatningsrutan anges positionen med det vänstra övre hörnet. Lägg till raden

textAlign(LEFT, TOP);

i setup-funktionen och testkör programmet igen.

Om användaren trycker på enter utan att ha skrivit in någonting, ligger det en tom textsträng i inmatningsrutan. Ändra i koden så att följande if-sats används:

if (inm.value() == "") {
	text("Skriv in ditt namn!", 100, 200);
} else {
	text("Hej " + inm.value() + "!", 100, 200);
	inm.value("");
}

Knappar

Funktionen createButton(<text>) skapar och returnerar en knapp med den text som ges av argumentet <text>.

Vi kan exempelvis skapa en knapp med denna kod

knapp = createButton("OK");

En knapp har ett antal metoder som skrivs med punktnotation efter knappens namn.

  • knapp.position(<x>, <y>) anger var knappen ska placeras.
  • knapp.mousePressed(<funktionsnamn>) tar emot ett argument som är ett funktionsnamn. Funktionen definierar man själv och i definitionen av funktionen skriver man den kod som ska utföras när knappen klickas.
  • knapp.hide() gömmer knappen.
  • knapp.show() visar knappen.

Man kan också ange hur stor knappens text ska vara med hjälp av följande metod:

  • knapp.style("font-size", "24px") ger egenskapen font-size (dvs textstorleken) värdet 24 pixlar.
Exempel 5

Denna kod ritar en slumpvis placerad cirkel när man klickar på knappen.

var knapp;

function setup() {
	createCanvas(windowWidth, windowHeight);
	background(100);
	knapp = createButton("Gör en cirkel");
	knapp.position(100, 100);
	knapp.style("font-size", "24px");
	knapp.mousePressed(hanteraKnapp);
}

function hanteraKnapp() {
	ellipse(random(width), random(height), 20);
}

Ändra i koden så att det händer något annat när man klickar på knappen.

Knappar används ofta för att hantera inmatningar i inmatningsrutor.

Exempel 6

Koden visar ett hälsningsmeddelande när användaren klickar på knappen.

var inm, knapp;

function setup() {
	createCanvas(windowWidth, windowHeight);
	background(100);
	textSize(24);
	textAlign(LEFT, TOP);
	text("Skriv in ditt namn:", 100, 100);
	inm = createInput();
	inm.position(320,100);
	inm.style("font-size", "24px");
	inm.size(100);
	knapp = createButton("OK");
	knapp.position(500, 100);
	knapp.style("font-size", "24px");
	knapp.mousePressed(hanteraKnapp);
}

function hanteraKnapp() {
	background(100);
	text("Skriv in ditt namn:", 100, 100);
	text("Hej "+ inm.value() + "!", 100, 200);
	inm.value("");
}

Testkör koden. Det är vanligt att man som användaren får någonting att hända antingen genom att klicka på en OK-knapp eller genom att trycka på enter. Lägg till kod som anropar funktionen hanteraKnapp också ifall användaren trycker på enter.

Omtypning

Det värde som ligger i en imatningsruta är av datatypen textsträng. Om man vill att användaren ska mata in ett numeriskt värde så måste man typa om från textsträng till antingen ett heltal eller ett flyttal innan man kan hantera det numeriska värdet i koden. Det finns två funktioner som gör sådana omtypningar:

  • int(<text>) gör om <text> till ett heltal. Heltal kallas för integer på engelska.
  • float(<text>) gör om <text> till ett flyttal. Flyttal kallas för floating point på engelska.

Om användaren matar in tecken som inte kan kan konverteras till tal, blir resultatet av omtypning antingen ett felaktigt heltal eller NaN vilket står för Not a Number.

Koden

print(int("12"));
print(float("3.14")); \\ korrekt decimalpunkt
print(int("huh")); 	\\ inte ett numeriskt värde
print(float("3,14")); \\ felaktigt decimalkomma

ger utskriften

12
3.14
NaN
3

Felet att omtypningen resulterar i NaN kan man hantera med funktionen isNaN(<värde>) som returnerar true om <värde> är NaN.

Program som låter användaren mata in numeriska värden i inmatningsrutor bör hantera felaktiga inmatningar. För enkelhetens skull visar vi bara exempel på inmatning av heltal och hanterar bara felet att inmatningen konverteras till NaN.

Exempel 7

Koden kollar om användaren klarar att mata in ett jämnt heltal. För att avgöra om talet är jämnt, kontrollerar programmet om resten då tal divideras med två är noll.

var inm, knapp;

function setup() {
	createCanvas(windowWidth, windowHeight);
	background(100);
	textAlign(LEFT, TOP);
	textSize(24);
	text("Skriv in ett jämnt heltal:", 100, 100);
	inm = createInput();
	inm.position(380, 100);
	inm.style("font-size", "24px");
	inm.size(60);
	knapp = createButton("OK");
	knapp.position(450, 100);
	knapp.style("font-size", "24px");
	knapp.mousePressed(hanteraKnapp);
}


function hanteraKnapp() {
	var tal;
	background(100);
	text("Skriv in ett jämnt heltal:", 100, 100);
	tal = int(inm.value());
	if (isNaN(tal) ) {
		text("Inget heltal. Försök igen!", 100, 200);
	} else if (tal%2 == 0) {
		text("Rätt! " + tal + " = 2*" + (tal/2), 100, 200);
	} else {
		text("Fel! " + tal + " är inte delbart med två.", 100, 200);
	}
	inm.value("");
}

Testkör programmet. Testa att skriva in bokstäver. Testa även att skriva in 6.32.

Ändra i koden så att meddelandet "Rätt ..." visas i grön förg och meddelandet "Fel ..." i röd färg.

Programmeringsuppgifter

Uppgift 1

Ritprogram med glidare

Utgå ifrån Exempel 2 men lägg också in en glidare som låter användaren välja storlek på ellipsen. Lägg in kod i funktionen visaVal som visar den storlek användaren gjort antingen som text eller genom en uppritad ellips. Använd funktionen visaVal som argument till den nya glidarens changed-metod. Se till att ellipsen ritas med den valda storleken.

Lägg in tre glidare till som låter användaren byta bakgrundsfärg. Lägg in kod i funktionen visaVal som visar den bakgrundsfärg användaren valt. Definiera en funktion ändraBakgrund vilken används som argument till de nya glidarnas changed-metod. När bakgrunden ändras ska ritområdet ritas över med den nya bakgrundsfärgen. Att byta bakgrund innebär alltså också att man suddar det som tidigare ritats.

Se slutligen till att det bara ritas när musknappen är nedtryckt.

Istället för att visa RGB-värden för de två valda färgerna, kan de visas i menyn exempelvis som färgade rektanglar.

ritprogram
Exempel på hur det kan se ut.

Uppgift 2

Matteövning med inmatningsruta

Gör ett program som exempelvis låter användaren öva på multiplikationstabellen. Slumptalsgenerera två heltal. Visa frågan och en inmatningsruta samt en OK-knapp. Visa huruvida användaren svarat rätt eller fel.

Det går att använda två knappar, en OK-knapp och en som låter användaren försöka med en ny slumpad fråga, en "Ny fråga"-knapp. Genom att använda metoderna show och hide kan du välja när knapparna ska visas eller döljas.