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; |   margin-top: 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -20,11 +20,11 @@ | ||||||
| 		}); | 		}); | ||||||
| 	}); | 	}); | ||||||
| 
 | 
 | ||||||
| 	$: onlyCard = $page.url.pathname === '/card'; | 	$: onlyCard = $page.data.card; | ||||||
| </script> | </script> | ||||||
| 
 | 
 | ||||||
| <TestCard full={onlyCard} on:focus={() => goto('/card')} /> | <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> | 	<a href=".." class="button button-back"><i class="ti ti-arrow-back" />Back</a> | ||||||
| 	<slot /> | 	<slot /> | ||||||
| </main> | </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"> | <script lang="ts"> | ||||||
| 	import { createEventDispatcher, onMount } from 'svelte'; |  | ||||||
| 	const dispatch = createEventDispatcher<{ end: void }>(); |  | ||||||
| 
 |  | ||||||
| 	export let src: string; | 	export let src: string; | ||||||
| 	export let left = false; | 	export let left = false; | ||||||
| 	export let center = false; | 	export let center = false; | ||||||
| 	export let right = false; | 	export let right = false; | ||||||
| 	export let lfe = false; | 	export let lfe = false; | ||||||
|  | 	export let inline = false; | ||||||
| 
 | 
 | ||||||
| 	let currentTime = 0; | 	let currentTime = 0; | ||||||
| 	let paused = true; | 	let paused = true; | ||||||
|  | @ -22,6 +20,7 @@ | ||||||
| 	class:right | 	class:right | ||||||
| 	class:center | 	class:center | ||||||
| 	class:lfe | 	class:lfe | ||||||
|  | 	class:inline | ||||||
| 	class:playing={!paused} | 	class:playing={!paused} | ||||||
| 	on:click={play} | 	on:click={play} | ||||||
| > | > | ||||||
|  | @ -30,7 +29,7 @@ | ||||||
| 	{:else} | 	{:else} | ||||||
| 		<i class="ti ti-wave-sine"></i> | 		<i class="ti ti-wave-sine"></i> | ||||||
| 	{/if} | 	{/if} | ||||||
| 	<label><slot /></label> | 	<span><slot /></span> | ||||||
| 	<audio bind:currentTime bind:paused {src}></audio> | 	<audio bind:currentTime bind:paused {src}></audio> | ||||||
| </button> | </button> | ||||||
| 
 | 
 | ||||||
|  | @ -43,6 +42,8 @@ | ||||||
| 		flex-direction: column; | 		flex-direction: column; | ||||||
| 		text-align: center; | 		text-align: center; | ||||||
| 
 | 
 | ||||||
|  | 		opacity: 0.8; | ||||||
|  | 
 | ||||||
| 		& .ti { | 		& .ti { | ||||||
| 			font-size: 3em; | 			font-size: 3em; | ||||||
| 		} | 		} | ||||||
|  | @ -58,11 +59,39 @@ | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		&:disabled { | 		&:disabled { | ||||||
| 			opacity: 0.33; | 			opacity: 0.5; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		&.playing { | 		&.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> | </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> | <script lang="ts"> | ||||||
| <ul> | 	import StereoTest from './(channels)/stereo-test.svelte'; | ||||||
| 	<li><a href="channels/stereo">Stereo</a></li> | </script> | ||||||
| 	<li><a href="channels/5.1">5.1 Surround</a></li> | 
 | ||||||
| 	<li><a href="channels/7.1">7.1 Surround</a></li> | <article> | ||||||
| </ul> | 	<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> | <style> | ||||||
|  | 	h4 { | ||||||
|  | 		margin-bottom: 0; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	ul { | 	ul { | ||||||
| 		list-style-type: none; | 		list-style-type: none; | ||||||
| 		padding: 0; | 		padding: 0; | ||||||
| 		margin: 0; | 		margin: 0; | ||||||
| 
 | 
 | ||||||
| 		display: flex; | 		display: inline-flex; | ||||||
| 		gap: 1rem; | 		gap: 1em; | ||||||
| 	} | 	} | ||||||
| 	li { | 
 | ||||||
| 		margin-bottom: 10px; | 	section { | ||||||
|  | 		margin: 1em 0; | ||||||
| 	} | 	} | ||||||
| </style> | </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