more content + style

This commit is contained in:
Felix Roos
2022-06-04 15:02:04 +02:00
parent 061abecaca
commit 1c77e7e5b3
4 changed files with 117 additions and 32 deletions
+6
View File
@@ -0,0 +1,6 @@
function ImgTile({ src, width, height }) {
return (
<div style={{ background: `url(${src})`, backgroundSize: 'cover', backgroundPosition: 'center', width, height }} />
);
}
export default ImgTile;
+10 -8
View File
@@ -32,7 +32,7 @@ loadWebDirt({
sampleFolder: './EmuSP12',
});
export function MaxiRepl({ code, canvasHeight = 400 }) {
export function MaxiRepl({ code, canvasHeight = 500 }) {
const [exampleIndex, setExampleIndex] = useState(0);
const examples = Array.isArray(code) ? code : [code];
return (
@@ -48,13 +48,15 @@ export function MaxiRepl({ code, canvasHeight = 400 }) {
))}
</div>
)}
<_MiniRepl
key={exampleIndex}
tune={examples[exampleIndex]}
defaultSynth={defaultSynth}
hideOutsideView={true}
theme={materialPalenightLarge}
/>
<div className="max-w-screen">
<_MiniRepl
key={exampleIndex}
tune={examples[exampleIndex]}
defaultSynth={defaultSynth}
hideOutsideView={true}
theme={materialPalenightLarge}
/>
</div>
<canvas
id="test-canvas"
className="w-full pointer-events-none"
+43 -11
View File
@@ -1,8 +1,31 @@
import { useState, useEffect } from 'react';
import { useState, useLayoutEffect, useEffect, useCallback } from 'react';
import { AnimatePresence, motion } from 'framer-motion';
const getUrlIndex = () => parseInt(window.location.hash.split('#')[1] || 0, 10);
export function Slides({ children }) {
const [slide, setSlide] = useState(0);
const [slide, setSlide] = useState(getUrlIndex() % children.length);
useEffect(() => {
window.location.hash = '#' + slide;
}, [slide]);
const next = useCallback(() => setSlide((s) => (s + 1) % children.length), [children]);
const prev = useCallback(() => setSlide((s) => (s + children.length - 1) % children.length), [children]);
useLayoutEffect(() => {
const handleKeyPress = async (e) => {
if (e.ctrlKey && e.altKey) {
if (e.code === 'ArrowRight') {
next();
} else if (e.code === 'ArrowLeft') {
prev();
}
e.preventDefault();
}
};
window.addEventListener('keydown', handleKeyPress, true);
return () => window.removeEventListener('keydown', handleKeyPress, true);
}, [slide]);
return (
<div className="bg-slate-900">
<AnimatePresence exitBeforeEnter>
@@ -13,14 +36,26 @@ export function Slides({ children }) {
exit={{ opacity: 0 }}
className="w-screen h-screen"
>
<div className="flex justify-center items-center p-6">
<div className="px-8 prose grow max-w-[1280px] text-gray-200 font-serif prose-headings:text-gray-200 prose-blockquote:text-gray-200 prose-headings:font-sans prose-2xl prose-slate">
<div className="flex justify-center items-center px-6">
<div
className={`px-8 prose grow max-w-[1280px]
text-gray-200 font-serif
prose-headings:text-gray-200
prose-a:text-indigo-300
prose-blockquote:text-gray-200
prose-em:text-[1.3em]
prose-li:text-[1.4em]
prose-headings:font-sans
prose-headings:mt-12
prose-2xl
prose-slate`}
>
<center>{children[slide]}</center>
</div>
</div>
</motion.div>
</AnimatePresence>
<SlideNav slide={slide} setSlide={setSlide} slides={children} />
<SlideNav onNext={next} onPrev={prev} slides={children} />
</div>
);
}
@@ -29,13 +64,10 @@ export function Slide({ children }) {
return children;
}
function SlideNav({ slide, setSlide, slides }) {
function SlideNav({ onNext, onPrev }) {
return (
<div className="flex absolute top-1/2 space-x-2 w-full justify-between items-center z-1">
<button
onClick={() => setSlide((s) => (s + slides.length - 1) % slides.length)}
className="absolute left-0 my-auto"
>
<button onClick={() => onPrev()} className="absolute left-0 my-auto">
<svg
xmlns="http://www.w3.org/2000/svg"
className="h-12 w-12 text-gray-200"
@@ -47,7 +79,7 @@ function SlideNav({ slide, setSlide, slides }) {
<path strokeLinecap="round" strokeLinejoin="round" d="M15 19l-7-7 7-7" />
</svg>
</button>
<button onClick={() => setSlide((s) => (s + 1) % slides.length)} className="absolute right-0 my-auto">
<button onClick={() => onNext()} className="absolute right-0 my-auto">
<svg
xmlns="http://www.w3.org/2000/svg"
className="h-12 w-12 text-gray-200"
+58 -13
View File
@@ -1,23 +1,25 @@
import { Slides, Slide } from './Slides.jsx';
import { MaxiRepl } from './MaxiRepl';
import ImgTile from './ImgTile';
<Slides>
<Slide>
## Strudel: Algorithmic Patterns for the Web
<h1 className="mb-0">Strudel</h1>
<img src="./ada.jpg" className="h-[500px] rounded-md" />
<h2 className="mt-0">Algorithmic Patterns for the Web</h2>
<div className="max-w-2xl">
<i>
<div className="flex space-x-2 items-center">
<em>
"The Analytical Engine weaves algebraic patterns, just as the Jacquard loom weaves flowers and leaves."
<br />
“Supposing, for instance, that the fundamental relations of pitched sounds in the science of harmony and of musical
composition were susceptible of such expression and adaptations, the [Analytical] Engine might compose elaborate and
scientific pieces of music of any degree of complexity or extent." - Ada Lovelace
</i>
</em>
</div>
<img src="./ada.jpg" className="h-[400px] rounded-md" />
</Slide>
<Slide>
@@ -39,13 +41,13 @@ import { MaxiRepl } from './MaxiRepl';
<div className="text-left">
- A very popular software for live coding music (and more)
- A very popular software for live coding music
- a powerful pattern language for time-based art
- find out more at <a href="https://tidalcycles.org" target="_blank" className="text-indigo-400">tidalcycles.org</a>
</div>
<img src="./tidal-screenshot2.png" className="h-[600px] rounded-md" />
<img src="./tidal-screenshot2.png" className="h-[500px] rounded-md" />
<p>Screenshot: "Yaxu & hellocatfood - LIVE code for Noise Quest"</p>
</Slide>
@@ -56,14 +58,19 @@ import { MaxiRepl } from './MaxiRepl';
<div className="text-left">
- a port of Tidal Cycles to JavaScript
- a browser based editor for zero-install live coding
- many ways to make sound: Tone.js, Webdirt, OSC Superdirt, MIDI, speech
- visuals: highlighting of active events + pianoroll visualization
- find out more at <a href="https://strudel.tidalcycles.org/" target="_blank" className="text-indigo-400">strudel.tidalcycles.org</a>
- a browser based editor for zero-install live coding: <a href="https://strudel.tidalcycles.org/" target="_blank" className="text-indigo-400">strudel.tidalcycles.org</a>
- many ways to make sound: Tone.js, Webdirt, OSC, MIDI ...
<div className="hidden">
- "Strudel" = internationally known as delicious pastry, but also "swirl" / "whirlpool" in german
- (a tidal can cause a whirlpool!)
</div>
<img src="./strudel-screenshot.png" className="h-[600px] rounded-md mb-0" />
</div>
<img src="./strudel-screenshot.png" className="h-[500px] rounded-md mb-0" />
<p>Screenshot: "Algorave 10th Birthday March 2022 - froos"</p>
</Slide>
@@ -111,7 +118,45 @@ stack(
</Slide>
<Slide>
## Contributors
## About Me
<div className="text-left">
- 💻 Studied Computer Science and Media in Stuttgart, working as a software developer by day
- 🎺 Trumpet Player, studied Jazz and Popular Music in Mannheim
- 🎤 Dilettante Music Producer of all kinds of genres
- 💿 ocassionally publishes music with Lui Mafuta & Puste
- 🔌 Modular Synth & Electronics Lover, Dilettante DJ ..
- 💌 Coding Blog: [Loophole Letters](https://loophole-letters.vercel.app/)
- ✨ Started live coding music not too long ago
<div className="grid grid-cols-5 gap-4 mt-12">
<ImgTile height={200} src="https://loophole-letters.vercel.app/_next/image?url=%2Fimg%2Flambdoma.png&w=2048&q=75" />
{/* <ImgTile
height={300}
src="https://loophole-letters.vercel.app/_next/image?url=%2Fimg%2Fharmonic-spiral.png&w=2048&q=75"
/> */}
<ImgTile height={200} src="https://loophole-letters.vercel.app/_next/image?url=%2Fimg%2Fpiano-roll.png&w=2048&q=75" />
<ImgTile height={200} src="https://loophole-letters.vercel.app/_next/image?url=%2Fimg%2Fcof.png&w=2048&q=75" />
<ImgTile height={200} src="https://loophole-letters.vercel.app/_next/image?url=%2Fimg%2F251graph.png&w=2048&q=75" />
<ImgTile
height={200}
src="https://loophole-letters.vercel.app/_next/image?url=%2Fimg%2Fdiy-modular-synth%2Fmidi2cv-styleshot.png&w=2048&q=75"
/>
{/* <ImgTile height={200} src="https://loophole-letters.vercel.app/_next/image?url=%2Fimg%2Fcolorpiano.png&w=2048&q=75" /> */}
{/*
<ImgTile
height={300}
src="https://loophole-letters.vercel.app/_next/image?url=%2Fimg%2Fvoicing-permutation.png&w=2048&q=75"
/> */}
</div>
</div>
</Slide>
<Slide>
## How it started
</Slide>
<Slide>