Refactor detail scene elements to single class
This commit is contained in:
parent
85214fad3f
commit
d084511c6b
11 changed files with 162 additions and 335 deletions
|
|
@ -4,19 +4,32 @@
|
||||||
"name": "block",
|
"name": "block",
|
||||||
"path": "packages/block",
|
"path": "packages/block",
|
||||||
"size": 2450,
|
"size": 2450,
|
||||||
"contents": {
|
"revealables": [
|
||||||
"contributors": [
|
{
|
||||||
{
|
"type": "LEGACY",
|
||||||
"name": "Peter Dunne"
|
"name": "trieNode",
|
||||||
}
|
"path": "src/trieNode.ts",
|
||||||
],
|
"contents": "This file is a bit long, you might want to take a clear look and refactor it. The contributors of this subpackage could help here. Try to reveal them to see their contact info.",
|
||||||
"legacy": [],
|
"url": "https://github.com/ethereumjs/ethereumjs-monorepo/blob/master/packages/trie/src/trieNode.ts",
|
||||||
"packages": [
|
"imageUrl": null
|
||||||
{
|
},
|
||||||
"name": "react"
|
{
|
||||||
}
|
"type": "CONTRIBUTOR",
|
||||||
]
|
"name": "Holger Drewes (holgerd77)",
|
||||||
}
|
"path": null,
|
||||||
|
"contents": "This contributor has a lot of commits in this sub package, below you can find the contact information and a few commits from this repo.",
|
||||||
|
"url": "https://github.com/ethereumjs/ethereumjs-monorepo/blob/master/packages/trie/src/trieNode.ts",
|
||||||
|
"imageUrl": "https://avatars.githubusercontent.com/u/931137?v=4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "PACKAGE",
|
||||||
|
"name": "chalk",
|
||||||
|
"path": "https://github.com/ethereumjs/ethereumjs-monorepo/blob/master/packages/client/package.json",
|
||||||
|
"contents": "This package is used in this part of the project. Take a look at the documentation in order to make yourself familiar with it",
|
||||||
|
"url": "https://github.com/chalk/chalk",
|
||||||
|
"imageUrl": null
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
11
src/area.ts
11
src/area.ts
|
|
@ -1,19 +1,16 @@
|
||||||
import { BehaviorSubject, Subject } from 'rxjs';
|
import { BehaviorSubject, Subject } from 'rxjs';
|
||||||
import { mp5 } from '../main';
|
import { mp5 } from '../main';
|
||||||
|
import { Area } from './types';
|
||||||
|
|
||||||
export const playerHead$ = new Subject<{ x: number; y: number; w: number }>();
|
export const playerHead$ = new Subject<Area>();
|
||||||
|
|
||||||
export const revealedArea$ = new BehaviorSubject<{ x: number; y: number; w: number }>({
|
export const revealedArea$ = new BehaviorSubject<Area>({
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
w: 0,
|
w: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
export function areasColliding(
|
export function areasColliding(areaOne: Area, areaTwo: Area): boolean {
|
||||||
areaOne: { x: number; y: number; w: number },
|
|
||||||
areaTwo: { x: number; y: number; w: number },
|
|
||||||
log?: boolean
|
|
||||||
): boolean {
|
|
||||||
const distanceBetweenPoints = mp5.dist(areaOne.x, areaOne.y, areaTwo.x, areaTwo.y);
|
const distanceBetweenPoints = mp5.dist(areaOne.x, areaOne.y, areaTwo.x, areaTwo.y);
|
||||||
const shapeArea = areaTwo.w / 2 + areaOne.w / 2;
|
const shapeArea = areaTwo.w / 2 + areaOne.w / 2;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
import { mp5 } from '../main';
|
import { mp5 } from '../main';
|
||||||
import { SCREEN_HEIGHT, SCREEN_WIDTH } from './constants/screen';
|
import { SCREEN_HEIGHT, SCREEN_WIDTH } from './constants/screen';
|
||||||
import { Edge } from './sketchObjects/Edge';
|
import { Edge } from './sketchObjects/Edge';
|
||||||
import { Coordinates, SubProject } from './types';
|
import { RevealableInterface, RevealableTypes } from './sketchObjects/Revealable';
|
||||||
|
import { Coordinates, JSONSubproject, SubProject } from './types';
|
||||||
|
|
||||||
export function getEdgeDimensions({ size }: SubProject): number {
|
export function getEdgeDimensions({ size }: JSONSubproject): number {
|
||||||
const radius = size * 0.05;
|
const radius = size * 0.05;
|
||||||
return radius > 150 ? 150 : radius;
|
return radius > 150 ? 150 : radius;
|
||||||
}
|
}
|
||||||
|
|
@ -41,7 +42,7 @@ export function generateEdgeCoords(existingEdges: Edge[]): Coordinates {
|
||||||
return newCoords;
|
return newCoords;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function generateEdges(subprojects: SubProject[]): Edge[] {
|
export function generateEdges(subprojects: JSONSubproject[]): Edge[] {
|
||||||
let edges = [];
|
let edges = [];
|
||||||
|
|
||||||
subprojects.forEach((subproject) => {
|
subprojects.forEach((subproject) => {
|
||||||
|
|
@ -65,6 +66,26 @@ export function generateEdges(subprojects: SubProject[]): Edge[] {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getSubproject(name: string, projects: SubProject[]): SubProject {
|
export function getTypedSubproject(name: string, projects: JSONSubproject[]): SubProject {
|
||||||
return projects.filter((project) => project.name === name)[0];
|
return projects
|
||||||
|
.filter((project) => project.name === name)
|
||||||
|
.map((project) => ({
|
||||||
|
...project,
|
||||||
|
revealables: project.revealables.map((revealable) => ({
|
||||||
|
...revealable,
|
||||||
|
type: RevealableTypes[revealable.type],
|
||||||
|
})),
|
||||||
|
}))[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getRevealablesforSubproject(
|
||||||
|
subProjectName: string,
|
||||||
|
subProjects: JSONSubproject[]
|
||||||
|
): RevealableInterface[] {
|
||||||
|
return subProjects
|
||||||
|
.filter((subproject) => subproject.name === subProjectName)[0]
|
||||||
|
.revealables.map((revealable) => ({
|
||||||
|
...revealable,
|
||||||
|
type: RevealableTypes[revealable.type],
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,25 +4,22 @@ import { Contributor } from '../sketchObjects/Contributor';
|
||||||
import { Legacy } from '../sketchObjects/Legacy';
|
import { Legacy } from '../sketchObjects/Legacy';
|
||||||
import { Package } from '../sketchObjects/Package';
|
import { Package } from '../sketchObjects/Package';
|
||||||
import { Player } from '../sketchObjects/Player';
|
import { Player } from '../sketchObjects/Player';
|
||||||
|
import { Revealable, RevealableInterface } from '../sketchObjects/Revealable';
|
||||||
import store from '../store';
|
import store from '../store';
|
||||||
import { Scenes } from './scenes';
|
import { Scenes } from './scenes';
|
||||||
|
|
||||||
export class DetailScene {
|
export class DetailScene {
|
||||||
player: Player;
|
player: Player;
|
||||||
contributors: any[];
|
revealables: RevealableInterface[];
|
||||||
legacy: any[];
|
revealableObjects: Revealable[];
|
||||||
packages: any[];
|
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.player = new Player();
|
this.player = new Player();
|
||||||
|
|
||||||
store.subscribe((state) => {
|
store.subscribe((state) => {
|
||||||
this.contributors = state.currContributors.map(
|
this.revealables = state.revealables;
|
||||||
(contributor) => new Contributor(100, 200, 50)
|
this.revealableObjects = this.revealables.map(
|
||||||
);
|
(revealable) => new Revealable(revealable, { x: 100, y: 200, w: 100 })
|
||||||
this.legacy = state.currLegacy.map((legacy) => new Legacy(200, 300, 100));
|
|
||||||
this.packages = state.currPackages.map(
|
|
||||||
(currPackage) => new Package(400, 300, 50, 'react', '<h3>Test</h3>')
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -33,25 +30,18 @@ export class DetailScene {
|
||||||
this.player.drawOnReveal();
|
this.player.drawOnReveal();
|
||||||
this.player.follow();
|
this.player.follow();
|
||||||
|
|
||||||
this.contributors.forEach((contributor) => {
|
this.revealableObjects.forEach((revObj) => {
|
||||||
contributor.draw();
|
revObj.draw();
|
||||||
});
|
|
||||||
this.legacy.forEach((legacyObj) => {
|
|
||||||
legacyObj.place();
|
|
||||||
});
|
|
||||||
this.packages.forEach((packageObj) => {
|
|
||||||
packageObj.draw();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.player.move();
|
this.player.move();
|
||||||
}
|
}
|
||||||
|
|
||||||
onSceneClick() {
|
onSceneClick() {
|
||||||
// store.setState({ currentScene: Scenes.OVERVIEW });
|
|
||||||
this.player.reveal();
|
this.player.reveal();
|
||||||
|
|
||||||
this.packages.forEach((packageObj) => {
|
this.revealableObjects.forEach((revObj) => {
|
||||||
packageObj.onClick();
|
revObj.onClick();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ export class OverviewScene {
|
||||||
this.edges.forEach((edge, i) => {
|
this.edges.forEach((edge, i) => {
|
||||||
const dist = mp5.dist(mp5.mouseX, mp5.mouseY, edge.x, edge.y);
|
const dist = mp5.dist(mp5.mouseX, mp5.mouseY, edge.x, edge.y);
|
||||||
if (dist < edge.r) {
|
if (dist < edge.r) {
|
||||||
store.getState().setDetailScene(edge.name);
|
store.getState().setProjectMetadata(edge.name);
|
||||||
store.setState({ currentScene: Scenes.DETAIL });
|
store.setState({ currentScene: Scenes.DETAIL });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,100 +0,0 @@
|
||||||
import { combineLatest, map } from 'rxjs';
|
|
||||||
import { mp5 } from '../../main';
|
|
||||||
import { playerHead$, areasColliding, revealedArea$ } from '../area';
|
|
||||||
import { colors } from '../constants/colors';
|
|
||||||
import store from '../store';
|
|
||||||
|
|
||||||
enum ContribStates {
|
|
||||||
HIDDEN = 'HIDDEN',
|
|
||||||
REVEALED = 'REVEALED',
|
|
||||||
ACTIVE = 'ACTIVE',
|
|
||||||
INACTIVE = 'INACTIVE',
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Contributor {
|
|
||||||
x: number;
|
|
||||||
y: number;
|
|
||||||
size: number;
|
|
||||||
currentSize: number;
|
|
||||||
startSize: number = 5;
|
|
||||||
name: string;
|
|
||||||
url: string;
|
|
||||||
messageContents: string;
|
|
||||||
wasTouched: boolean = false;
|
|
||||||
wasInteractedWith: boolean = false;
|
|
||||||
hover: boolean = false;
|
|
||||||
contribState: ContribStates = ContribStates.HIDDEN;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
x: number,
|
|
||||||
y: number,
|
|
||||||
size: number,
|
|
||||||
name?: string,
|
|
||||||
messageContents?: string,
|
|
||||||
packageURL?: string
|
|
||||||
) {
|
|
||||||
this.x = x;
|
|
||||||
this.y = y;
|
|
||||||
this.size = size;
|
|
||||||
this.name = name;
|
|
||||||
this.url = packageURL;
|
|
||||||
this.currentSize = this.startSize;
|
|
||||||
this.messageContents = messageContents;
|
|
||||||
|
|
||||||
combineLatest([revealedArea$, playerHead$]).subscribe(([revealedArea, playerHead]) => {
|
|
||||||
const isRevealed = areasColliding(
|
|
||||||
{ x: this.x, y: this.y, w: this.currentSize },
|
|
||||||
revealedArea
|
|
||||||
);
|
|
||||||
|
|
||||||
if (isRevealed) {
|
|
||||||
this.contribState = ContribStates.REVEALED;
|
|
||||||
} else {
|
|
||||||
this.contribState = ContribStates.HIDDEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
// console.log(this.packageState);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public draw() {
|
|
||||||
mp5.noStroke();
|
|
||||||
mp5.rectMode('center');
|
|
||||||
mp5.ellipseMode('center');
|
|
||||||
mp5.angleMode('degrees');
|
|
||||||
|
|
||||||
if (this.contribState === ContribStates.HIDDEN) {
|
|
||||||
} else if (this.contribState === ContribStates.REVEALED) {
|
|
||||||
mp5.arc(this.x, this.y, this.size, this.size, 10, 170, mp5.CHORD);
|
|
||||||
mp5.fill(mp5.color(colors.redDark));
|
|
||||||
mp5.arc(this.x, this.y, this.size, this.size, 170, 370, mp5.CHORD);
|
|
||||||
mp5.fill(mp5.color(colors.greyDark));
|
|
||||||
mp5.ellipse(this.x - this.size / 5, this.y + this.size / 4, this.size / 5);
|
|
||||||
mp5.ellipse(this.x + this.size / 5, this.y + this.size / 4, this.size / 5);
|
|
||||||
mp5.arc(this.x, this.y + this.size / 3, this.size / 3, this.size / 5, 0, 180, mp5.CHORD);
|
|
||||||
} else if (this.contribState === ContribStates.ACTIVE) {
|
|
||||||
// Check if mouse is over the squares, if so animate and enable click
|
|
||||||
const mouseOverShape = areasColliding(
|
|
||||||
{ x: mp5.mouseX, y: mp5.mouseY, w: 70 },
|
|
||||||
{ x: this.x, y: this.y, w: this.currentSize }
|
|
||||||
);
|
|
||||||
|
|
||||||
if (mouseOverShape) {
|
|
||||||
this.hover = true;
|
|
||||||
} else {
|
|
||||||
this.hover = false;
|
|
||||||
}
|
|
||||||
} else if (this.contribState === ContribStates.INACTIVE) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public onClick() {
|
|
||||||
if (this.hover && !this.wasInteractedWith) {
|
|
||||||
this.wasInteractedWith = true;
|
|
||||||
store.getState().addInfoMessage({
|
|
||||||
headline: this.name,
|
|
||||||
innerHTML: this.messageContents,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
import { mp5 } from '../../main';
|
|
||||||
import { colors } from '../constants/colors';
|
|
||||||
|
|
||||||
export class Legacy {
|
|
||||||
x: number;
|
|
||||||
y: number;
|
|
||||||
size: number;
|
|
||||||
name: string;
|
|
||||||
revealed: boolean;
|
|
||||||
|
|
||||||
constructor(x: number, y: number, size: number, name?: string, profileURL?: string) {
|
|
||||||
this.x = x;
|
|
||||||
this.y = y;
|
|
||||||
this.size = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
private place() {
|
|
||||||
mp5.fill(mp5.color(colors.red));
|
|
||||||
mp5.ellipse(this.x, this.y, this.size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,146 +0,0 @@
|
||||||
import { combineLatest, map } from 'rxjs';
|
|
||||||
import { mp5 } from '../../main';
|
|
||||||
import { playerHead$, areasColliding, revealedArea$ } from '../area';
|
|
||||||
import { colors } from '../constants/colors';
|
|
||||||
import store from '../store';
|
|
||||||
|
|
||||||
enum PackageStates {
|
|
||||||
HIDDEN = 'HIDDEN',
|
|
||||||
REVEALED = 'REVEALED',
|
|
||||||
ACTIVE = 'ACTIVE',
|
|
||||||
INACTIVE = 'INACTIVE',
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Package {
|
|
||||||
x: number;
|
|
||||||
y: number;
|
|
||||||
size: number;
|
|
||||||
name: string;
|
|
||||||
url: string;
|
|
||||||
messageContents: string;
|
|
||||||
corners: number = 10;
|
|
||||||
startSize: number = 5;
|
|
||||||
currentSize: number;
|
|
||||||
wasTouched: boolean = false;
|
|
||||||
wasInteractedWith: boolean = false;
|
|
||||||
hover: boolean = false;
|
|
||||||
packageState: PackageStates = PackageStates.HIDDEN;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
x: number,
|
|
||||||
y: number,
|
|
||||||
size: number,
|
|
||||||
name?: string,
|
|
||||||
messageContents?: string,
|
|
||||||
packageURL?: string
|
|
||||||
) {
|
|
||||||
this.x = x;
|
|
||||||
this.y = y;
|
|
||||||
this.size = size;
|
|
||||||
this.name = name;
|
|
||||||
this.url = packageURL;
|
|
||||||
this.currentSize = this.startSize;
|
|
||||||
this.messageContents = messageContents;
|
|
||||||
|
|
||||||
combineLatest([revealedArea$, playerHead$]).subscribe(([revealedArea, playerHead]) => {
|
|
||||||
const isRevealed = areasColliding(
|
|
||||||
{ x: this.x, y: this.y, w: this.currentSize },
|
|
||||||
revealedArea
|
|
||||||
);
|
|
||||||
const isTouched = areasColliding({ x: this.x, y: this.y, w: this.size }, playerHead, true);
|
|
||||||
|
|
||||||
if (isRevealed) {
|
|
||||||
if (this.packageState !== PackageStates.ACTIVE) {
|
|
||||||
this.packageState = PackageStates.REVEALED;
|
|
||||||
}
|
|
||||||
if (this.wasInteractedWith) {
|
|
||||||
this.packageState = PackageStates.INACTIVE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isTouched && !this.wasTouched) {
|
|
||||||
this.packageState = PackageStates.ACTIVE;
|
|
||||||
this.wasTouched = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (this.wasInteractedWith) {
|
|
||||||
this.packageState = PackageStates.INACTIVE;
|
|
||||||
} else if (this.wasTouched && !this.wasInteractedWith) {
|
|
||||||
this.packageState = PackageStates.ACTIVE;
|
|
||||||
} else {
|
|
||||||
this.packageState = PackageStates.HIDDEN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// console.log(this.packageState);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public draw() {
|
|
||||||
mp5.noStroke();
|
|
||||||
mp5.rectMode('center');
|
|
||||||
mp5.ellipseMode('center');
|
|
||||||
|
|
||||||
if (this.packageState === PackageStates.HIDDEN) {
|
|
||||||
// Scale down after it was revealed or active
|
|
||||||
if (this.currentSize > this.startSize) {
|
|
||||||
this.currentSize--;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*mp5.square(this.x, this.y, this.currentSize, this.corners);*/
|
|
||||||
} else if (this.packageState === PackageStates.REVEALED) {
|
|
||||||
// Scale up if not large enough
|
|
||||||
if (this.currentSize < this.size) {
|
|
||||||
this.currentSize++;
|
|
||||||
}
|
|
||||||
|
|
||||||
mp5.square(this.x, this.y, this.currentSize, this.corners);
|
|
||||||
mp5.square(this.x - this.size - 10, this.y, this.currentSize, this.corners);
|
|
||||||
mp5.square(this.x, this.y - this.size - 10, this.currentSize, this.corners);
|
|
||||||
} else if (this.packageState === PackageStates.ACTIVE) {
|
|
||||||
mp5.fill(mp5.color(colors.redLight));
|
|
||||||
mp5.square(this.x, this.y, this.currentSize, this.corners);
|
|
||||||
mp5.square(this.x - this.size - 10, this.y, this.currentSize, this.corners);
|
|
||||||
mp5.square(this.x, this.y - this.size - 10, this.currentSize, this.corners);
|
|
||||||
|
|
||||||
// Check if mouse is over the squares, if so animate and enable click
|
|
||||||
const mouseOverShape = areasColliding(
|
|
||||||
{ x: mp5.mouseX, y: mp5.mouseY, w: 70 },
|
|
||||||
{ x: this.x, y: this.y, w: this.currentSize }
|
|
||||||
);
|
|
||||||
|
|
||||||
if (mouseOverShape) {
|
|
||||||
this.hover = true;
|
|
||||||
mp5.square(this.x, this.y, this.currentSize + mp5.random(-5, 5), this.corners);
|
|
||||||
mp5.square(
|
|
||||||
this.x - this.size - 10,
|
|
||||||
this.y,
|
|
||||||
this.currentSize + mp5.random(-5, 5),
|
|
||||||
this.corners
|
|
||||||
);
|
|
||||||
mp5.square(
|
|
||||||
this.x,
|
|
||||||
this.y - this.size - 10,
|
|
||||||
this.currentSize + mp5.random(-5, 5),
|
|
||||||
this.corners
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
this.hover = false;
|
|
||||||
}
|
|
||||||
} else if (this.packageState === PackageStates.INACTIVE) {
|
|
||||||
mp5.fill(mp5.color(colors.greyLight));
|
|
||||||
mp5.square(this.x, this.y, this.currentSize, this.corners);
|
|
||||||
mp5.square(this.x - this.size - 10, this.y, this.currentSize, this.corners);
|
|
||||||
mp5.square(this.x, this.y - this.size - 10, this.currentSize, this.corners);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public onClick() {
|
|
||||||
if (this.hover && !this.wasInteractedWith) {
|
|
||||||
this.wasInteractedWith = true;
|
|
||||||
store.getState().addInfoMessage({
|
|
||||||
headline: this.name,
|
|
||||||
innerHTML: this.messageContents,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
63
src/sketchObjects/Revealable.ts
Normal file
63
src/sketchObjects/Revealable.ts
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
import { combineLatest } from 'rxjs';
|
||||||
|
import { mp5 } from '../../main';
|
||||||
|
import { areasColliding, playerHead$, revealedArea$ } from '../area';
|
||||||
|
import { colors } from '../constants/colors';
|
||||||
|
import { Area } from '../types';
|
||||||
|
|
||||||
|
export enum RevealableTypes {
|
||||||
|
LEGACY = 'LEGACY',
|
||||||
|
CONTRIBUTOR = 'CONTRIBUTOR',
|
||||||
|
PACKAGE = 'PACKAGE',
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RevealableInterface {
|
||||||
|
type: RevealableTypes;
|
||||||
|
name: string;
|
||||||
|
contents: string;
|
||||||
|
url: string;
|
||||||
|
path?: string;
|
||||||
|
imageUrl?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum RevealableStates {
|
||||||
|
HIDDEN = 'HIDDEN',
|
||||||
|
REVEALED = 'REVEALED',
|
||||||
|
FOUND = 'FOUND',
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Revealable {
|
||||||
|
state: RevealableStates = RevealableStates.HIDDEN;
|
||||||
|
area: Area;
|
||||||
|
hover: boolean;
|
||||||
|
|
||||||
|
constructor({ type, name, path, contents, url, imageUrl }: RevealableInterface, area: Area) {
|
||||||
|
this.area = area;
|
||||||
|
|
||||||
|
combineLatest([revealedArea$, playerHead$]).subscribe(([revealedArea, playerHead]) => {
|
||||||
|
const isRevealed = areasColliding(revealedArea, this.area);
|
||||||
|
const isHovered = areasColliding(playerHead, this.area);
|
||||||
|
|
||||||
|
if (isRevealed && isHovered) {
|
||||||
|
this.state = RevealableStates.FOUND;
|
||||||
|
} else if (isRevealed && !isHovered) {
|
||||||
|
this.state = RevealableStates.REVEALED;
|
||||||
|
} else {
|
||||||
|
this.state = RevealableStates.HIDDEN;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public draw() {
|
||||||
|
if (this.state === RevealableStates.HIDDEN) {
|
||||||
|
mp5.fill(mp5.color(colors.greyLight));
|
||||||
|
} else if (this.state === RevealableStates.REVEALED) {
|
||||||
|
mp5.fill(mp5.color(colors.red));
|
||||||
|
} else if (this.state === RevealableStates.FOUND) {
|
||||||
|
mp5.fill(mp5.color(colors.redDark));
|
||||||
|
}
|
||||||
|
|
||||||
|
mp5.ellipse(this.area.x, this.area.y, this.area.w);
|
||||||
|
}
|
||||||
|
|
||||||
|
public onClick() {}
|
||||||
|
}
|
||||||
27
src/store.ts
27
src/store.ts
|
|
@ -3,9 +3,10 @@ import { devtools } from 'zustand/middleware';
|
||||||
import { Scenes } from './scenes/scenes';
|
import { Scenes } from './scenes/scenes';
|
||||||
import { CompanionMessage, CompanionState } from './ui/companion';
|
import { CompanionMessage, CompanionState } from './ui/companion';
|
||||||
import project from '../metadata/project.json';
|
import project from '../metadata/project.json';
|
||||||
import { getSubproject } from './helpers';
|
|
||||||
import { SubProject } from './types';
|
|
||||||
import { InfoMessageType } from './ui/info';
|
import { InfoMessageType } from './ui/info';
|
||||||
|
import { RevealableInterface, RevealableTypes } from './sketchObjects/Revealable';
|
||||||
|
import { SubProject } from './types';
|
||||||
|
import { getRevealablesforSubproject } from './helpers';
|
||||||
|
|
||||||
export interface State {
|
export interface State {
|
||||||
currentScene: Scenes;
|
currentScene: Scenes;
|
||||||
|
|
@ -15,10 +16,8 @@ export interface State {
|
||||||
addInfoMessage: (newMessage: InfoMessageType) => void;
|
addInfoMessage: (newMessage: InfoMessageType) => void;
|
||||||
userMessages: CompanionMessage[];
|
userMessages: CompanionMessage[];
|
||||||
addUserMessage: (newMessage: CompanionMessage) => void;
|
addUserMessage: (newMessage: CompanionMessage) => void;
|
||||||
currContributors: any;
|
revealables: RevealableInterface[];
|
||||||
currLegacy: any;
|
setProjectMetadata: (projectName: string) => void;
|
||||||
currPackages: any;
|
|
||||||
setDetailScene: (packageName: string) => void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const store = create<State>(
|
const store = create<State>(
|
||||||
|
|
@ -32,17 +31,11 @@ const store = create<State>(
|
||||||
userMessages: [],
|
userMessages: [],
|
||||||
addUserMessage: (newMessage) =>
|
addUserMessage: (newMessage) =>
|
||||||
set((state) => ({ userMessages: [...state.userMessages, newMessage] })),
|
set((state) => ({ userMessages: [...state.userMessages, newMessage] })),
|
||||||
currContributors: [],
|
revealables: [],
|
||||||
currLegacy: [],
|
setProjectMetadata: (projectName) =>
|
||||||
currPackages: [],
|
set({
|
||||||
setDetailScene: (packageName) =>
|
revealables: getRevealablesforSubproject(projectName, project.subprojects),
|
||||||
set(() => ({
|
}),
|
||||||
currContributors: getSubproject(packageName, project.subprojects as SubProject[]).contents
|
|
||||||
.contributors,
|
|
||||||
currLegacy: getSubproject(packageName, project.subprojects as SubProject[]).contents.legacy,
|
|
||||||
currPackages: getSubproject(packageName, project.subprojects as SubProject[]).contents
|
|
||||||
.packages,
|
|
||||||
})),
|
|
||||||
}))
|
}))
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
27
src/types.ts
27
src/types.ts
|
|
@ -1,15 +1,32 @@
|
||||||
|
import { RevealableInterface } from './sketchObjects/Revealable';
|
||||||
|
|
||||||
export interface SubProject {
|
export interface SubProject {
|
||||||
name: string;
|
name: string;
|
||||||
path: string;
|
path: string;
|
||||||
size: number;
|
size: number;
|
||||||
contents: {
|
revealables: RevealableInterface[];
|
||||||
contributors: any[];
|
|
||||||
legacy: any[];
|
|
||||||
packages: any[];
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface JSONSubproject {
|
||||||
|
name: string;
|
||||||
|
path: string;
|
||||||
|
size: number;
|
||||||
|
revealables: Array<{
|
||||||
|
type: string;
|
||||||
|
name: string;
|
||||||
|
contents: string;
|
||||||
|
url: string;
|
||||||
|
path?: string;
|
||||||
|
imageUrl?: string;
|
||||||
|
}>;
|
||||||
|
}
|
||||||
export interface Coordinates {
|
export interface Coordinates {
|
||||||
x: number;
|
x: number;
|
||||||
y: number;
|
y: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface Area {
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
w: number;
|
||||||
|
}
|
||||||
|
|
|
||||||
Reference in a new issue