xxxxxxxxxx
140
let txt;
let markovChain = {};
let generatedPoem = ""; // Variable to store the generated poem
let sentences = [];
let currentSentenceIndex = 0;
let animationTime = 0;
let baseDurationPerWord = 20; // Base duration for each word in the sentence
const MIN_FADE_DURATION = 150;
// Load Neruda's text file
function preload() {
txt = loadStrings("neruda_poem.txt"); // Load text file containing Neruda's poetry
}
function setup() {
createCanvas(400, 300);
textSize(20);
textAlign(CENTER, CENTER);
background(255);
// Join all lines into a single string and split into words
let words = txt.join(" ").split(/\s+/);
// Build the Markov chain
for (let i = 0; i < words.length - 1; i++) {
let word = words[i].toLowerCase();
let nextWord = words[i + 1].toLowerCase();
if (!markovChain[word]) {
markovChain[word] = [];
}
markovChain[word].push(nextWord);
}
// Create a "Generate Poem" button
let generateButton = createButton("Generate Poem");
generateButton.position(10, height + 10);
generateButton.mousePressed(generateAndDisplayPoem);
}
function draw() {
background(255);
fill(0);
animatePoem(); // Animate the poem display
}
// Function to generate and display a Neruda-style poem
function generateAndDisplayPoem() {
generatedPoem = generatePoem("love", 14); // Generate a poem of 14 sentences
sentences = generatedPoem.split("\n"); // Split the poem into individual sentences
console.log(sentences);
currentSentenceIndex = 0; // Reset to the first sentence
animationTime = 0; // Reset animation time
}
// Generate a poem using Markov Chain
function generatePoem(startWord, sentenceCount) {
let poem = "";
let sentences = 0;
while (sentences < sentenceCount) {
let currentWord = startWord;
let sentence = currentWord;
let sentenceEnded = false;
// Generate words for the sentence until it reaches an ending punctuation
while (!sentenceEnded) {
let possibleNextWords = markovChain[currentWord];
if (!possibleNextWords) break;
// Choose a random next word from possible next words
currentWord = random(possibleNextWords);
sentence += " " + currentWord;
// Check if the sentence has ended
if (currentWord.endsWith(".") || currentWord.endsWith("!") || currentWord.endsWith("?")) {
sentenceEnded = true;
sentences++;
}
}
// Append the completed sentence to the poem
poem += sentence + "\n"; // Single line break between sentences
// Choose a new random starting word for the next sentence to avoid repetition
let keys = Object.keys(markovChain);
startWord = random(keys); // Set a new random word for the next sentence
}
return poem;
}
// Animate poem display with phase-in and phase-out effect, with line breaks for long sentences
function animatePoem() {
if (sentences.length === 0) return; // Check if there are sentences to display
let sentence = sentences[currentSentenceIndex].trim();
let wrappedLines = wrapText(sentence, width - 40); // Wrap the sentence to fit canvas width
// Calculate fadeDuration based on the number of words in the sentence
let wordCount = sentence.split(" ").length;
let fadeDuration = wordCount * baseDurationPerWord; // Duration is proportional to word count
fadeDuration = max(fadeDuration, MIN_FADE_DURATION)
let alpha = sin((PI * animationTime) / fadeDuration); // Ease-in-out effect using sine wave
// Display each wrapped line with animated opacity
fill(0, 255 * abs(alpha)); // Scale alpha to 255 for opacity
let y = height / 2 - (wrappedLines.length * 12); // Center the block of wrapped lines vertically
for (let i = 0; i < wrappedLines.length; i++) {
text(wrappedLines[i], width / 2, y + i * 24); // Draw each line with spacing
}
// Update animation time
animationTime++;
if (animationTime >= fadeDuration) {
animationTime = 0; // Reset time for next sentence
currentSentenceIndex = (currentSentenceIndex + 1) % sentences.length; // Move to the next sentence
}
}
// Helper function to wrap text into multiple lines based on canvas width
function wrapText(sentence, maxWidth) {
let words = sentence.split(" ");
let lines = [];
let line = "";
for (let i = 0; i < words.length; i++) {
let testLine = line + words[i] + " ";
if (textWidth(testLine) > maxWidth) {
lines.push(line); // Save the current line
line = words[i] + " "; // Start a new line
} else {
line = testLine;
}
}
lines.push(line.trim()); // Add the last line
return lines;
}