From 92c5b06b7e4b33f8a88f9a49238de75c2b33819e Mon Sep 17 00:00:00 2001 From: root Date: Sun, 13 Jul 2025 17:09:24 +0200 Subject: [PATCH] Add interactive visual content system for kids MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ✨ New Features: - Visual animations for science concepts (sky, birds, water, etc.) - Interactive educational illustrations with emoji and animations - Topic-based visual content mapping system - Kid-friendly CSS animations and effects - Enhanced learning experience for ages 8-12 🎨 Visual Content Includes: - Sky/atmosphere light scattering animation - Bird flight mechanics visualization - Water molecule structure and behavior - Earth orbit and seasons explanation - Computer data flow representation - Brain and dream visualization - Rainbow light spectrum breakdown - General thinking process animations 📱 Features: - Responsive design for all devices - Smooth animations and transitions - Auto-detection of topics from questions - Multi-language visual descriptions - Engaging educational content --- index.html | 2 + script-new.js | 28 +++ style.css | 51 ++++ visual-animations.css | 571 ++++++++++++++++++++++++++++++++++++++++++ visual-content.js | 224 +++++++++++++++++ 5 files changed, 876 insertions(+) create mode 100644 visual-animations.css create mode 100644 visual-content.js diff --git a/index.html b/index.html index 43918a9..983f18f 100755 --- a/index.html +++ b/index.html @@ -20,6 +20,7 @@ + @@ -177,6 +178,7 @@ + diff --git a/script-new.js b/script-new.js index 659ac67..b1ac325 100644 --- a/script-new.js +++ b/script-new.js @@ -236,6 +236,9 @@ class KidsAIExplorer { conversationContainer.className = 'conversation-container'; this.thinkingSteps.appendChild(conversationContainer); + // Get the original question for visual content + const currentQuestion = this.questionInput ? this.questionInput.value.trim() : ''; + // Show initial encouragement const welcomeStep = document.createElement('div'); welcomeStep.className = 'conversation-step visible'; @@ -263,6 +266,31 @@ class KidsAIExplorer { `; conversationContainer.appendChild(welcomeStep); + // Add visual content if available + if (typeof VisualContent !== 'undefined' && currentQuestion) { + const visualContent = VisualContent.getVisualForTopic(currentQuestion); + if (visualContent) { + const visualStep = document.createElement('div'); + visualStep.className = 'conversation-step visual-step visible'; + + const visualDescription = visualContent.description[this.currentLanguage] || visualContent.description['en']; + + visualStep.innerHTML = ` +
+
+ ${visualContent.emoji} + ${aiTeacherLabel} +
+
+

${visualDescription}

+ ${visualContent.illustration} +
+
+ `; + conversationContainer.appendChild(visualStep); + } + } + // Add thinking questions as interactive steps const fallbackQuestions = [ t['fallback-question-1'] || "What do you already know about this topic?", diff --git a/style.css b/style.css index 008b75f..a5653cf 100755 --- a/style.css +++ b/style.css @@ -1334,3 +1334,54 @@ body { background: rgba(255, 255, 255, 0.8); border-left-color: #e53e3e; } + +/* Visual Content Integration */ +.visual-step { + margin: 20px 0; +} + +.visual-step .ai-message { + background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); + border: 2px solid rgba(255, 255, 255, 0.3); +} + +.visual-step .message-content { + padding: 20px; +} + +.visual-step .message-content p { + margin-bottom: 15px; + font-weight: 600; + color: white; + text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3); +} + +/* Enhanced conversation styling */ +.conversation-container { + max-width: 100%; + margin: 0 auto; +} + +.conversation-step { + opacity: 0; + transform: translateY(20px); + transition: all 0.6s ease-out; + margin-bottom: 20px; +} + +.conversation-step.visible { + opacity: 1; + transform: translateY(0); +} + +/* Responsive visual content */ +@media (max-width: 768px) { + .visual-concept { + margin: 10px -10px; + border-radius: 10px; + } + + .visual-step .message-content { + padding: 15px; + } +} diff --git a/visual-animations.css b/visual-animations.css new file mode 100644 index 0000000..c9fdef0 --- /dev/null +++ b/visual-animations.css @@ -0,0 +1,571 @@ +/* Visual Animations for Educational Concepts */ + +/* General Visual Concept Styles */ +.visual-concept { + background: rgba(255, 255, 255, 0.95); + border-radius: 15px; + padding: 20px; + margin: 15px 0; + box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1); + text-align: center; + position: relative; + overflow: hidden; + animation: slideInUp 0.8s ease-out; +} + +.visual-concept::before { + content: ''; + position: absolute; + top: -50%; + left: -50%; + width: 200%; + height: 200%; + background: linear-gradient(45deg, transparent, rgba(102, 126, 234, 0.1), transparent); + animation: shimmer 3s infinite; + pointer-events: none; +} + +/* Sky/Atmosphere Animation */ +.sky-layers { + height: 200px; + position: relative; + border-radius: 10px; + overflow: hidden; +} + +.atmosphere-layer { + height: 100%; + position: relative; + display: flex; + align-items: center; + justify-content: center; +} + +.light-rays { + position: absolute; + width: 100%; + height: 100%; +} + +.light-ray { + position: absolute; + width: 3px; + height: 50px; + background: linear-gradient(to bottom, transparent, rgba(255, 255, 0, 0.6), transparent); + animation: lightScatter 2s infinite ease-in-out; +} + +.light-ray:nth-child(1) { + left: 20%; + animation-delay: 0s; +} + +.light-ray:nth-child(2) { + left: 50%; + animation-delay: 0.5s; +} + +.light-ray:nth-child(3) { + left: 80%; + animation-delay: 1s; +} + +.scattered-light { + position: absolute; + bottom: 20px; + left: 50%; + transform: translateX(-50%); + background: rgba(0, 100, 255, 0.8); + color: white; + padding: 8px 16px; + border-radius: 20px; + font-size: 14px; + animation: bounce 2s infinite; +} + +/* Bird Flight Animation */ +.bird-flight { + height: 180px; + position: relative; + display: flex; + align-items: center; + justify-content: center; +} + +.bird { + position: relative; + animation: bobbing 2s infinite ease-in-out; +} + +.wing { + position: absolute; + font-size: 24px; + animation: wingFlap 1s infinite; +} + +.wing-left { + left: -30px; + transform-origin: right center; +} + +.wing-right { + right: -30px; + transform-origin: left center; +} + +.bird-body { + font-size: 32px; +} + +.air-currents { + position: absolute; + width: 100%; + height: 100%; +} + +.air-flow { + position: absolute; + font-size: 14px; + padding: 5px 10px; + border-radius: 15px; + animation: floatUpDown 3s infinite ease-in-out; +} + +.up-flow { + top: 20%; + left: 20%; + background: rgba(0, 255, 0, 0.2); + animation-delay: 0s; +} + +.down-flow { + bottom: 20%; + right: 20%; + background: rgba(255, 0, 0, 0.2); + animation-delay: 1.5s; +} + +/* Water Molecule Animation */ +.water-molecules { + height: 160px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: space-around; +} + +.molecule { + display: flex; + align-items: center; + gap: 5px; + position: relative; + animation: moleculeVibrate 1.5s infinite; +} + +.atom { + width: 30px; + height: 30px; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + font-weight: bold; + font-size: 12px; +} + +.hydrogen { + background: #ff6b6b; + color: white; +} + +.oxygen { + background: #4ecdc4; + color: white; +} + +.bond { + width: 20px; + height: 2px; + background: #333; + position: absolute; + left: 50%; + transform: translateX(-50%); +} + +.water-droplet { + font-size: 48px; + animation: dropletBounce 2s infinite; +} + +.wetness-effect { + font-size: 12px; + color: #666; + max-width: 200px; +} + +/* Seasons/Earth Animation */ +.solar-system { + height: 200px; + position: relative; + display: flex; + align-items: center; + justify-content: center; +} + +.sun { + font-size: 48px; + position: absolute; + left: 20px; + animation: sunGlow 3s infinite ease-in-out; +} + +.earth-orbit { + width: 200px; + height: 200px; + border: 2px dashed #ccc; + border-radius: 50%; + position: relative; + animation: orbit 8s infinite linear; +} + +.earth { + font-size: 32px; + position: absolute; + top: -20px; + left: 50%; + transform: translateX(-50%); +} + +.earth.tilted { + transform: translateX(-50%) rotate(23.5deg); +} + +.season-labels { + position: absolute; + width: 100%; + height: 100%; +} + +.season { + position: absolute; + font-size: 12px; + padding: 4px 8px; + border-radius: 10px; + background: rgba(255, 255, 255, 0.8); +} + +.season.summer { + top: 0; + left: 50%; + transform: translateX(-50%); +} + +.season.winter { + bottom: 0; + left: 50%; + transform: translateX(-50%); +} + +/* Computer/Data Flow Animation */ +.computer-brain { + height: 160px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: space-around; +} + +.cpu { + font-size: 24px; + padding: 10px; + background: linear-gradient(45deg, #667eea, #764ba2); + color: white; + border-radius: 10px; + animation: cpuPulse 2s infinite; +} + +.data-flow { + display: flex; + gap: 20px; +} + +.binary-code { + font-family: 'Courier New', monospace; + font-size: 14px; + color: #00ff00; + background: #000; + padding: 5px 10px; + border-radius: 5px; + animation: binaryScroll 1s infinite; +} + +.binary-code:nth-child(2) { + animation-delay: 0.5s; +} + +.memory { + font-size: 18px; + padding: 8px 12px; + background: #f0f0f0; + border-radius: 8px; +} + +/* Dream Animation */ +.sleeping-brain { + height: 180px; + position: relative; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + +.brain { + font-size: 48px; + animation: brainPulse 3s infinite ease-in-out; +} + +.dream-bubbles { + position: absolute; + top: 0; + width: 100%; + height: 100%; +} + +.dream-bubble { + position: absolute; + font-size: 24px; + animation: dreamFloat 4s infinite ease-in-out; +} + +.dream-bubble:nth-child(1) { + left: 10%; + animation-delay: 0s; +} + +.dream-bubble:nth-child(2) { + left: 50%; + animation-delay: 1.3s; +} + +.dream-bubble:nth-child(3) { + right: 10%; + animation-delay: 2.6s; +} + +.sleep-waves { + position: absolute; + bottom: 20px; + font-size: 18px; + color: #667eea; + animation: waveMove 2s infinite; +} + +/* Rainbow/Light Spectrum Animation */ +.light-spectrum { + height: 160px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: space-around; +} + +.white-light { + font-size: 24px; + animation: lightPulse 2s infinite; +} + +.prism { + font-size: 32px; + animation: prismRotate 4s infinite linear; +} + +.rainbow-colors { + display: flex; + gap: 10px; + animation: colorSpread 3s infinite ease-in-out; +} + +.rainbow-colors span { + font-weight: bold; + padding: 4px 8px; + border-radius: 5px; + background: rgba(255, 255, 255, 0.8); + animation: colorPulse 1s infinite ease-in-out; +} + +/* General Thinking Animation */ +.thinking-process { + height: 150px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + +.brain-icon { + font-size: 48px; + animation: thinkingPulse 2s infinite ease-in-out; +} + +.thought-bubbles { + display: flex; + gap: 15px; + margin-top: 20px; +} + +.bubble { + font-size: 24px; + animation: bubbleFloat 3s infinite ease-in-out; +} + +.bubble:nth-child(1) { animation-delay: 0s; } +.bubble:nth-child(2) { animation-delay: 1s; } +.bubble:nth-child(3) { animation-delay: 2s; } + +/* Keyframe Animations */ +@keyframes shimmer { + 0% { transform: translateX(-100%) translateY(-100%) rotate(45deg); } + 100% { transform: translateX(100%) translateY(100%) rotate(45deg); } +} + +@keyframes slideInUp { + from { + opacity: 0; + transform: translateY(30px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +@keyframes lightScatter { + 0%, 100% { opacity: 0.3; transform: translateY(0); } + 50% { opacity: 1; transform: translateY(-10px); } +} + +@keyframes bounce { + 0%, 20%, 50%, 80%, 100% { transform: translateX(-50%) translateY(0); } + 40% { transform: translateX(-50%) translateY(-10px); } + 60% { transform: translateX(-50%) translateY(-5px); } +} + +@keyframes bobbing { + 0%, 100% { transform: translateY(0); } + 50% { transform: translateY(-10px); } +} + +@keyframes wingFlap { + 0%, 100% { transform: rotateZ(0deg); } + 50% { transform: rotateZ(-30deg); } +} + +@keyframes floatUpDown { + 0%, 100% { transform: translateY(0); opacity: 0.7; } + 50% { transform: translateY(-15px); opacity: 1; } +} + +@keyframes moleculeVibrate { + 0%, 100% { transform: translateX(0); } + 25% { transform: translateX(-2px); } + 75% { transform: translateX(2px); } +} + +@keyframes dropletBounce { + 0%, 100% { transform: scale(1); } + 50% { transform: scale(1.1); } +} + +@keyframes sunGlow { + 0%, 100% { transform: scale(1); filter: brightness(1); } + 50% { transform: scale(1.1); filter: brightness(1.2); } +} + +@keyframes orbit { + from { transform: rotate(0deg); } + to { transform: rotate(360deg); } +} + +@keyframes cpuPulse { + 0%, 100% { transform: scale(1); } + 50% { transform: scale(1.05); } +} + +@keyframes binaryScroll { + 0% { opacity: 0; } + 50% { opacity: 1; } + 100% { opacity: 0; } +} + +@keyframes brainPulse { + 0%, 100% { transform: scale(1); } + 50% { transform: scale(1.1); } +} + +@keyframes dreamFloat { + 0% { opacity: 0; transform: translateY(30px); } + 25% { opacity: 1; transform: translateY(0); } + 75% { opacity: 1; transform: translateY(-20px); } + 100% { opacity: 0; transform: translateY(-40px); } +} + +@keyframes waveMove { + 0% { transform: translateX(-10px); } + 50% { transform: translateX(10px); } + 100% { transform: translateX(-10px); } +} + +@keyframes lightPulse { + 0%, 100% { filter: brightness(1); } + 50% { filter: brightness(1.3); } +} + +@keyframes prismRotate { + from { transform: rotate(0deg); } + to { transform: rotate(360deg); } +} + +@keyframes colorSpread { + 0% { transform: scale(0.8); opacity: 0.8; } + 50% { transform: scale(1); opacity: 1; } + 100% { transform: scale(0.8); opacity: 0.8; } +} + +@keyframes colorPulse { + 0%, 100% { transform: scale(1); } + 50% { transform: scale(1.05); } +} + +@keyframes thinkingPulse { + 0%, 100% { transform: scale(1) rotate(0deg); } + 25% { transform: scale(1.05) rotate(-2deg); } + 75% { transform: scale(1.05) rotate(2deg); } +} + +@keyframes bubbleFloat { + 0%, 100% { transform: translateY(0) scale(1); opacity: 0.7; } + 50% { transform: translateY(-15px) scale(1.1); opacity: 1; } +} + +/* Responsive adjustments */ +@media (max-width: 768px) { + .visual-concept { + padding: 15px; + margin: 10px 0; + } + + .sky-layers, + .bird-flight, + .solar-system { + height: 150px; + } + + .bird-body, .earth, .brain { + font-size: 24px; + } + + .sun { + font-size: 36px; + } +} diff --git a/visual-content.js b/visual-content.js new file mode 100644 index 0000000..a2977d9 --- /dev/null +++ b/visual-content.js @@ -0,0 +1,224 @@ +// Visual Content System for KidsAI Explorer +// Maps topics and concepts to appropriate visual elements for kids aged 8-12 + +const VisualContent = { + // Topic-based visual mappings + topicVisuals: { + // Science topics + 'sky': { + emoji: '🌌', + animation: 'sky-animation', + illustration: ` +
+
+
+
+
+
+
+
+
💙 Blue light scatters more!
+
+
+
+ `, + description: { + en: "Watch how sunlight scatters in our atmosphere!", + de: "Schau, wie das Sonnenlicht in unserer Atmosphäre gestreut wird!" + } + }, + + 'bird': { + emoji: '🕊️', + animation: 'bird-flight-animation', + illustration: ` +
+
+
+
🪶
+
🐦
+
🪶
+
+
+
⬆️ Lift
+
⬇️ Gravity
+
+
+
+ `, + description: { + en: "See how birds use their wings to create lift!", + de: "Sieh, wie Vögel ihre Flügel nutzen, um Auftrieb zu erzeugen!" + } + }, + + 'water': { + emoji: '💧', + animation: 'water-molecule-animation', + illustration: ` +
+
+
+
H
+
O
+
H
+
+
+
💧
+
Makes things wet because molecules stick!
+
+
+ `, + description: { + en: "Discover why water feels wet!", + de: "Entdecke, warum sich Wasser nass anfühlt!" + } + }, + + 'seasons': { + emoji: '🌍', + animation: 'earth-orbit-animation', + illustration: ` +
+
+
☀️
+
+
🌍
+
+ Summer ☀️ + Winter ❄️ +
+
+
+
+ `, + description: { + en: "See how Earth's tilt creates seasons!", + de: "Sieh, wie die Neigung der Erde die Jahreszeiten entstehen lässt!" + } + }, + + 'computer': { + emoji: '💻', + animation: 'data-flow-animation', + illustration: ` +
+
+
🧠 CPU
+
+
1010101
+
0110011
+
+
💾 Memory
+
+
+ `, + description: { + en: "Watch how computers think with 1s and 0s!", + de: "Schau, wie Computer mit 1en und 0en denken!" + } + }, + + 'dream': { + emoji: '💭', + animation: 'brain-dream-animation', + illustration: ` +
+
+
🧠
+
+
🌈
+
🦄
+
🏰
+
+
~~~
+
+
+ `, + description: { + en: "See your brain creating dreams while you sleep!", + de: "Sieh, wie dein Gehirn Träume erschafft, während du schläfst!" + } + }, + + 'rainbow': { + emoji: '🌈', + animation: 'light-prism-animation', + illustration: ` +
+
+
🌞 White Light
+
🔺
+
+ Red + Orange + Yellow + Green + Blue + Indigo + Violet +
+
+
+ `, + description: { + en: "Watch white light split into rainbow colors!", + de: "Schau, wie weißes Licht in Regenbogenfarben aufgeteilt wird!" + } + } + }, + + // Get visual content for a question/topic + getVisualForTopic: function(question) { + const questionLower = question.toLowerCase(); + + // Check for topic keywords + for (const [topic, visual] of Object.entries(this.topicVisuals)) { + if (questionLower.includes(topic) || + this.getTopicKeywords(topic).some(keyword => questionLower.includes(keyword))) { + return visual; + } + } + + // Default visual for general questions + return { + emoji: '🤔', + animation: 'thinking-animation', + illustration: ` +
+
+
🧠
+
+
💡
+
+
🔍
+
+
+
+ `, + description: { + en: "Let's think about this together!", + de: "Lass uns gemeinsam darüber nachdenken!" + } + }; + }, + + // Get additional keywords for topic matching + getTopicKeywords: function(topic) { + const keywords = { + 'sky': ['blue', 'himmel', 'blau', 'atmosphere', 'atmosphäre'], + 'bird': ['fly', 'flying', 'fliegen', 'wing', 'flügel', 'vogel'], + 'water': ['wet', 'nass', 'liquid', 'flüssig', 'molecule', 'molekül'], + 'seasons': ['winter', 'summer', 'spring', 'autumn', 'jahreszeit', 'sommer', 'herbst', 'frühling'], + 'computer': ['work', 'funktioniert', 'processor', 'prozessor', 'digital'], + 'dream': ['sleep', 'schlafen', 'träume', 'night', 'nacht'], + 'rainbow': ['colors', 'farben', 'light', 'licht', 'regenbogen', 'prism', 'prisma'] + }; + return keywords[topic] || []; + } +}; + +// Export for use in other files +if (typeof module !== 'undefined' && module.exports) { + module.exports = VisualContent; +}