master
= 4 years ago
parent 4e6df6ebd0
commit 6634947107
  1. 3
      .prettierrc
  2. 11
      package-lock.json
  3. 3
      webclient/package.json
  4. 152
      webclient/src/Footer.js
  5. 25
      webclient/src/light.css
  6. 65
      webclient/src/spaceport/Ship.js
  7. 5
      webclient/yarn.lock

@ -0,0 +1,3 @@
{
"singleQuote": true
}

11
package-lock.json generated

@ -0,0 +1,11 @@
{
"requires": true,
"lockfileVersion": 1,
"dependencies": {
"three": {
"version": "0.119.1",
"resolved": "https://registry.npmjs.org/three/-/three-0.119.1.tgz",
"integrity": "sha512-GHyh/RiUfQ5VTiWIVRRTANYoXc1PFB1y+jDVRTb649nif1uX1F06PT1TKU3k2+F/MN4UJ3PWvQB53fY2OqKqKw=="
}
}
}

@ -20,7 +20,8 @@
"react-scripts": "3.4.1",
"react-to-print": "~2.5.1",
"recharts": "~1.8.5",
"semantic-ui-react": "~0.88.2"
"semantic-ui-react": "~0.88.2",
"three": "^0.119.1"
},
"scripts": {
"start": "react-scripts start",

@ -1,46 +1,154 @@
import React from 'react';
import React, { useRef, useEffect } from 'react';
import { Container, Icon } from 'semantic-ui-react';
import * as THREE from 'three/build/three.module';
import { Ship } from './spaceport/Ship';
export const Footer = () => {
const footerRef = useRef();
useEffect(() => {
if (!footerRef.current) return;
let t = 0.01;
const shipInterval = 2;
let nextShip = shipInterval;
var scene = new THREE.Scene();
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(
footerRef.current.clientWidth,
footerRef.current.clientHeight
);
const camera = new THREE.PerspectiveCamera(65, 1, 0.01, 1000);
camera.position.set(4, 1, 4);
camera.lookAt(new THREE.Vector3(-8, 0, -2));
scene.add(camera);
footerRef.current.appendChild(renderer.domElement);
let ships = [];
const ship = new Ship();
scene.add(ship.mesh);
ships.push(ship);
const animate = () => {
const deltaTime = 0.075;
t += deltaTime;
// get mouse
if (t > nextShip) {
console.log('bing');
const ship = new Ship();
scene.add(ship.mesh);
ships.push(ship);
nextShip += shipInterval + (Math.random() - 0.5) * 2;
}
for (const ship of ships) {
ship.update({ deltaTime });
if (ship.kill) {
console.log('killing ship');
scene.remove(ship.mesh);
}
}
ships = ships.filter((s) => !s.kill);
requestAnimationFrame(animate);
renderer.render(scene, camera);
};
animate();
renderer.render(scene, camera);
}, [footerRef]);
export function Footer() {
return (
<div className='footer'>
<Container>
<div className="footer" ref={footerRef}>
<Container className="footer-content">
<p>
<img alt='site logo' src='/logo-short.svg' className='logo' />
<img
alt="site logo"
src="/logo-short.svg"
className="logo"
/>
</p>
<p className='text'>
Contact us: <a href='mailto:info@protospace.ca' target='_blank' rel='noopener noreferrer'>info@protospace.ca</a>
<p className="text">
Contact us:{' '}
<a
href="mailto:info@protospace.ca"
target="_blank"
rel="noopener noreferrer"
>
info@protospace.ca
</a>
</p>
<p className='text'>
Created and hosted by Protospace members for Protospace members.
<p className="text">
Created and hosted by Protospace members for Protospace
members.
</p>
<p className='text'>
Spaceport is free and open-source software. <a href='https://github.com/Protospace/spaceport' target='_blank' rel='noopener noreferrer'>Click here</a> to view the source code and license.
<p className="text">
Spaceport is free and open-source software.{' '}
<a
href="https://github.com/Protospace/spaceport"
target="_blank"
rel="noopener noreferrer"
>
Click here
</a>{' '}
to view the source code and license.
</p>
<p>
<a href='https://instagram.com/protospace' target='_blank' rel='noopener noreferrer' aria-label='link to our instagram'>
<Icon name='instagram' size='large' />
<a
href="https://instagram.com/protospace"
target="_blank"
rel="noopener noreferrer"
aria-label="link to our instagram"
>
<Icon name="instagram" size="large" />
</a>
<a href='https://twitter.com/protospace' target='_blank' rel='noopener noreferrer' aria-label='link to our twitter'>
<Icon name='twitter' size='large' />
<a
href="https://twitter.com/protospace"
target="_blank"
rel="noopener noreferrer"
aria-label="link to our twitter"
>
<Icon name="twitter" size="large" />
</a>
<a href='https://youtube.com/user/calgaryprotospace/playlists' target='_blank' rel='noopener noreferrer' aria-label='link to our youtube'>
<Icon name='youtube' size='large' />
<a
href="https://youtube.com/user/calgaryprotospace/playlists"
target="_blank"
rel="noopener noreferrer"
aria-label="link to our youtube"
>
<Icon name="youtube" size="large" />
</a>
<a href='https://github.com/Protospace' target='_blank' rel='noopener noreferrer' aria-label='link to our github'>
<Icon name='github' size='large' />
<a
href="https://github.com/Protospace"
target="_blank"
rel="noopener noreferrer"
aria-label="link to our github"
>
<Icon name="github" size="large" />
</a>
<a href='https://docs.my.protospace.ca' target='_blank' rel='noopener noreferrer' aria-label='link to our docs'>
<Icon name='book' size='large' />
<a
href="https://docs.my.protospace.ca"
target="_blank"
rel="noopener noreferrer"
aria-label="link to our docs"
>
<Icon name="book" size="large" />
</a>
</p>
<p>© 2020 Calgary Protospace Ltd.</p>
</Container>
</div>
);

@ -1,4 +1,5 @@
html, body {
html,
body {
font-size: 16px;
height: 100%;
margin: 0;
@ -43,7 +44,7 @@ body {
padding-top: 1rem;
}
.topPadding > .ui.container{
.topPadding > .ui.container {
min-height: 45rem;
}
@ -66,7 +67,9 @@ body {
padding-bottom: 24rem;
}
.course-editor, .class-editor, .transaction-editor {
.course-editor,
.class-editor,
.transaction-editor {
margin-bottom: 1rem;
}
@ -116,12 +119,22 @@ body {
.footer {
margin-top: -20rem;
background: black;
color: white;
display: grid;
}
/* grid bottom */
.footer canvas {
grid-row: 1/2;
grid-column: 1/2;
}
/* grid top */
.footer .container {
z-index: 99;
grid-row: 1/2;
grid-column: 1/2;
padding-top: 3rem;
padding-bottom: 3rem;
}
@ -151,8 +164,8 @@ body {
margin-right: 0.5em;
}
.darkmode-layer, .darkmode-toggle {
.darkmode-layer,
.darkmode-toggle {
z-index: 500;
}

@ -0,0 +1,65 @@
import * as THREE from 'three';
const SHIP_SIZE = 1;
export class Ship {
constructor() {
this.life = Math.random() * 5 + 3;
this.flyIn = true;
const shipGeo = new THREE.BoxGeometry(
SHIP_SIZE * 0.3,
SHIP_SIZE * 0.3,
SHIP_SIZE
);
this.mesh = new THREE.Mesh(
shipGeo,
new THREE.MeshBasicMaterial(0xff0000)
);
this.y = (Math.random() - 0.5) * 2;
this.hue = Math.floor(Math.random() * 360);
this.mesh.material.color.set(
new THREE.Color(`hsl(${this.hue},70%,80%)`)
);
this.mesh.position.x = (Math.random() - 0.5) * 2;
this.mesh.position.y = this.y;
this.mesh.position.z = -105 + Math.random();
}
update({ deltaTime }) {
if (this.flyIn) {
this.mesh.scale.z = 10;
this.mesh.position.z += 4.75;
// ship accelerating decreasing
// checvk if in space
if (this.mesh.position.z > -1 && this.flyIn) {
this.flyIn = false;
this.mesh.scale.z = 0.5;
this.mesh.material.color.set(
new THREE.Color(`hsl(${this.hue},70%,100%)`)
);
}
} else {
this.mesh.scale.z = 0.5;
}
this.life -= deltaTime;
this.mesh.position.y = this.y + Math.sin(this.life + this.y) * 0.02;
if (this.life < 0) {
const a = Math.abs(this.life);
this.mesh.position.z += a * 2;
this.mesh.scale.z = a * 4;
// accelerate away
}
if (this.mesh.position.z > 5) {
this.kill = true;
}
}
}

@ -10473,6 +10473,11 @@ text-table@0.2.0, text-table@^0.2.0:
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=
three@^0.119.1:
version "0.119.1"
resolved "https://registry.yarnpkg.com/three/-/three-0.119.1.tgz#9d979a082c4cd9622af8e3498a8dfa026a619332"
integrity sha512-GHyh/RiUfQ5VTiWIVRRTANYoXc1PFB1y+jDVRTb649nif1uX1F06PT1TKU3k2+F/MN4UJ3PWvQB53fY2OqKqKw==
throat@^4.0.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a"

Loading…
Cancel
Save