xxxxxxxxxx
229
//code written by: Jane He
//references: saveCanvas(), createFileInput(), createInput(), value(), handleFile(), ceateObjectURL(),dist()
//https://stackoverflow.com/questions/58987477/generating-a-color-palette-from-image-using-p5-javascript
//variables for the basic layout design
let textColor="#343a40";
let titleFont,printFont;
let before,after;
//variables for the user input
let uploadFile;
let userImage;
let myPostcard;
//variables for functions
let y=0;
var atWelcome=true;
var startGenerate=false;
var getResult=false;
//load images and fonts
function preload(){
titleFont=loadFont("assets/LibreBodoni-Italic-VariableFont_wght.ttf");
printFont=loadFont("assets/WaterBrush-Regular.ttf");
before=loadImage("assets/before.png");
after=loadImage("assets/after.png");
}
function setup() {
createCanvas(700, 500);
before.resize(350,250);
after.resize(350,250);
}
function draw(){
if(atWelcome===true){
welcome();
}
if(startGenerate===true){
generate();
}
//image transformation
//trasforming the picture
if (y>0&&y<height){
myPostcard.transPic();
}
//transformation complete
if (y===height){
myPostcard.savePostcard();
y=-1;
}
}
function mousePressed(){
if(atWelcome===true){
if(mouseX>=280&&mouseX<=430&&mouseY>=420&&mouseY<=470){
atWelcome=false;
getResult=false;
generate();
}
}
}
function welcome(){
background("#f7ede2");
textFont(titleFont);
fill(textColor);
textSize(40);
text('Futuristic Postcard Generator',90,80);
textSize(20);
image(before,0,120);
image(after,350,120);
//create hover effect for the button
if(mouseX>=280&&mouseX<=430&&mouseY>=420&&mouseY<=470){
fill("#fafafa");
rect(280,420,150,50);
textSize(30);
fill(textColor);
text('Start!',315,455);
}else{
noFill();
rect(280,420,150,50);
fill(textColor);
textSize(30);
text('Start!',315,455);
}
}
function generate(){
background("#f7ede2");
if(startGenerate===false){
startGenerate=true;
//create the upload file button
uploadFile = createFileInput(handleFile);
uploadFile.position(80, 320);
//create the user input
postcardText=createInput('');
postcardText.style('border','1px solid rgb(52, 58, 64)');
postcardText.style('font-size','16px');
postcardText.position(80, 370);
postcardText.size(300, 30);
postcardText.attribute('placeholder', 'Enter the words for your postcard');
}
//written instructions
textSize(20);
fill(textColor);
text('Instruction:',80,100);
text('1. Click "Choose File" button to upload an image',80,130);
text('2. Enter the words you want to print on the postcard',80,190);
text('3. A filter will be applied automatically to your picture.',80,250);
text('4. Click "Save Postcard" button to save your postcard!',80,280);
fill(201, 28, 28);
text('**Only horizontal image is available now**',80,160);
text('**Only two words are available**',80,220);
}
//create objects
function createPostcard(){
myPostcard = new postcard(userImage,postcardText.value());
myPostcard.startGenerate();
}
//process the uploaded file
function handleFile(file){
print(file);
if(file.type==='image'){
let imageSrc=URL.createObjectURL(file.file);
//"generate your postcard!" button will pop up after the user uploads an image
userImage=loadImage(imageSrc, () => {
let start_generate=createButton('Generate your postcard!');
start_generate.position(250,440);
start_generate.mousePressed(createPostcard);
});
print(userImage);
}else{
userImage=null;
}
}
//Here's an explanation of how the color palette works
//1. Create a color palette of the filter
//2. Split the color of the original image based on RGB
//3. Match the original image with the color palette
function getPaletteColor(imgColor) {
palette = ['#264653','#2a9d8f','#e9c46a','#f4a261','#e76f51'];
const imgR = red(imgColor);
const imgG = green(imgColor);
const imgB = blue(imgColor);
let minDistance = 999999;
let targetColor;
for (const c of palette){
const paletteR = red(c);
const paletteG = green(c);
const paletteB = blue(c);
const colorDistance =
dist(imgR, imgG, imgB,
paletteR, paletteG, paletteB);
if(colorDistance < minDistance){
targetColor = c;
minDistance = colorDistance;
}
}
return targetColor;
}
//create objects
class postcard{
constructor(pos_img, pos_text){
this.pos_img = pos_img;
this.pos_text = pos_text;
removeElements();
background("#f7ede2");
atWelcome=false;
startGenerate=false;
getResult=true;
}
startGenerate(){
this.showPic();
this.transPic();
}
showPic(){
this.pos_img.resize(700,500);
image(this.pos_img, 0, 0);
}
transPic(){
for (let x = 0; x < width; x++) {
const imgColor = this.pos_img.get(x, y);
const paletteColor = getPaletteColor(imgColor);
stroke(paletteColor);
point(x, y);
}
y++;
noStroke();
fill("snow");
textFont(printFont);
textSize(100);
text(this.pos_text,160,150);
}
// create the save button
// the button will pop up after the generation
savePostcard(){
let saveResult = createButton('Save Postcard');
saveResult.position(250,400);
saveResult.style('width','200px')
saveResult.style('height','40px')
saveResult.style('color','#343a40')
saveResult.style('background-color', '#f7ede2');
saveResult.style('border','1px solid','#343a40');
saveResult.style('border-radius','5px');
saveResult.mousePressed(saveCanvas);
}
}