Migrate to components
This commit is contained in:
@ -1,179 +0,0 @@
|
||||
import "./styles.sass";
|
||||
import {StateContext} from "@/common/contexts/StateContext";
|
||||
import {useContext, useState, useEffect, useRef} from "react";
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { faMusic } from '@fortawesome/free-solid-svg-icons';
|
||||
|
||||
export const Home = () => {
|
||||
const {setCurrentState} = useContext(StateContext);
|
||||
const [frequency, setFrequency] = useState(440);
|
||||
const [isPlaying, setIsPlaying] = useState(false);
|
||||
const [dragging, setDragging] = useState(false);
|
||||
const audioContextRef = useRef(null);
|
||||
const oscillatorRef = useRef(null);
|
||||
const gainNodeRef = useRef(null);
|
||||
const sliderRef = useRef(null);
|
||||
const [messages, setMessages] = useState([{ sender: "Marco", text: "Hallo!" },]);
|
||||
const [inputValue, setInputValue] = useState("");
|
||||
const messageEndRef = useRef(null);
|
||||
|
||||
const startAudio = () => {
|
||||
if (!audioContextRef.current) {
|
||||
audioContextRef.current = new (window.AudioContext || window.webkitAudioContext)();
|
||||
}
|
||||
if (!oscillatorRef.current) {
|
||||
oscillatorRef.current = audioContextRef.current.createOscillator();
|
||||
oscillatorRef.current.type = 'sine';
|
||||
oscillatorRef.current.frequency.setValueAtTime(frequency, audioContextRef.current.currentTime);
|
||||
|
||||
gainNodeRef.current = audioContextRef.current.createGain();
|
||||
gainNodeRef.current.gain.setValueAtTime(0.5, audioContextRef.current.currentTime);
|
||||
|
||||
oscillatorRef.current.connect(gainNodeRef.current);
|
||||
gainNodeRef.current.connect(audioContextRef.current.destination);
|
||||
oscillatorRef.current.start();
|
||||
} else {
|
||||
oscillatorRef.current.frequency.setValueAtTime(frequency, audioContextRef.current.currentTime);
|
||||
}
|
||||
setIsPlaying(true);
|
||||
};
|
||||
|
||||
const stopAudio = () => {
|
||||
if (oscillatorRef.current) {
|
||||
oscillatorRef.current.stop();
|
||||
oscillatorRef.current.disconnect();
|
||||
oscillatorRef.current = null;
|
||||
}
|
||||
setIsPlaying(false);
|
||||
};
|
||||
|
||||
const handleMouseDown = (e) => {
|
||||
setDragging(true);
|
||||
startAudio();
|
||||
handleFrequencyChange(e);
|
||||
};
|
||||
|
||||
const handleMouseUp = () => {
|
||||
setDragging(false);
|
||||
stopAudio();
|
||||
};
|
||||
|
||||
const handleFrequencyChange = (e) => {
|
||||
const rect = sliderRef.current.getBoundingClientRect();
|
||||
const x = e.clientX - rect.left;
|
||||
const clampedX = Math.max(0, Math.min(x, rect.width));
|
||||
const newFrequency = 20 + (clampedX / rect.width) * 1980;
|
||||
setFrequency(newFrequency);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const handleMouseMove = (e) => {
|
||||
if (dragging) {
|
||||
handleFrequencyChange(e);
|
||||
}
|
||||
};
|
||||
|
||||
const handleMouseUpGlobal = () => {
|
||||
if (dragging) {
|
||||
handleMouseUp();
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener('mousemove', handleMouseMove);
|
||||
document.addEventListener('mouseup', handleMouseUpGlobal);
|
||||
|
||||
return () => {
|
||||
document.removeEventListener('mousemove', handleMouseMove);
|
||||
document.removeEventListener('mouseup', handleMouseUpGlobal);
|
||||
};
|
||||
}, [dragging]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isPlaying) {
|
||||
if (oscillatorRef.current) {
|
||||
oscillatorRef.current.frequency.setValueAtTime(frequency, audioContextRef.current.currentTime);
|
||||
}
|
||||
}
|
||||
}, [frequency, isPlaying]);
|
||||
|
||||
useEffect(() => {
|
||||
messageEndRef.current?.scrollIntoView({ behavior: "smooth" });
|
||||
}, [messages]);
|
||||
|
||||
const handleSendMessage = () => {
|
||||
if (inputValue.trim()) {
|
||||
setMessages([...messages, { sender: "User", text: inputValue }]);
|
||||
setInputValue("");
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="home-page">
|
||||
<div className="background-elements">
|
||||
<FontAwesomeIcon icon={faMusic} className="music-note note-1" />
|
||||
<FontAwesomeIcon icon={faMusic} className="music-note note-2" />
|
||||
<FontAwesomeIcon icon={faMusic} className="music-note note-3" />
|
||||
</div>
|
||||
<div className="main-content">
|
||||
<div className="song-display">
|
||||
<h2>ToneGuessr</h2>
|
||||
<div className="song-card">
|
||||
<img src="https://mir-s3-cdn-cf.behance.net/project_modules/1400/fe529a64193929.5aca8500ba9ab.jpg" alt="Song" />
|
||||
<div className="song-info">
|
||||
<div className="song-name">Black Steam</div>
|
||||
<div className="song-description">von Carrot Quest GmbH</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="chat-window">
|
||||
<div className="chat-header">
|
||||
<div className="account-icon"></div>
|
||||
<div className="chat-title">Chat</div>
|
||||
</div>
|
||||
<div className="chat-messages">
|
||||
{messages.map((message, index) => (
|
||||
<div key={index} className="message">
|
||||
<span className="message-sender">{message.sender}:</span>
|
||||
<span className="message-text">{message.text}</span>
|
||||
</div>
|
||||
))}
|
||||
<div ref={messageEndRef}></div>
|
||||
</div>
|
||||
<div className="chat-input">
|
||||
<input
|
||||
type="text"
|
||||
value={inputValue}
|
||||
onChange={(e) => setInputValue(e.target.value)}
|
||||
onKeyPress={(e) => e.key === 'Enter' && handleSendMessage()}
|
||||
placeholder="Gib eine Nachricht ein..."
|
||||
/>
|
||||
<button onClick={handleSendMessage}>Send</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="otamatone-container">
|
||||
<div
|
||||
className="otamatone"
|
||||
onMouseDown={handleMouseDown}
|
||||
>
|
||||
<div className="otamatone-neck" ref={sliderRef}>
|
||||
<div className="frequency-indicator" style={{ left: `${(frequency - 20) / 1980 * 100}%` }}></div>
|
||||
<div className="note-marker" style={{left: '10%', pointerEvents: 'none'}}>♩</div>
|
||||
<div className="note-marker" style={{left: '50%', pointerEvents: 'none'}}>♪</div>
|
||||
<div className="note-marker" style={{left: '90%', pointerEvents: 'none'}}>♫</div>
|
||||
</div>
|
||||
<div className="otamatone-face">
|
||||
<div
|
||||
className="otamatone-mouth"
|
||||
style={{ height: `${10 + (frequency / 2000) * 40}px`, width: `${10 + (frequency / 2000) * 40}px` }}
|
||||
></div>
|
||||
<div className="otamatone-eyes">
|
||||
<div className="eye left-eye"></div>
|
||||
<div className="eye right-eye"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
Reference in New Issue
Block a user