לדלג לתוכן

3.8 פרויקטים פרויקט

פרויקט 1 - רשימת משימות - Todo List

בנו אפליקציית רשימת משימות מלאה עם ממשק מעוצב ושמירה מקומית.

דרישות פונקציונליות

  1. הוספת משימה - שדה input וכפתור "add". לחיצה על הכפתור או Enter מוסיפה משימה חדשה לרשימה.
  2. סימון כהושלם - לחיצה על משימה מסמנת אותה כהושלמה (קו חוצה וצבע מעומעם). לחיצה נוספת מבטלת את הסימון.
  3. מחיקת משימה - כל משימה מכילה כפתור X למחיקה. לחיצה מסירה את המשימה מהרשימה.
  4. סינון - שלושה כפתורי סינון:
  5. "all" - מציג את כל המשימות
  6. "active" - מציג רק משימות שלא הושלמו
  7. "completed" - מציג רק משימות שהושלמו
  8. מונה משימות - הציגו "X tasks remaining" שמתעדכן בזמן אמת (סופר רק משימות פעילות).
  9. שמירה ל-localStorage - כל שינוי (הוספה, מחיקה, סימון) נשמר אוטומטית. כשטוענים את הדף מחדש, הרשימה משוחזרת.
  10. אנימציות - כשמוסיפים משימה, היא נכנסת עם אנימציה (slide in או fade in). כשמוחקים, היא יוצאת עם אנימציה (fade out) ורק אז מוסרת מה-DOM.

דרישות טכניות

  • השתמשו בדלגציית אירועים - handler אחד על ה-ul לכל הלחיצות על משימות
  • כל משימה נשמרת כאובייקט עם id, text, ו-completed
  • השתמשו ב-JSON.stringify ו-JSON.parse לשמירה וטעינה מ-localStorage
  • ה-id של כל משימה יכול להיות Date.now() ברגע היצירה

דרישות עיצוב

  • עיצוב נקי ומודרני
  • רקע בהיר, כרטיס לבן עם צל
  • שדה ה-input בולט עם מסגרת
  • כפתור ההוספה בצבע בולט
  • משימות שהושלמו עם קו חוצה וטקסט אפור
  • כפתורי הסינון - הכפתור הפעיל מודגש
  • כפתור המחיקה מופיע רק ב-hover על המשימה

מבנה HTML מוצע

<div class="todo-app">
  <h1>todo list</h1>
  <div class="input-section">
    <input type="text" id="todo-input" placeholder="what needs to be done?">
    <button id="add-btn">add</button>
  </div>
  <div class="filters">
    <button class="filter-btn active" data-filter="all">all</button>
    <button class="filter-btn" data-filter="active">active</button>
    <button class="filter-btn" data-filter="completed">completed</button>
  </div>
  <ul id="todo-list"></ul>
  <p id="task-count"></p>
</div>

טיפים

  • שמרו מערך של אובייקטי משימות: [{ id: 123, text: "...", completed: false }, ...]
  • בכל שינוי, שמרו את כל המערך ל-localStorage ורנדרו מחדש
  • לאנימציות, הוסיפו class ותנו ל-CSS transition לעשות את העבודה. למחיקה, הוסיפו class של "removing", חכו שהאנימציה תסתיים (setTimeout), ואז הסירו מה-DOM
  • לסינון, אל תמחקו אלמנטים - פשוט הסתירו/הציגו עם display

פרויקט 2 - מחשבון ויזואלי - Visual Calculator

בנו מחשבון עם ממשק גרפי שעובד עם עכבר ומקלדת.

דרישות פונקציונליות

  1. כפתורים - כפתורים לספרות 0-9, פעולות (+, -, *, /), נקודה עשרונית, שווה (=), ניקוי (C), מחיקת תו אחרון (backspace).
  2. תצוגה - אזור תצוגה שמראה את הקלט הנוכחי ואת התוצאה. הציגו גם את הפעולה הנוכחית (למשל "5 + 3").
  3. חישוב - לחיצה על = מחשבת את התוצאה ומציגה אותה. התוצאה הופכת לקלט הבא (אפשר להמשיך לחשב).
  4. שרשור פעולות - תמיכה בחישוב רציף. למשל: 3 + 5 = 8, ואז * 2 = 16.
  5. תמיכת מקלדת - לחיצה על מקשים מפעילה את הכפתורים המתאימים:
  6. מקשי 0-9 ונקודה עשרונית
  7. מקשי +, -, *, /
  8. Enter = חישוב
  9. Escape = ניקוי
  10. Backspace = מחיקת תו אחרון
  11. היסטוריה - רשימה מתחת למחשבון שמציגה את החישובים האחרונים (למשל "5 + 3 = 8"). ההיסטוריה נשמרת ב-localStorage.

דרישות טכניות

  • השתמשו בדלגציית אירועים - handler אחד על ה-div של הכפתורים
  • כל כפתור עם data-value attribute שמציין את הערך שלו
  • אירוע keydown על document לתמיכת מקלדת
  • היסטוריה נשמרת כמערך ב-localStorage

דרישות עיצוב

  • layout של הכפתורים ב-CSS Grid (4 עמודות, כמו מחשבון אמיתי)
  • כפתור = תופס 2 שורות או 2 עמודות
  • כפתור 0 תופס 2 עמודות
  • צבעים שונים לכפתורי ספרות, פעולות, וניקוי
  • אזור תצוגה גדול עם טקסט מיושר לימין
  • אפקט hover ו-active (לחיצה) על כל כפתור
  • כשלוחצים מקש במקלדת, הכפתור המתאים מקבל הדגשה ויזואלית לרגע

מבנה HTML מוצע

<div class="calculator">
  <div class="display">
    <div class="display-expression">5 + 3</div>
    <div class="display-result">8</div>
  </div>
  <div class="buttons">
    <button data-value="C" class="btn-clear">C</button>
    <button data-value="backspace" class="btn-clear">DEL</button>
    <button data-value="/" class="btn-operator">/</button>
    <button data-value="*" class="btn-operator">*</button>
    <button data-value="7">7</button>
    <button data-value="8">8</button>
    <button data-value="9">9</button>
    <button data-value="-" class="btn-operator">-</button>
    <button data-value="4">4</button>
    <button data-value="5">5</button>
    <button data-value="6">6</button>
    <button data-value="+" class="btn-operator">+</button>
    <button data-value="1">1</button>
    <button data-value="2">2</button>
    <button data-value="3">3</button>
    <button data-value="=" class="btn-equals">=</button>
    <button data-value="0" class="btn-zero">0</button>
    <button data-value=".">.</button>
  </div>
</div>
<div class="history">
  <h3>history</h3>
  <ul id="calc-history"></ul>
  <button id="clear-history">clear history</button>
</div>

טיפים

  • שמרו את מצב המחשבון במשתנים: currentNumber, previousNumber, operator
  • כשלוחצים ספרה, הוסיפו אותה ל-currentNumber (כמחרוזת, ואז המירו למספר בחישוב)
  • כשלוחצים operator, שמרו את currentNumber ב-previousNumber ואפסו את currentNumber
  • כשלוחצים =, חשבו את התוצאה מ-previousNumber operator currentNumber
  • היזהרו מחילוק באפס - הציגו הודעת שגיאה
  • היזהרו מנקודות עשרוניות כפולות

פרויקט 3 - משחק חידון - Quiz App

בנו אפליקציית חידון עם שאלות רב-ברירה, טיימר, וציונים.

דרישות פונקציונליות

  1. מאגר שאלות - מערך של לפחות 10 שאלות. כל שאלה מכילה: טקסט השאלה, מערך של 4 תשובות אפשריות, אינדקס התשובה הנכונה.
  2. הצגת שאלה - הציגו שאלה אחת בכל פעם עם 4 כפתורי תשובה.
  3. טיימר - כל שאלה מקבלת 15 שניות. הטיימר מוצג ויזואלית (פס שהולך ונגמר, או מספר שיורד). אם הזמן נגמר, השאלה נספרת כשגויה ועוברים לשאלה הבאה.
  4. משוב מיידי - כשבוחרים תשובה:
  5. תשובה נכונה - הכפתור הופך ירוק
  6. תשובה שגויה - הכפתור שנבחר הופך אדום, והתשובה הנכונה הופכת ירוקה
  7. חכו 1-2 שניות ואז עברו לשאלה הבאה
  8. מעקב ציון - הציגו ציון נוכחי (כמה נכונות מתוך כמה נענו) וסרגל התקדמות.
  9. מסך תוצאות - בסוף כל השאלות הציגו:
  10. ציון סופי (X/10)
  11. אחוז הצלחה
  12. פירוט - רשימת כל השאלות עם סימון נכון/שגוי
  13. הצגת התשובה הנכונה לכל שאלה שנענתה לא נכון
  14. התחלה מחדש - כפתור "play again" שמערבב את השאלות ומתחיל מחדש.
  15. ציון גבוה - שמרו את הציון הגבוה ביותר ב-localStorage. הציגו אותו במסך הפתיחה.

דרישות טכניות

  • השתמשו בדלגציית אירועים לכפתורי התשובות
  • setTimeout למעבר בין שאלות
  • setInterval לטיימר (אל תשכחו לעצור אותו ב-clearInterval)
  • Math.random ו-sort לערבוב שאלות וסדר תשובות

דרישות עיצוב

  • מסך פתיחה עם שם המשחק, הציון הגבוה, וכפתור "start"
  • כרטיס שאלה במרכז המסך
  • כפתורי תשובה גדולים ונוחים ללחיצה
  • פס טיימר שמשנה צבע (ירוק -> כתום -> אדום) ככל שהזמן אוזל
  • סרגל התקדמות "question X of 10"
  • מסך תוצאות עם עיצוב ברור - ירוק לנכון, אדום לשגוי

מבנה נתונים מוצע

let questions = [
  {
    question: "What does HTML stand for?",
    answers: [
      "Hyper Text Markup Language",
      "High Tech Modern Language",
      "Hyper Transfer Markup Language",
      "Home Tool Markup Language"
    ],
    correct: 0
  },
  {
    question: "Which CSS property changes the text color?",
    answers: [
      "text-color",
      "font-color",
      "color",
      "text-style"
    ],
    correct: 2
  }
  // ... more questions
];

טיפים

  • חלקו את הקוד לפונקציות ברורות: showQuestion, checkAnswer, nextQuestion, showResults, startGame
  • שמרו את מצב המשחק במשתנים: currentQuestionIndex, score, answers (מערך של תשובות המשתמש)
  • לטיימר, השתמשו ב-setInterval שרץ כל שניה ומעדכן את התצוגה. עצרו אותו עם clearInterval כשבוחרים תשובה
  • לערבוב, השתמשו באלגוריתם Fisher-Yates shuffle

פרויקט 4 - משחק זיכרון - Memory Game

בנו משחק זיכרון קלאסי - מצאו זוגות תואמים של קלפים.

דרישות פונקציונליות

  1. לוח משחק - רשת של קלפים (4x4 = 16 קלפים = 8 זוגות). כל הקלפים מתחילים הפוכים (מוסתרים).
  2. חשיפת קלפים - לחיצה על קלף חושפת אותו (אנימציית הפיכה). אפשר לחשוף שני קלפים בכל תור.
  3. בדיקת התאמה:
  4. אם שני הקלפים שנחשפו תואמים - הם נשארים גלויים
  5. אם הם לא תואמים - חכו 1 שניה ואז הפכו אותם חזרה
  6. תוכן הקלפים - השתמשו בסמלים או אימוג'ים (אפשר גם טקסט פשוט כמו A, B, C...). כל סמל מופיע בדיוק פעמיים.
  7. מונה מהלכים - ספרו כמה מהלכים (זוגות לחיצות) המשתמש ביצע.
  8. טיימר - הציגו את הזמן שעובר מתחילת המשחק (דקות:שניות).
  9. תנאי ניצחון - כשכל הזוגות נמצאו:
  10. הציגו הודעת ניצחון
  11. הציגו את מספר המהלכים והזמן
  12. השוו לציון הטוב ביותר (נשמר ב-localStorage)
  13. כפתור "play again" להתחלה מחדש
  14. ערבוב - בכל משחק חדש, הקלפים מעורבבים באקראי.

דרישות טכניות

  • השתמשו בדלגציית אירועים - handler אחד על הלוח כולו
  • אנימציית הפיכת קלף עם CSS transform (rotateY(180deg)) ו-transition
  • setInterval לטיימר
  • שמרו את הציון הטוב ביותר ב-localStorage (מספר מהלכים מינימלי, או זמן מינימלי)

דרישות עיצוב

  • רשת הקלפים ב-CSS Grid (4 עמודות)
  • כל קלף הוא ריבוע עם פינות מעוגלות
  • צד אחורי של הקלף בצבע אחיד עם סימן שאלה או דפוס
  • צד קדמי מציג את הסמל בגדול ובצבע
  • אנימציית הפיכה תלת-ממדית (perspective + rotateY)
  • קלפים שנמצא להם זוג מקבלים אפקט ויזואלי (צבע רקע שונה, או גבול ירוק)
  • פס מידע עליון עם מהלכים, טיימר, וכפתור restart
  • מסך ניצחון עם אנימציה

מבנה HTML מוצע

<div class="memory-game">
  <div class="game-info">
    <span>moves: <span id="moves-count">0</span></span>
    <span>time: <span id="timer">00:00</span></span>
    <span>best: <span id="best-score">-</span></span>
    <button id="restart-btn">restart</button>
  </div>
  <div class="game-board" id="game-board">
    <!-- cards will be generated by JavaScript -->
  </div>
</div>

<!-- victory modal -->
<div id="victory-modal" style="display: none;">
  <div class="modal-content">
    <h2>you won!</h2>
    <p>moves: <span id="final-moves"></span></p>
    <p>time: <span id="final-time"></span></p>
    <p id="new-record" style="display: none;">new record!</p>
    <button id="play-again">play again</button>
  </div>
</div>

מבנה CSS לאנימציית הפיכה

.card {
  perspective: 1000px;
  cursor: pointer;
  aspect-ratio: 1;
}

.card-inner {
  width: 100%;
  height: 100%;
  position: relative;
  transition: transform 0.5s;
  transform-style: preserve-3d;
}

.card.flipped .card-inner {
  transform: rotateY(180deg);
}

.card-front, .card-back {
  position: absolute;
  width: 100%;
  height: 100%;
  backface-visibility: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
}

.card-back {
  background: #3498db;
  color: white;
  font-size: 2rem;
}

.card-front {
  background: white;
  transform: rotateY(180deg);
  font-size: 2.5rem;
}

טיפים

  • צרו מערך של סמלים, שכפלו אותו (כדי שכל סמל יהיה פעמיים), ועירבבו
  • שמרו שני משתנים: firstCard ו-secondCard. כשלוחצים קלף ראשון, שמרו אותו. כשלוחצים שני, השוו
  • בזמן שמחכים שהקלפים ייהפכו בחזרה (1 שניה), חסמו לחיצות נוספות (דגל isChecking)
  • אל תאפשרו לחיצה על קלף שכבר גלוי או שכבר נמצא לו זוג
  • לערבוב Fisher-Yates:
function shuffle(array) {
  for (let i = array.length - 1; i > 0; i--) {
    let j = Math.floor(Math.random() * (i + 1));
    let temp = array[i];
    array[i] = array[j];
    array[j] = temp;
  }
  return array;
}
  • לטיימר, שמרו את זמן ההתחלה (Date.now()) וחשבו את ההפרש בכל שניה
  • הציון הטוב ביותר יכול להיות מבוסס על מספר מהלכים בלבד (פשוט יותר) או על שילוב של מהלכים וזמן