document.body.addEventListener("click", firstClick);
document.body.addEventListener("click", drawcelestial);
function firstClick(event) {
//create and start audio
let song = new Audio("../Audio/funeral-canticle.mp3");
song.loop = true;
song.play();
//hide header
document.getElementsByTagName("h1")[0].style.display = "none";
event.stopPropagation();
document.body.removeEventListener("click", firstClick);
}
//Places celestial bodies on an empty universe.
// 75% of time body to place on universe is chosen randomly from an array
function drawcelestial(event) {
let celestial = document.createElement("div");
let randomNum = Math.random();
//potential image array for it randomNum < .75
let spaceImages = ["comet", "comet-1", "europa", "jupiter", "mars", "mercury", "milky-way", "meteorite", "saturn", "uranus", "neptune"];
if (randomNum <= .75)
//sets image title from array index of random index number between 0 an 10
celestial.style.backgroundImage = `url(assets/images/space/${spaceImages[Math.floor(Math.random()*spaceImages.length)]}.svg)`;
else if (randomNum > .75 && randomNum < .98)
celestial.style.backgroundImage = "url(assets/images/space/sun.svg)";
else
celestial.style.backgroundImage = "url(assets/images/space/planet-earth-1.svg)";
celestial.style.position = "absolute";
//responsive sizing for varying viewport sizes
window.innerWidth > 700 ? celestial.style.height = `${Math.random() * 6}vw`: celestial.style.height = `${Math.random() * 12.5}vw`;
//sets to place coordinates clicked
celestial.style.left = `${event.pageX}px`;
celestial.style.top = `${event.pageY}px`;
document.body.appendChild(celestial);
}
Basic text editor with [Shift], [Space], [Backspace], [Enter], [Tab], & [CapsLock] Functionalities
Click this box, then enter text
JS Source Code
//workspace box for text insertion area
let keyDiv = document.querySelector("#keyClick");
//add text to text area
keyDiv.addEventListener("keydown", event => {
let divChild = keyDiv.lastChild;
//for different handlings for special action keys and standard keys
switch(event.key){
case "Enter":
keyDiv.appendChild(document.createElement("p"));
break;
case "Tab":
event.preventDefault();
divChild.textContent += "\xa0\xa0\xa0\xa0";
break;
case " ":
//to prevent default window action of move page down when space pressed
event.preventDefault();
divChild.textContent += "\xa0"
break;
case "Backspace":
//removes one char from each P or last P if P is empty
if(divChild.textContent.length > 0)
divChild.textContent = divChild.textContent.slice(0, divChild.textContent.length-1);
else if(divChild.previousSibling != null)
divChild.remove();
break;
case "CapsLock":
break;
case "Shift":
break;
default:
divChild.textContent += event.key;
}
//checks if overflowing from DIV and if so, scrolls DIV up
if(keyDiv.scrollHeight > keyDiv.clientHeight)
keyDiv.scrollTop = keyDiv.scrollHeight;
});
//remove display instructions after first key press
keyDiv.addEventListener("keydown", firstPress);
function firstPress(event){
keyDiv.firstChild.textContent = event.textContent;
keyDiv.removeEventListener("keydown", firstPress);
}
The HTML DOM Skeleton
//index.html//
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>React App</title>
</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<main>
<div id="helloDiv"></div>
</main>
</body>
</html>
The Time Component, to create a dynamically updating clock, that updates once per second
//Time.js//
import React, { Component } from 'react';
class Time extends Component {
//Constructor creates time value and starts update method
constructor(props){
super(props);
this.state = {time: (new Date()).toLocaleString()};
this.startTime(); //starts time when class created
}
//updates time every second
startTime(){
setInterval(() => {this.setState({time: (new Date()).toLocaleString()})}, 1000);
}
//Time component with time value that updates every second is rendered
render() {
return <div>{this.state.time}</div>;
}
}
export default Time;
The App Component, to Display Different Texts and in Some Cases an Image, based On Properties Set During Instantiation
//App.js//
import React, { Component } from 'react';
import Time from './Time';
import './App.css';
class App extends Component {
render() {
return this.selectType();
}
selectType(){
let Elm = <h1 style={{color:'green', border: '3px solid black', backgroundColor: 'black', textAlgin: 'center'}}>
Hello world</h1>;
let Feel = <h1>I FEEL IT</h1>;
let Belm = <h1>REEEEE</h1>;
let Relm = <img src={this.props.url} height="200px" width="200px"></img>
//tests theType property passed in by creating object, then uses that to decide what type of App to return
switch(this.props.theType){
case "Elm":
return(
<div>
<h3>{this.props.theType.toString()}</h3>
{Elm}
<Time />
</div>
);
case "Feelit":
return (
<div>
{Elm}
{Relm}
{Elm}
</div>
);
default:
return (
<div>
{Belm}
{Relm}
{Feel}
{Belm}
</div>
);
}
}
}
export default App;
The index.js Script, to Render Onto the DOM
//index.js//
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import AppGroup from './AppGroup';
//import * as serviceWorker from './serviceWorker';
//set HelloWorld with 1, 2, or 3 <AppGroup/> components based on viewport size
function HelloWorld(){
if(document.documentElement.clientWidth <= 400)
return <div style={{display: "flex", alignItems: "center", justifyContent: "space-around"}}>
<AppGroup/></div>;
else if(document.documentElement.clientWidth <= 615)
return <div style={{display: "flex", alignItems: "center", justifyContent: "space-around"}}>
<AppGroup/><AppGroup/></div>;
else
return <div style={{display: "flex", alignItems: "center", justifyContent: "space-around"}}>
<AppGroup/><AppGroup/><AppGroup/></div>;
}
ReactDOM.render(HelloWorld(), document.getElementById('helloDiv'));
Box.js, for housing the a single image as part of a series of dynamically generated images, in stateless functional JS
import React from 'react';
const Box = (url) => {
return <img src={url} alt="box image" style={{margin: "3vh", width:"41vh", height: "41vh"}}></img>
}
export default Box;
BoxGroup.js, for building a group of boxes, in stateless functional JS
import React from 'react';
import Box from './Box';
//take in a list of images and dynamically the box group, one box per url
const BoxGroup = (urlList) => {
return (<div id="container" style={{ display: "flex", flexFlow: "row wrap", justifyContent: "center"}}>
{urlList.map(url => Box(url))}
</div>
);
};
export default BoxGroup;
IntervalBoxGroup.js, for building a stateful box group, where a box group with new images is rendered every 3 seconds
import React, {Component} from 'react';
import BoxGroup from './BoxGroup';
class IntervalBoxGroup extends Component {
constructor(props) {
super(props);
this.state = {
urlList: ['/images/stocks/1.jpg',
'/images/stocks/2.png',
'/images/stocks/3.jpg',
'/images/stocks/4.jpg',
'/images/stocks/5.png',
'/images/stocks/6.jpg',
'/images/stocks/7.jpg',
'/images/stocks/8.png'
]
};
}
componentDidMount() {
this.switchImage();
}
componentWillUnmount(){
this.switchImage();
}
//creates temp urlList based on current state, moves rear index to front, then sets new state with temp urlList
nextImages() {
let tempUrl = new Array(...this.state.urlList);
tempUrl.unshift(tempUrl.pop());
this.setState(lastState => ({
urlList: tempUrl
}));
}
//Updates images every 3 seconds
switchImage() {
setInterval(() => this.nextImages(), 3000);
}
//renders BoxGroup, which re-renders with new images each setInterval interation
render() {
return BoxGroup(this.state.urlList);
};
}
export default IntervalBoxGroup;
index.js, for rendering the IntervalBoxGroup onto index.html
import React from 'react';
import ReactDOM from 'react-dom';
import IntervalBoxGroup from './IntervalBoxGroup';
import './index.css';
ReactDOM.render(<IntervalBoxGroup/>, document.getElementById('root'));