diff --git a/index.html b/index.html index 3788b5f..d4d0e2f 100644 --- a/index.html +++ b/index.html @@ -23,8 +23,12 @@
-

Test

+
+

Test

+ +
Test
+ Check this out on Github
revObj.wasInteractedWith) && !(store.getState().companionState === CompanionState.ACTIVE) ) { + store.setState((state) => ({ + finishedSubProjects: [...state.finishedSubProjects, state.currentSubproject], + })); + store.getState().addUserMessage({ text: "Yaay! You've found all of the important parts of this part of the repository. You will be returned to the subproject overview now. Pick the next subproject you want to take a look at there.", inputWanted: false, diff --git a/src/scenes/OverviewScene.ts b/src/scenes/OverviewScene.ts index 5fde1e7..1dba359 100644 --- a/src/scenes/OverviewScene.ts +++ b/src/scenes/OverviewScene.ts @@ -6,9 +6,12 @@ import store from '../store'; import { generateEdges } from '../helpers'; import { Scenes } from './scenes'; import projectMetadata from '../../metadata/project.json'; +import { playerHead$ } from '../area'; +import { Area } from '../types'; export class OverviewScene { player: Player; + playerHead: Area; edges: Edge[]; constructor() { @@ -29,12 +32,18 @@ export class OverviewScene { const dist = mp5.dist(mp5.mouseX, mp5.mouseY, edge.x, edge.y); if (dist < edge.r) { store.getState().setProjectMetadata(edge.name); - store.setState({ currentScene: Scenes.DETAIL }); + store.setState({ currentSubproject: edge.name, currentScene: Scenes.DETAIL }); } }); } private drawLocations() { - this.edges.forEach((edgeShape) => edgeShape.draw()); + this.edges.forEach((edgeShape) => { + if (store.getState().finishedSubProjects.some((fsp) => fsp === edgeShape.name)) { + edgeShape.finished = true; + } + + edgeShape.draw(); + }); } } diff --git a/src/sketchObjects/Edge.ts b/src/sketchObjects/Edge.ts index a521ee8..a258aef 100644 --- a/src/sketchObjects/Edge.ts +++ b/src/sketchObjects/Edge.ts @@ -1,4 +1,5 @@ import { mp5 } from '../../main'; +import { areasColliding, playerHead$ } from '../area'; import { colors } from '../constants/colors'; export class Edge { @@ -7,18 +8,58 @@ export class Edge { r: number; name: string; + currentSize: number; + maxSize: number; + isHovered: boolean; + hoverColor: any; + + finished: boolean; + constructor({ x, y, r, name }: { x: number; y: number; r: number; name: string }) { this.x = x; this.y = y; this.r = r; this.name = name; + this.maxSize = r * 2 + 20; + this.currentSize = r * 2; + this.hoverColor = mp5.color(colors.red); + this.hoverColor.setAlpha(200); + + playerHead$.subscribe((playerHead) => { + this.isHovered = areasColliding(playerHead, { x: this.x, y: this.y, w: this.r * 2 }); + }); } draw() { - mp5.fill(mp5.color(colors.grey)); - mp5.ellipse(this.x, this.y, this.r * 2); - mp5.textSize(20); - mp5.fill(0); - mp5.text(this.name, this.x, this.y); + if (this.finished) { + mp5.fill(mp5.color(colors.greyLight)); + mp5.ellipse(this.x, this.y, this.r * 2); + mp5.textSize(20); + mp5.fill(mp5.color(colors.grey)); + mp5.text(`packages/${this.name}`, this.x - this.r / 2, this.y); + } else { + mp5.fill(mp5.color(colors.grey)); + + if (this.isHovered) { + mp5.fill(mp5.color(this.hoverColor)); + + if (this.currentSize < this.maxSize) { + this.currentSize++; + } else { + this.currentSize = this.maxSize; + } + } else { + if (this.currentSize > this.r * 2) { + this.currentSize--; + } else { + this.currentSize = this.r * 2; + } + } + + mp5.ellipse(this.x, this.y, this.currentSize); + mp5.textSize(20); + mp5.fill(mp5.color(colors.black)); + mp5.text(`packages/${this.name}`, this.x - this.r / 2, this.y); + } } } diff --git a/src/sketchObjects/Revealable.ts b/src/sketchObjects/Revealable.ts index 60dabb4..98aed78 100644 --- a/src/sketchObjects/Revealable.ts +++ b/src/sketchObjects/Revealable.ts @@ -122,6 +122,8 @@ export class Revealable { store.getState().addInfoMessage({ headline: this.name, innerHTML: this.contents, + imgUrl: this.imageUrl, + url: this.url, }); } } diff --git a/src/store.ts b/src/store.ts index b692f2d..1e0b677 100644 --- a/src/store.ts +++ b/src/store.ts @@ -6,9 +6,11 @@ import project from '../metadata/project.json'; import { InfoMessageType } from './ui/info'; import { RevealableInterface, RevealableTypes } from './sketchObjects/Revealable'; import { getRevealablesforSubproject } from './helpers'; +import { SubProject } from './types'; export interface State { currentScene: Scenes; + currentSubproject?: string; companionState: CompanionState; infoMessageShown: boolean; infoMessages: InfoMessageType[]; @@ -16,12 +18,14 @@ export interface State { userMessages: CompanionMessage[]; addUserMessage: (newMessage: CompanionMessage) => void; revealables: RevealableInterface[]; + finishedSubProjects: string[]; setProjectMetadata: (projectName: string) => void; } const store = create( devtools((set) => ({ currentScene: Scenes.OVERVIEW, + currentSubproject: null, companionState: CompanionState.IDLE, infoMessageShown: false, infoMessages: [], @@ -33,6 +37,7 @@ const store = create( userMessages: [...state.userMessages, newMessage], })), revealables: [], + finishedSubProjects: [], setProjectMetadata: (projectName) => set((state) => ({ ...state, diff --git a/src/ui/info.ts b/src/ui/info.ts index c69df7d..d434108 100644 --- a/src/ui/info.ts +++ b/src/ui/info.ts @@ -3,6 +3,8 @@ import store from '../store'; export interface InfoMessageType { headline: string; innerHTML: string; + imgUrl?: string; + url?: string; } export class InfoMessage { @@ -10,6 +12,8 @@ export class InfoMessage { infoMessageHeadline: HTMLElement; infoMessageContents: HTMLElement; infoMessageClose: HTMLElement; + infoMessageImgRef: HTMLImageElement; + infoMessageLinkRef: HTMLAnchorElement; backdrop: HTMLElement; constructor() { @@ -17,6 +21,8 @@ export class InfoMessage { this.infoMessageHeadline = document.getElementById('info-message-headline'); this.infoMessageContents = document.getElementById('info-message-contents'); this.infoMessageClose = document.getElementById('info-message-close'); + this.infoMessageImgRef = document.getElementById('info-message-img') as HTMLImageElement; + this.infoMessageLinkRef = document.getElementById('info-message-link') as HTMLAnchorElement; this.backdrop = document.getElementById('backdrop'); this.backdrop.addEventListener('click', this.onBackdropClick); @@ -32,6 +38,19 @@ export class InfoMessage { if (state.infoMessages.length > prevState.infoMessages.length) { const newMessage = state.infoMessages[state.infoMessages.length - 1]; this.setContents(newMessage.headline, newMessage.innerHTML); + + if (newMessage.imgUrl) { + this.setImg(newMessage.imgUrl); + } else { + this.infoMessageImgRef.style.display = 'none'; + } + + if (newMessage.url) { + this.setLink(newMessage.url); + } else { + this.infoMessageLinkRef.style.display = 'none'; + } + store.setState({ infoMessageShown: true }); } }); @@ -42,6 +61,16 @@ export class InfoMessage { this.infoMessageContents.innerHTML = innerHTML; } + private setImg(imgUrl: string) { + this.infoMessageImgRef.src = imgUrl; + this.infoMessageImgRef.style.display = 'block'; + } + + private setLink(url: string) { + this.infoMessageLinkRef.href = url; + this.infoMessageLinkRef.style.display = 'block'; + } + private show() { this.infoMessage.style.display = 'block'; this.backdrop.style.display = 'block'; diff --git a/styles.scss b/styles.scss index c97cf80..c254d7f 100644 --- a/styles.scss +++ b/styles.scss @@ -149,6 +149,8 @@ button { z-index: 10; top: 50%; left: 50%; + min-width: 60%; + max-width: 90%; transform: translate(-50%, -50%); background-color: #fff; padding: 2.5rem 4rem; @@ -157,10 +159,44 @@ button { box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); - #info-message-headline { - margin: 0; - padding-bottom: 1rem; + #info-message-header { + display: flex; + justify-content: space-between; + align-items: flex-end; + margin-bottom: 25px; + + #info-message-img { + display: none; + height: 100px; + width: 100px; + border-radius: 50%; + } + + #info-message-headline { + margin: 0; + text-align: center; + } + } + + #info-message-link { + display: none; + min-width: 20%; + padding: 6px 15px; + background-color: transparent; + border: 2px solid black; + border-radius: 5px; + font-weight: bold; + text-decoration: none; + color: black; text-align: center; + margin-top: 50px; + float: right; + + &:hover { + cursor: pointer; + background-color: black; + color: white; + } } #info-message-close {