Compare commits
	
		
			4 commits
		
	
	
		
			fd25154725
			...
			a75d3b0175
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| a75d3b0175 | |||
| 40270c7f32 | |||
| cfe22d204b | |||
| 7e29468247 | 
					 14 changed files with 217 additions and 123 deletions
				
			
		|  | @ -21,7 +21,7 @@ a { | |||
| } | ||||
| 
 | ||||
| 
 | ||||
| h1, h2, h3 { | ||||
| h1, h2, h3, h4 { | ||||
|   margin-top: 0; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -20,11 +20,11 @@ | |||
| 		}); | ||||
| 	}); | ||||
| 
 | ||||
| 	$: onlyCard = $page.url.pathname === '/card'; | ||||
| 	$: onlyCard = $page.data.card; | ||||
| </script> | ||||
| 
 | ||||
| <TestCard full={onlyCard} on:focus={() => goto('/card')} /> | ||||
| <main class:content={!onlyCard} class:sub={$page.url.pathname !== '/' && !onlyCard}> | ||||
| <main class:content={!onlyCard} class:sub={!$page.data.root && !onlyCard}> | ||||
| 	<a href=".." class="button button-back"><i class="ti ti-arrow-back" />Back</a> | ||||
| 	<slot /> | ||||
| </main> | ||||
|  |  | |||
							
								
								
									
										7
									
								
								src/routes/+page.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/routes/+page.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,7 @@ | |||
| import type { PageLoad } from './$types'; | ||||
| 
 | ||||
| export const load: PageLoad = () => { | ||||
| 	return { | ||||
| 		root: true | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										51
									
								
								src/routes/audio/(channels)/+layout.svelte
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								src/routes/audio/(channels)/+layout.svelte
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,51 @@ | |||
| <script lang="ts"> | ||||
| 	import CycleButton from './cycle-button.svelte'; | ||||
| 
 | ||||
| 	let channelsEl: HTMLDivElement; | ||||
| </script> | ||||
| 
 | ||||
| <div class="channels" bind:this={channelsEl}> | ||||
| 	<slot /> | ||||
| </div> | ||||
| <div class="controls"> | ||||
| 	<CycleButton element={channelsEl} /> | ||||
| </div> | ||||
| 
 | ||||
| <style> | ||||
| 	.channels { | ||||
| 		display: flex; | ||||
| 		flex-direction: column; | ||||
| 		justify-content: space-evenly; | ||||
| 		font-size: 2rem; | ||||
| 		flex-grow: 1; | ||||
| 
 | ||||
| 		position: relative; | ||||
| 	} | ||||
| 
 | ||||
| 	:global(.channels .row) { | ||||
| 		display: flex; | ||||
| 		justify-content: space-between; | ||||
| 	} | ||||
| 
 | ||||
| 	.controls { | ||||
| 		text-align: center; | ||||
| 		margin: 2rem 0; | ||||
| 		font-size: 1.5rem; | ||||
| 	} | ||||
| 
 | ||||
| 	:global(.channels .center) { | ||||
| 		font-size: 0.9em; | ||||
| 	} | ||||
| 
 | ||||
| 	:global(.channels .label) { | ||||
| 		opacity: 0.2; | ||||
| 		font-size: 6rem; | ||||
| 
 | ||||
| 		position: absolute; | ||||
| 		top: 50%; | ||||
| 		left: 50%; | ||||
| 		transform: translate(-50%, -50%); | ||||
| 
 | ||||
| 		pointer-events: none; | ||||
| 	} | ||||
| </style> | ||||
							
								
								
									
										53
									
								
								src/routes/audio/(channels)/cycle-button.svelte
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								src/routes/audio/(channels)/cycle-button.svelte
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,53 @@ | |||
| <script lang="ts"> | ||||
| 	import { onDestroy } from 'svelte'; | ||||
| 
 | ||||
| 	export let element: HTMLElement; | ||||
| 
 | ||||
| 	let cycling = false; | ||||
| 	let currentChannel: HTMLAudioElement | undefined; | ||||
| 	async function cycleChannels() { | ||||
| 		cycling = true; | ||||
| 		const buttons = element.querySelectorAll('button'); | ||||
| 		buttons.forEach((button) => (button.disabled = true)); | ||||
| 		const channels = element.querySelectorAll('audio'); | ||||
| 		while (cycling) { | ||||
| 			for (const channel of channels) { | ||||
| 				currentChannel = channel; | ||||
| 				await channel.play(); | ||||
| 				await new Promise((resolve) => { | ||||
| 					channel.onended = resolve; | ||||
| 				}); | ||||
| 				if (!cycling) { | ||||
| 					break; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		buttons.forEach((button) => (button.disabled = false)); | ||||
| 	} | ||||
| 
 | ||||
| 	function onClick() { | ||||
| 		cycling = !cycling; | ||||
| 		if (cycling) { | ||||
| 			cycleChannels(); | ||||
| 		} else { | ||||
| 			if (currentChannel) { | ||||
| 				currentChannel.pause(); | ||||
| 				currentChannel.currentTime = 0; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	onDestroy(() => { | ||||
| 		cycling = false; | ||||
| 		currentChannel?.pause(); | ||||
| 	}); | ||||
| </script> | ||||
| 
 | ||||
| <button on:click={onClick}> | ||||
| 	<i class="ti ti-refresh"></i> | ||||
| 	{#if cycling} | ||||
| 		Stop Cycling | ||||
| 	{:else} | ||||
| 		Cycle through | ||||
| 	{/if} | ||||
| </button> | ||||
|  | @ -1,12 +1,10 @@ | |||
| <script lang="ts"> | ||||
| 	import { createEventDispatcher, onMount } from 'svelte'; | ||||
| 	const dispatch = createEventDispatcher<{ end: void }>(); | ||||
| 
 | ||||
| 	export let src: string; | ||||
| 	export let left = false; | ||||
| 	export let center = false; | ||||
| 	export let right = false; | ||||
| 	export let lfe = false; | ||||
| 	export let inline = false; | ||||
| 
 | ||||
| 	let currentTime = 0; | ||||
| 	let paused = true; | ||||
|  | @ -22,6 +20,7 @@ | |||
| 	class:right | ||||
| 	class:center | ||||
| 	class:lfe | ||||
| 	class:inline | ||||
| 	class:playing={!paused} | ||||
| 	on:click={play} | ||||
| > | ||||
|  | @ -30,7 +29,7 @@ | |||
| 	{:else} | ||||
| 		<i class="ti ti-wave-sine"></i> | ||||
| 	{/if} | ||||
| 	<label><slot /></label> | ||||
| 	<span><slot /></span> | ||||
| 	<audio bind:currentTime bind:paused {src}></audio> | ||||
| </button> | ||||
| 
 | ||||
|  | @ -43,6 +42,8 @@ | |||
| 		flex-direction: column; | ||||
| 		text-align: center; | ||||
| 
 | ||||
| 		opacity: 0.8; | ||||
| 
 | ||||
| 		& .ti { | ||||
| 			font-size: 3em; | ||||
| 		} | ||||
|  | @ -58,11 +59,39 @@ | |||
| 		} | ||||
| 
 | ||||
| 		&:disabled { | ||||
| 			opacity: 0.33; | ||||
| 			opacity: 0.5; | ||||
| 		} | ||||
| 
 | ||||
| 		&.playing { | ||||
| 			opacity: 0.66; | ||||
| 			transform: scale(1.1); | ||||
| 			opacity: 1; | ||||
| 		} | ||||
| 
 | ||||
| 		transition: | ||||
| 			transform 0.2s ease, | ||||
| 			opacity 0.2s ease; | ||||
| 
 | ||||
| 		&.inline { | ||||
| 			flex-direction: row; | ||||
| 			align-items: center; | ||||
| 			justify-content: center; | ||||
| 			background: black; | ||||
| 			border: 1px solid white; | ||||
| 
 | ||||
| 			opacity: 1; | ||||
| 
 | ||||
| 			& .ti { | ||||
| 				font-size: 1.5em; | ||||
| 			} | ||||
| 
 | ||||
| 			&.playing { | ||||
| 				transform: scale(1); | ||||
| 				opacity: 0.8; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		&:active { | ||||
| 			transform: scale(1); | ||||
| 		} | ||||
| 	} | ||||
| </style> | ||||
							
								
								
									
										34
									
								
								src/routes/audio/(channels)/stereo-test.svelte
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								src/routes/audio/(channels)/stereo-test.svelte
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,34 @@ | |||
| <script lang="ts"> | ||||
| 	import leftUrl from '@assets/audio/stereo/Left.mp3'; | ||||
| 	import centerUrl from '@assets/audio/stereo/Center.mp3'; | ||||
| 	import rightUrl from '@assets/audio/stereo/Right.mp3'; | ||||
| 	import Speaker from './speaker.svelte'; | ||||
| 	import CycleButton from './cycle-button.svelte'; | ||||
| 
 | ||||
| 	let speakersEl: HTMLElement; | ||||
| </script> | ||||
| 
 | ||||
| <div class="test"> | ||||
| 	<div class="speakers" bind:this={speakersEl}> | ||||
| 		<Speaker src={leftUrl} left inline>Left</Speaker> | ||||
| 		<Speaker src={centerUrl} center inline>Center</Speaker> | ||||
| 		<Speaker src={rightUrl} right inline>Right</Speaker> | ||||
| 	</div> | ||||
| 	<CycleButton element={speakersEl} /> | ||||
| </div> | ||||
| 
 | ||||
| <style> | ||||
| 	.test { | ||||
| 		display: flex; | ||||
| 		gap: 1em; | ||||
| 		align-items: center; | ||||
| 		margin: 0.5em 0; | ||||
| 	} | ||||
| 
 | ||||
| 	.speakers { | ||||
| 		display: flex; | ||||
| 		gap: 1em; | ||||
| 		font-size: 1.25em; | ||||
| 		margin-right: 1em; | ||||
| 	} | ||||
| </style> | ||||
|  | @ -1,20 +1,37 @@ | |||
| <h3>Channel tests</h3> | ||||
| <ul> | ||||
| 	<li><a href="channels/stereo">Stereo</a></li> | ||||
| 	<li><a href="channels/5.1">5.1 Surround</a></li> | ||||
| 	<li><a href="channels/7.1">7.1 Surround</a></li> | ||||
| </ul> | ||||
| <script lang="ts"> | ||||
| 	import StereoTest from './(channels)/stereo-test.svelte'; | ||||
| </script> | ||||
| 
 | ||||
| <article> | ||||
| 	<h3>Channel tests</h3> | ||||
| 	<h4>Stereo</h4> | ||||
| 	<section> | ||||
| 		<StereoTest /> | ||||
| 	</section> | ||||
| 	<h4>Surround audio</h4> | ||||
| 	<section> | ||||
| 		<ul> | ||||
| 			<li><a class="button" href="channels-5.1">5.1 Surround</a></li> | ||||
| 			<li><a class="button" href="channels-7.1">7.1 Surround</a></li> | ||||
| 		</ul> | ||||
| 	</section> | ||||
| </article> | ||||
| 
 | ||||
| <style> | ||||
| 	h4 { | ||||
| 		margin-bottom: 0; | ||||
| 	} | ||||
| 
 | ||||
| 	ul { | ||||
| 		list-style-type: none; | ||||
| 		padding: 0; | ||||
| 		margin: 0; | ||||
| 
 | ||||
| 		display: flex; | ||||
| 		gap: 1rem; | ||||
| 		display: inline-flex; | ||||
| 		gap: 1em; | ||||
| 	} | ||||
| 	li { | ||||
| 		margin-bottom: 10px; | ||||
| 
 | ||||
| 	section { | ||||
| 		margin: 1em 0; | ||||
| 	} | ||||
| </style> | ||||
|  |  | |||
|  | @ -1,82 +0,0 @@ | |||
| <script lang="ts"> | ||||
| 	import { onDestroy } from 'svelte'; | ||||
| 
 | ||||
| 	let channelsEl: HTMLDivElement; | ||||
| 
 | ||||
| 	let cycling = false; | ||||
| 	async function cycleChannels() { | ||||
| 		cycling = true; | ||||
| 		const buttons = channelsEl.querySelectorAll('button'); | ||||
| 		buttons.forEach((button) => (button.disabled = true)); | ||||
| 		const channels = channelsEl.querySelectorAll('audio'); | ||||
| 		while (cycling) { | ||||
| 			for (const channel of channels) { | ||||
| 				await channel.play(); | ||||
| 				await new Promise((resolve) => { | ||||
| 					channel.onended = resolve; | ||||
| 				}); | ||||
| 				if (!cycling) { | ||||
| 					break; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		buttons.forEach((button) => (button.disabled = false)); | ||||
| 	} | ||||
| 
 | ||||
| 	function startCycle() { | ||||
| 		cycling = !cycling; | ||||
| 		if (cycling) { | ||||
| 			cycleChannels(); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	onDestroy(() => { | ||||
| 		cycling = false; | ||||
| 	}); | ||||
| </script> | ||||
| 
 | ||||
| <div class="channels" bind:this={channelsEl}> | ||||
| 	<slot /> | ||||
| </div> | ||||
| <div class="controls"> | ||||
| 	<button on:click={startCycle}>Cycle all</button> | ||||
| </div> | ||||
| 
 | ||||
| <style> | ||||
| 	.channels { | ||||
| 		display: flex; | ||||
| 		flex-direction: column; | ||||
| 		justify-content: space-evenly; | ||||
| 		font-size: 2rem; | ||||
| 		flex-grow: 1; | ||||
| 
 | ||||
| 		position: relative; | ||||
| 	} | ||||
| 
 | ||||
| 	:global(.channels .row) { | ||||
| 		display: flex; | ||||
| 		justify-content: space-between; | ||||
| 	} | ||||
| 
 | ||||
| 	.controls { | ||||
| 		text-align: center; | ||||
| 		margin: 2rem 0; | ||||
| 		font-size: 1.5rem; | ||||
| 	} | ||||
| 
 | ||||
| 	:global(.channels .center) { | ||||
| 		font-size: 0.9em; | ||||
| 	} | ||||
| 
 | ||||
| 	:global(.channels .label) { | ||||
| 		opacity: 0.2; | ||||
| 		font-size: 6rem; | ||||
| 
 | ||||
| 		position: absolute; | ||||
| 		top: 50%; | ||||
| 		left: 50%; | ||||
| 		transform: translate(-50%, -50%); | ||||
| 
 | ||||
| 		pointer-events: none; | ||||
| 	} | ||||
| </style> | ||||
|  | @ -1,8 +0,0 @@ | |||
| <script lang="ts"> | ||||
| 	import { onMount } from 'svelte'; | ||||
| 	import { goto } from '$app/navigation'; | ||||
| 
 | ||||
| 	onMount(() => { | ||||
| 		goto('..'); | ||||
| 	}); | ||||
| </script> | ||||
|  | @ -1,14 +0,0 @@ | |||
| <script lang="ts"> | ||||
| 	import Speaker from '../speaker.svelte'; | ||||
| 	import leftUrl from '@assets/audio/stereo/Left.mp3'; | ||||
| 	import centerUrl from '@assets/audio/stereo/Center.mp3'; | ||||
| 	import rightUrl from '@assets/audio/stereo/Right.mp3'; | ||||
| </script> | ||||
| 
 | ||||
| <div class="row"> | ||||
| 	<Speaker src={leftUrl} left>Left</Speaker> | ||||
| 	<div class="center"> | ||||
| 		<Speaker src={centerUrl} center>Center</Speaker> | ||||
| 	</div> | ||||
| 	<Speaker src={rightUrl} right>Right</Speaker> | ||||
| </div> | ||||
							
								
								
									
										7
									
								
								src/routes/card/+page.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/routes/card/+page.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,7 @@ | |||
| import type { PageLoad } from './$types'; | ||||
| 
 | ||||
| export const load: PageLoad = () => { | ||||
| 	return { | ||||
| 		card: true | ||||
| 	}; | ||||
| }; | ||||
		Loading…
	
	Add table
		
		Reference in a new issue