Added Image with Multiple CHoice

This commit is contained in:
2025-09-11 20:24:52 +02:00
parent 8ce77c1250
commit c1b44c081a
7 changed files with 141 additions and 47 deletions

View File

@@ -35,4 +35,23 @@
.card:hover {
background-color: rgba(0, 0, 0, 0.1);
}
.choiceCard {
border: 1px solid black;
border-radius: 5px;
display: flex;
align-items: center;
justify-content: center;
height: fit-content;
padding: 32px;
/* font-size: larger;
font-weight: bold;
cursor: pointer; */
}
.choice-answer {
background-color: rgb(87, 255, 87);
box-shadow: 0 0 20px 5px rgb(87, 255, 87);
border: 1px solid rgb(50, 141, 50);
}
}

View File

@@ -48,31 +48,10 @@
{#if showQuestion}
<div class="flex w-full grow-1 flex-wrap items-center justify-around gap-2">
{#each _choices as choice}
<div class="choiceCard {showAnswer && choice === answer ? 'answer' : ''}">
<div class="choiceCard {showAnswer && choice === answer ? 'choice-answer' : ''}">
{choice}
</div>
{/each}
</div>
{/if}
</div>
<style>
.choiceCard {
border: 1px solid black;
border-radius: 5px;
display: flex;
align-items: center;
justify-content: center;
height: fit-content;
padding: 32px;
/* font-size: larger;
font-weight: bold;
cursor: pointer; */
}
.answer {
background-color: rgb(87, 255, 87);
box-shadow: 0 0 20px 5px rgb(87, 255, 87);
border: 1px solid rgb(50, 141, 50);
}
</style>

View File

@@ -0,0 +1,76 @@
<script lang="ts">
import type { ImageMultipleChoiceQuestion } from "./games/games";
const path = "/images/";
interface Props {
question: ImageMultipleChoiceQuestion;
showAnswer: boolean;
showQuestion: boolean;
isBuzzed: boolean;
[key: string]: unknown;
}
function shuffle<T>(array: T[]) {
let currentIndex = array.length;
// While there remain elements to shuffle...
while (currentIndex != 0) {
// Pick a remaining element...
let randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex--;
// And swap it with the current element.
[array[currentIndex], array[randomIndex]] = [array[randomIndex], array[currentIndex]];
}
}
let { question, showAnswer, showQuestion, isBuzzed }: Props = $props();
const answer = question.data.choices[0];
let _choices = [...question.data.choices];
shuffle(_choices);
</script>
<div class="mb-4 flex w-full grow flex-col items-center gap-2 text-6xl">
{#if showQuestion}
<div class="flex grow items-center">
<div class="text-center">{question.data.question}</div>
</div>
<div class="container grow-6">
<img
src={path + question.data.image}
alt={path + question.data.image}
class={isBuzzed ? "blurry" : ""}
/>
</div>
<div class="flex w-full grow-1 flex-wrap items-center justify-around gap-2">
{#each _choices as choice}
<div class="choiceCard {showAnswer && choice === answer ? 'choice-answer' : ''}">
{choice}
</div>
{/each}
</div>
{/if}
</div>
<style>
.container {
position: relative;
}
.container > img {
position: absolute;
top: 50%;
left: 50%;
max-height: 100%;
max-width: 100%;
display: block;
transform: translate(-50%, -50%);
}
.blurry {
filter: blur(60px);
}
</style>

View File

@@ -37,31 +37,10 @@
</div>
<div class="flex w-full grow-1 flex-wrap items-center justify-around gap-2">
{#each _choices as choice}
<div class="choiceCard {showAnswer && choice === answer ? 'answer' : ''}">
<div class="choiceCard {showAnswer && choice === answer ? 'choice-answer' : ''}">
{choice}
</div>
{/each}
</div>
{/if}
</div>
<style>
.choiceCard {
border: 1px solid black;
border-radius: 5px;
display: flex;
align-items: center;
justify-content: center;
height: fit-content;
padding: 32px;
/* font-size: larger;
font-weight: bold;
cursor: pointer; */
}
.answer {
background-color: rgb(87, 255, 87);
box-shadow: 0 0 20px 5px rgb(87, 255, 87);
border: 1px solid rgb(50, 141, 50);
}
</style>

View File

@@ -37,11 +37,18 @@ const games: Games = [
},
{
points: 300,
type: "IMAGE",
type: "IMAGE_MULTIPLE_CHOICE",
data: {
question: "Question 3?",
image: "test/secondImage.jpg",
answer: "Answer 3"
choices: [
"Choice 1",
"Choice 2",
"Choice 3",
"Choice 4",
"Choice 5",
"Choice 6"
]
}
},
{
@@ -1237,6 +1244,7 @@ export type QuestionType =
| "SIMPLE"
| "MULTIPLE_CHOICE"
| "IMAGE"
| "IMAGE_MULTIPLE_CHOICE"
| "AUDIO"
| "AUDIO_MULTIPLE_CHOICE";
@@ -1273,6 +1281,15 @@ export type ImageQuestion = Question & {
};
};
export type ImageMultipleChoiceQuestion = Question & {
type: "IMAGE_MULTIPLE_CHOICE";
data: {
question: string;
image: string;
choices: string[];
};
};
export type AudioQuestion = Question & {
type: "AUDIO";
data: {
@@ -1300,6 +1317,11 @@ export function isMultipleChoiceQuestion(question: Question): question is Multip
export function isImageQuestion(question: Question): question is ImageQuestion {
return (question as ImageQuestion).type === "IMAGE";
}
export function isImageMultipleChoiceQuestion(
question: Question
): question is ImageMultipleChoiceQuestion {
return (question as ImageMultipleChoiceQuestion).type === "IMAGE_MULTIPLE_CHOICE";
}
export function isAudioQuestion(question: Question): question is AudioQuestion {
return (question as AudioQuestion).type === "AUDIO";
}
@@ -1315,6 +1337,7 @@ export type Category = {
| SimpleQuestion
| MultipleChoiceQuestion
| ImageQuestion
| ImageMultipleChoiceQuestion
| AudioQuestion
| AudioMultipleChoiceQuestion
)[];

View File

@@ -6,6 +6,7 @@
import {
isAudioMultipleChoiceQuestion,
isAudioQuestion,
isImageMultipleChoiceQuestion,
isImageQuestion,
isMultipleChoiceQuestion,
isSimpleQuestion
@@ -17,6 +18,7 @@
import ImageQuestionComponent from "$lib/ImageQuestionComponent.svelte";
import AudioQuestionComponent from "$lib/AudioQuestionComponent.svelte";
import AudioMultipleChoiceQuestionComponent from "$lib/AudioMultipleChoiceQuestionComponent.svelte";
import ImageMultipleChoiceQuestionComponent from "$lib/ImageMultipleChoiceQuestionComponent.svelte";
console.log("wall:", page.params.wall);
@@ -134,6 +136,13 @@
<MultipleChoiceQuestionComponent {question} {showAnswer} {showQuestion} />
{:else if isImageQuestion(question)}
<ImageQuestionComponent {question} {showAnswer} {showQuestion} {isBuzzed} />
{:else if isImageMultipleChoiceQuestion(question)}
<ImageMultipleChoiceQuestionComponent
{question}
{showAnswer}
{showQuestion}
{isBuzzed}
/>
{:else if isAudioQuestion(question)}
<AudioQuestionComponent {question} {showAnswer} {showQuestion} showPlayer={false} />
{:else if isAudioMultipleChoiceQuestion(question)}

View File

@@ -8,7 +8,8 @@
isImageQuestion,
type Game,
isAudioQuestion,
isAudioMultipleChoiceQuestion
isAudioMultipleChoiceQuestion,
isImageMultipleChoiceQuestion
} from "$lib/games/games";
import ws from "$lib/websocket.svelte";
import { page } from "$app/state";
@@ -22,6 +23,7 @@
import ImageQuestionComponent from "$lib/ImageQuestionComponent.svelte";
import AudioQuestionComponent from "$lib/AudioQuestionComponent.svelte";
import AudioMultipleChoiceQuestionComponent from "$lib/AudioMultipleChoiceQuestionComponent.svelte";
import ImageMultipleChoiceQuestionComponent from "$lib/ImageMultipleChoiceQuestionComponent.svelte";
let startDisabled = $state(true);
@@ -370,6 +372,13 @@
showQuestion={true}
isBuzzed={false}
/>
{:else if isImageMultipleChoiceQuestion(gameManager.question)}
<ImageMultipleChoiceQuestionComponent
question={gameManager.question}
showAnswer={true}
showQuestion={true}
isBuzzed={false}
/>
{:else if isAudioQuestion(gameManager.question)}
<AudioQuestionComponent
question={gameManager.question}