latest update

This commit is contained in:
skelbon 2024-08-08 17:36:04 +01:00
parent d3c931eed1
commit c4acccbb85
5 changed files with 327 additions and 87 deletions

View File

@ -1 +1 @@
<?xml version="1.0" encoding="UTF-8"?><svg id="Layer_2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20.14 15.64"><defs><style>.cls-1{fill:none;stroke:#fff;stroke-miterlimit:10;}</style></defs><g id="Layer_1-2"><line class="cls-1" x1="19.78" y1="4.49" x2="13.66" y2="10.61"/><line class="cls-1" x1="13.66" y1="4.49" x2="19.78" y2="10.61"/><polygon class="cls-1" points=".5 11.16 3.84 11.16 10.92 14.82 10.92 .82 3.84 4.49 .5 4.49 .5 11.15 .5 11.16"/><line class="cls-1" x1="3.84" y1="4.49" x2="3.84" y2="11.16"/></g></svg> <?xml version="1.0" encoding="UTF-8"?><svg id="Layer_2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18.27 15.64"><defs><style>.cls-1{fill:none;stroke:#fff;stroke-miterlimit:10;}</style></defs><g id="Layer_1-2"><line class="cls-1" x1="19.78" y1="4.49" x2="13.66" y2="10.61"/><line class="cls-1" x1="13.66" y1="4.49" x2="19.78" y2="10.61"/><polygon class="cls-1" points=".5 11.16 3.84 11.16 10.92 14.82 10.92 .82 3.84 4.49 .5 4.49 .5 11.15 .5 11.16"/><line class="cls-1" x1="3.84" y1="4.49" x2="3.84" y2="11.16"/></g></svg>

Before

Width:  |  Height:  |  Size: 525 B

After

Width:  |  Height:  |  Size: 525 B

View File

@ -1,38 +1,83 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Conductor</title>
<link rel="icon" href="/Logo.svg" type="image/svg+xml">
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<div id="loading-screen">
<object
type="image/svg+xml"
data="/Logo.svg"
class="logo"
></object>
<div class="loading">
</div>
</div>
<div id="main-content">
<div class="title">
15.5.2024 08:00:00 - 08:01:00 UTC
</div> <head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Conductor</title>
<link rel="icon" href="/Logo.svg" type="image/svg+xml">
<link rel="stylesheet" href="styles.css" />
</head>
<div class="sheet-music-window" id="music-window"> <body>
<object <div id="loading-screen">
type="image/svg+xml" <object type="image/svg+xml" data="/Logo.svg" class="logo"></object>
data="/assets/svg/time-pointer.svg" <div class="loading">
class="time-indicator"
id="time-indicator"
></object>
</div>
</div> </div>
<script type="module" src="/src/script.js"></script> </div>
</body> <div id="buttons">
</html> <img src="/assets/svg/mute.svg" class="audio" id="mute"></img>
<img src="/assets/svg/menu.svg" class="menu" id="menu-button"></img>
</div>
<div id="main-content">
<div class="title-title">
The Conductor
</div>
<div class="title" id="title">
15.5.2024 08:00:00 - 08:01:00 UTC
</div>
<div class="sheet-music-window" id="music-window">
<object type="image/svg+xml" data="/assets/svg/time-pointer.svg" class="time-indicator"
id="time-indicator"></object>
</div>
</div>
<div id="about-content">
<div class="title">
<img src="/assets/svg/the-conductor-title.svg"></img>
</div>
<div class="about-content">
<div class="safari">
<div class="instruments-key" id="instrument-key-div"></div>
</div>
<p>
The Conductor translates live lightning strikes from around the world into a graphic score for seven percussion instruments.
</p>
<p>
The project was conceived and developed by the artist Mishka Henner between 2023 and 2024 with a team of musicians, sound artists and acoustics engineers during an artist's residency at Energy House 2.0 at the University of Salford.
</p>
<p>
The Conductor was first performed at the University of Salfords Acoustic Laboratories during the Sounds From the Other City Festival on 5 May 2024.
</p>
<p>
Click <a href="https://mishkahenner.com/The-Conductor" style="color: #fff; text-decoration:underline">here</a> to read more about the project. Download a copy of the artist's graphic score <a href="https://files.cargocollective.com/c20096/CONDUCTOR-SHEET-MUSIC-Black-BG.pdf" style="color: #fff; text-decoration:underline">here</a>.
</p>
<br />
<div class="production-credits">
<br />
<div>
Project Conception and Design by Mishka Henner.
</div>
Data Capture, Web Design and Coding by Joe Gibson.
<div>
Lightning data from Blitzortung.org
</div>
<p>
With support from the University of Salford Art Collection in partnership with Open Eye Gallery, Liverpool as part of the LOOK Photo Biennial, and Castlefield Gallery, Manchester. Generously supported by Friends of Energy House Labs.
</p>
</div>
</div>
</div>
<script type="module" src="/src/script.js"></script>
</body>
</html>

View File

@ -1,6 +1,15 @@
- change title to timestamp - date and time - program stop zooming issue - resize rules
- add a tab in the date/time format mishka gonna send an x icon for the back behaviour
- Mishka gonna send a mute symbol look at memory leak??
- Add circle logo make the sound and menu icons part of an 'app bar' along with the conductor logo
- Mishka gonna change up the samples make the mid size the default size but double check the size on the phone isnt too small
refactor when it's all done
format the key as per the pdf
sort out the title size
sort out the blitzortung connection issue

View File

@ -2,32 +2,106 @@ import { Client, BrowserSocketFactory } from "./blitz.js";
import { loadInstruments } from "./instruments.js"; import { loadInstruments } from "./instruments.js";
document.addEventListener("DOMContentLoaded", async () => { document.addEventListener("DOMContentLoaded", async () => {
let showing;
let audioContext;
let interacted = false;
let gainNode;
function startAudio() {
audioContext = new (window.AudioContext || window.webkitAudioContext)();
gainNode = audioContext.createGain();
gainNode.gain.value = 0;
gainNode.connect(audioContext.destination);
}
function muter() {
fadeOutVolume();
}
function unMute() {
startAudio();
fadeInVolume();
}
function padZero(num) {
return num.toString().padStart(2, "0");
}
function setTitle() {
const now = new Date();
const future = new Date(now.getTime() + 59 * 1000); // 59 seconds later
const formattedDate = `${padZero(now.getDate())}.${padZero(
now.getMonth() + 1
)}.${now.getFullYear()}`;
const formattedTime = `${padZero(now.getHours())}:${padZero(
now.getMinutes()
)}:${padZero(now.getSeconds())}`;
const formattedFutureTime = `${padZero(future.getHours())}:${padZero(
future.getMinutes()
)}:${padZero(future.getSeconds())}`;
title.innerHTML = `${formattedDate}<span class="tab-space"></span>${formattedTime} - ${formattedFutureTime} UTC`;
}
function fadeInVolume() { function fadeInVolume() {
gainNode.gain.setValueAtTime(0, audioContext.currentTime); // Start at 0 gainNode.gain.setValueAtTime(0, audioContext.currentTime); // Start at 0
gainNode.gain.linearRampToValueAtTime(1, audioContext.currentTime + 10); // Fade to full volume gainNode.gain.linearRampToValueAtTime(1, audioContext.currentTime + 2); // Fade to full volume
}
function fadeOutVolume() {
gainNode.gain.setValueAtTime(1, audioContext.currentTime); // Start at 0
gainNode.gain.linearRampToValueAtTime(0, audioContext.currentTime + 2); // Fade to full volume
} }
function showMainContent() { function showMainContent() {
const loadingScreen = document.getElementById("loading-screen"); setTitle();
const mainContent = document.getElementById("main-content"); const mute = document.getElementById("mute");
loadingScreen.classList.add("fade-out");
loadingScreen.addEventListener("transitionend", (event) => { mute.addEventListener("click", () => {
if (event.propertyName === "opacity") { const mutedSrc = "/assets/svg/sound-on.svg";
loadingScreen.style.display = "none"; const unMutedSrc = "/assets/svg/mute.svg";
mainContent.style.display = "flex"; interacted = !interacted;
mainContent.style.opacity = "0"; interacted ? unMute() : muter();
void mainContent.offsetWidth; mute.src = interacted ? mutedSrc : unMutedSrc;
mainContent.classList.add("fade-in");
mainContent.style.opacity = "1"; startAudio();
fadeInVolume(); fadeInVolume();
}
}); });
fadeAndReplaceADiv("main-content", "loading-screen");
fadeAndReplaceADiv("buttons", "buttons");
showing = "main-content";
document.getElementById("menu-button").onclick = function () {
console.log(showing);
toggleInfo();
};
} }
const audioContext = new (window.AudioContext || window.webkitAudioContext)(); function toggleInfo() {
const gainNode = audioContext.createGain(); if (showing === "main-content") {
gainNode.gain.value = 0; fadeAndReplaceADiv("about-content", "main-content");
gainNode.connect(audioContext.destination); cleanUpAndRestart();
showing = "about-content";
} else {
fadeAndReplaceADiv("main-content", "about-content");
showing = "main-content";
}
}
function fadeAndReplaceADiv(innyDivId, outtyDivId) {
const outty = document.getElementById(outtyDivId);
const inny = document.getElementById(innyDivId);
outty.classList.remove("fade-in");
outty.classList.add("fade-out");
outty.style.display = "none";
inny.style.display = "flex";
inny.style.opacity = "0";
void inny.offsetWidth;
inny.classList.add("fade-in");
inny.style.opacity = "1";
}
const socketFactory = new BrowserSocketFactory(); const socketFactory = new BrowserSocketFactory();
let client = new Client(socketFactory); let client = new Client(socketFactory);
@ -44,7 +118,31 @@ document.addEventListener("DOMContentLoaded", async () => {
let currStaveNumber = 1; let currStaveNumber = 1;
const instruments = await loadInstruments(); const instruments = await loadInstruments();
console.log(instruments);
const instNames = Object.keys(instruments);
showMainContent(); showMainContent();
/***
* add the instrument images and names into the about section
*
*/
const instrumentsKey = document.getElementById("instrument-key-div");
for (const instrument of instNames) {
console.log(instrument);
const keyDiv = document.createElement("div");
const keySvg = document.createElement("object");
const keyName = document.createElement("div");
keyName.innerText = instrument.toUpperCase();
keySvg.type = "image/svg+xml";
keySvg.data = instruments[instrument].image;
keyDiv.appendChild(keySvg);
keyDiv.appendChild(keyName);
keyDiv.classList.add("instrument-key");
instrumentsKey.appendChild(keyDiv);
}
const numStaves = 6; const numStaves = 6;
const sheetWindow = document.getElementById("music-window"); const sheetWindow = document.getElementById("music-window");
@ -71,31 +169,37 @@ document.addEventListener("DOMContentLoaded", async () => {
} }
}); });
const cleanUpAndRestart = () => { const cleanUpAndRestart = (reload = false) => {
const icons = document.querySelectorAll(".event-icon"); const icons = document.querySelectorAll(".event-icon");
const timeIndicator = document.getElementById("time-indicator"); const timeIndicator = document.getElementById("time-indicator");
icons.forEach((icon) => { icons.forEach((icon) => {
icon.classList.add("fade-out"); icon.classList.add("fade-out");
icon.addEventListener("transitionend", () => { icon.addEventListener("transitionend", () => {
icon.remove(); icon.remove();
currStaveNumber = 1;
}); });
}); });
location.reload(); currStaveNumber = 1;
setTitle();
if (reload) location.reload();
}; };
window.addEventListener("orientationchange", cleanUpAndRestart); window.addEventListener("orientationchange", () => {
cleanUpAndRestart(true);
});
const playSound = (instrument) => { const playSound = (instrument) => {
const source = audioContext.createBufferSource(); if (interacted) {
const samples = instrument.samples; const source = audioContext.createBufferSource();
const sampleKeys = Object.keys(samples); const samples = instrument.samples;
const numSamples = sampleKeys.length; const sampleKeys = Object.keys(samples);
const ramdomKey = sampleKeys[Math.floor(Math.random() * (numSamples - 1))]; const numSamples = sampleKeys.length;
const ramdomKey =
sampleKeys[Math.floor(Math.random() * (numSamples - 1))];
source.buffer = samples[`${ramdomKey}`]; // Example: Play the 'Gong' sound source.buffer = samples[`${ramdomKey}`]; // Example: Play the 'Gong' sound
source.connect(audioContext.destination); source.connect(gainNode);
source.start(); source.start();
}
}; };
const placeIcon = (instrument) => { const placeIcon = (instrument) => {

View File

@ -2,16 +2,15 @@
body { body {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
/* justify-content: center; */
align-items: center; align-items: center;
background-color: rgb(24, 24, 24); background-color: rgb(24, 24, 24);
position: absoulute;
height: 100vh; height: 100vh;
} }
#main-content { #main-content {
position: absolute; position: absolute;
width: 100%; width: 100%;
max-width: 800px;
height: 100%; height: 100%;
display: none; display: none;
flex-direction: column; flex-direction: column;
@ -19,8 +18,28 @@ body {
align-items: center; align-items: center;
opacity: 0; opacity: 0;
transition: opacity 2s ease; transition: opacity 2s ease;
}
#about-content {
position: relative;
flex-direction: column;
display: none;
width: 80vw;
max-width: 700px;
padding-right: 10px;
height: 100%;
color: #fff;
/* justify-content: center; */
align-items: center;
font-family: 'Courier';
font-size: 12pt;
line-height: 1.2;
margin: 20px;
opacity: 0;
transition: opacity 2s ease;
} }
#loading-screen { #loading-screen {
position: absolute; position: absolute;
width: 100%; width: 100%;
@ -31,14 +50,22 @@ body {
align-items: center; align-items: center;
color: #fff; color: #fff;
transition: opacity 1s ease; transition: opacity 1s ease;
} }
#buttons {
display: none;
opacity: 0;
transition: opacity 1s ease;
}
.logo { .logo {
color: #fff; color: #fff;
width: 20%; width: 20%;
height: 20%; height: 20%;
animation: rotate360 10s linear infinite; animation: rotate360 10s linear infinite;
} }
.loading { .loading {
font-family: Helvetica; font-family: Helvetica;
font-size: 10pt; font-size: 10pt;
@ -50,30 +77,85 @@ body {
min-width: 10px; min-width: 10px;
} }
.instruments-key {
position: relative;
display: flex;
margin: 8px;
padding-top: 8% ;
padding-bottom: 8% ;
flex-direction: row;
align-content: center;
justify-content: space-around;
}
.instrument-key {
display: flex;
flex-direction: column;
vertical-align: baseline;
justify-content: space-between;
width: 25px;
font-size: xx-small;
margin: 0;
}
.sheet-music-window { .sheet-music-window {
position: relative; position: relative;
width: 80vw; width: 80vw;
max-width: 700px; max-width: 700px;
height: 70%; height: 70%;
margin: 0; margin: 0;
background-color: rgb(24,24,24); background-color: rgb(24,24,24);
margin-bottom: 100px; margin-bottom: 100px;
/* overflow: hidden; */ }
.conductor-title{
width: 40%;
}
.menu {
position: fixed;
padding: 40px;
width: 21px;
top: 0;
left: 0;
flex: 0 0 auto;
z-index: 99;
}
.audio{
position: fixed;
padding: 40px;
width: 20px;
top: 0;
right: 0;
flex: 0 0 auto;
z-index: 99;
} }
.title{ .title{
position: relative; top: 30px;
align-content: center; width: 30%;
max-width: 500px; margin: 30px;
width: auto; text-align: center;
height: 15%;
color: white; color: white;
background-color: rgb(24,24,24); background-color: rgb(24,24,24);
/* height: 20vh; */ /* height: 20vh; */
font-family: Helvetica; font-family: Helvetica;
font-size: 10pt; font-size: 1.4vw;
}
.title-title {
font-family: Helvetica;
color: #fff;
font-size: 1.5vw;;
}
.production-credits {
font-size: smaller;
}
.tab-space::before {
content: '\00a0\00a0\00a0\00a0\00a0\00a0'; /* 6 non-breaking spaces */
} }
.stave-wrapper { .stave-wrapper {
@ -88,12 +170,13 @@ body {
top: 0; top: 0;
left: 0; left: 0;
position: absolute; position: absolute;
width: 2px; /* Adjust width of SVG as needed */ width: 2px;
height: 100%; /* Adjust height of SVG as needed */ /* height: 100%; */
animation: moveRight 10s linear infinite; animation: moveRight 10s linear infinite;
z-index: 2; /* Ensure it is above other elements */ z-index: 2;
} }
.fade-in { .fade-in {
opacity: 1; opacity: 1;
} }
@ -101,7 +184,6 @@ body {
.fade-out { .fade-out {
opacity: 0; opacity: 0;
transition: opacity 1s ease; transition: opacity 1s ease;
} }
@keyframes rotate360 { @keyframes rotate360 {