Fix youtube embed
This commit is contained in:
parent
a5579cc474
commit
6750b00f46
@ -11,5 +11,6 @@ $pink: #ff6bb3
|
||||
$blue: #4d9dff
|
||||
$purple: #9c6bff
|
||||
$cyan: #6bffea
|
||||
$orange: #ff9b6b
|
||||
$yellow: #ffde6b
|
||||
$mint-green: #85ffbd
|
@ -4,17 +4,18 @@ import './styles.sass';
|
||||
const YouTubePlayer = ({
|
||||
videoId,
|
||||
autoplay = false,
|
||||
volume = 50,
|
||||
startTime = 45,
|
||||
onReady = () => {},
|
||||
onError = () => {},
|
||||
onPlayerReady = null,
|
||||
className = ''
|
||||
}) => {
|
||||
const iframeRef = useRef(null);
|
||||
const playerRef = useRef(null);
|
||||
const [isLoaded, setIsLoaded] = useState(false);
|
||||
const [customStartTime] = useState(startTime);
|
||||
|
||||
console.log("YouTubePlayer rendering with videoId:", videoId, "volume:", volume, "startTime:", startTime);
|
||||
console.log("YouTubePlayer rendering with videoId:", videoId, "startTime:", startTime);
|
||||
|
||||
useEffect(() => {
|
||||
if (!window.YT) {
|
||||
@ -58,18 +59,38 @@ const YouTubePlayer = ({
|
||||
'showinfo': 0,
|
||||
'rel': 0,
|
||||
'autoplay': autoplay ? 1 : 0,
|
||||
'start': startTime
|
||||
'start': startTime,
|
||||
'modestbranding': 1,
|
||||
'fs': 0,
|
||||
},
|
||||
events: {
|
||||
'onReady': (event) => {
|
||||
console.log("YouTube player ready");
|
||||
event.target.setVolume(volume);
|
||||
if (autoplay) {
|
||||
event.target.seekTo(startTime);
|
||||
event.target.playVideo();
|
||||
const player = event.target;
|
||||
console.log("YouTube player ready event fired");
|
||||
|
||||
playerRef.current = player;
|
||||
|
||||
try {
|
||||
const hasSeekTo = typeof player.seekTo === 'function';
|
||||
console.log(`Player has seekTo: ${hasSeekTo}`);
|
||||
|
||||
// Start playback if needed
|
||||
if (autoplay) {
|
||||
player.seekTo(startTime || 0);
|
||||
player.playVideo();
|
||||
}
|
||||
|
||||
setIsLoaded(true);
|
||||
onReady();
|
||||
|
||||
if (typeof onPlayerReady === 'function') {
|
||||
console.log("Providing player instance to parent");
|
||||
onPlayerReady(player);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("Error in player ready handler:", err);
|
||||
onError(err);
|
||||
}
|
||||
setIsLoaded(true);
|
||||
onReady();
|
||||
},
|
||||
'onError': (event) => {
|
||||
console.error("YouTube player error:", event);
|
||||
@ -94,21 +115,20 @@ const YouTubePlayer = ({
|
||||
}
|
||||
}
|
||||
};
|
||||
}, [videoId, autoplay, onReady, onError, startTime]);
|
||||
}, [videoId, autoplay, onReady, onError, startTime, customStartTime]);
|
||||
|
||||
useEffect(() => {
|
||||
if (playerRef.current && isLoaded) {
|
||||
console.log("Setting YouTube volume to:", volume);
|
||||
if (playerRef.current && isLoaded && customStartTime !== startTime) {
|
||||
try {
|
||||
playerRef.current.setVolume(volume);
|
||||
playerRef.current.seekTo(customStartTime);
|
||||
} catch (error) {
|
||||
console.error("Error setting volume:", error);
|
||||
console.error("Error seeking to time:", error);
|
||||
}
|
||||
}
|
||||
}, [volume, isLoaded]);
|
||||
}, [customStartTime, isLoaded]);
|
||||
|
||||
return (
|
||||
<div className={`youtube-player-container ${className}`}>
|
||||
<div className={`youtube-player-container visible-player ${className}`}>
|
||||
<div ref={iframeRef} className="youtube-embed" />
|
||||
</div>
|
||||
);
|
||||
|
@ -1,19 +1,16 @@
|
||||
.youtube-player-container
|
||||
position: fixed
|
||||
right: 20px
|
||||
bottom: 120px
|
||||
width: 300px
|
||||
height: 200px
|
||||
z-index: 100
|
||||
width: 100%
|
||||
margin: 10px 0
|
||||
border-radius: 12px
|
||||
overflow: hidden
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3)
|
||||
background: #000
|
||||
|
||||
&.hidden-player
|
||||
width: 1px
|
||||
height: 1px
|
||||
opacity: 0
|
||||
overflow: hidden
|
||||
position: absolute
|
||||
left: -9999px
|
||||
top: -9999px
|
||||
&.visible-player
|
||||
height: 200px
|
||||
max-width: 100%
|
||||
opacity: 1
|
||||
z-index: 1
|
||||
|
||||
.youtube-embed
|
||||
width: 100%
|
||||
|
@ -10,7 +10,9 @@ import {
|
||||
faClock,
|
||||
faCrown,
|
||||
faPaperPlane,
|
||||
faCheckCircle
|
||||
faCheckCircle,
|
||||
faVolumeUp,
|
||||
faStepForward
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import { fetchPlaylistSongs } from "@/services/youtubeService.js";
|
||||
import YouTubePlayer from "../../components/YouTubePlayer/YouTubePlayer";
|
||||
@ -45,13 +47,13 @@ export const Game = () => {
|
||||
const timerIntervalRef = useRef(null);
|
||||
|
||||
const [allSongs, setAllSongs] = useState([]);
|
||||
const [playerVolume, setPlayerVolume] = useState(30);
|
||||
const [playbackError, setPlaybackError] = useState(null);
|
||||
const [songsLoading, setSongsLoading] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (!connected) return;
|
||||
|
||||
|
||||
const eventHandlers = {
|
||||
"roles-assigned": (roles) => {
|
||||
const myRole = roles[socket?.id];
|
||||
@ -256,8 +258,24 @@ export const Game = () => {
|
||||
setTimeLeft(0);
|
||||
}, [send]);
|
||||
|
||||
const handlePlayerReady = useCallback(() => {
|
||||
const handlePlayerReady = useCallback((player) => {
|
||||
console.log("Player ready handler called with:", player);
|
||||
setPlaybackError(null);
|
||||
|
||||
if (player && typeof player.seekTo === 'function') {
|
||||
console.log("Setting valid YouTube player instance");
|
||||
setYtPlayer(player);
|
||||
|
||||
try {
|
||||
const currentTime = player.getCurrentTime();
|
||||
console.log(`Player initialized at ${currentTime}s`);
|
||||
} catch (err) {
|
||||
console.error("Error testing player methods:", err);
|
||||
}
|
||||
} else {
|
||||
console.error("Invalid YouTube player instance provided:", player);
|
||||
setPlaybackError("YouTube player initialization issue");
|
||||
}
|
||||
}, []);
|
||||
|
||||
const handlePlayerError = useCallback((error) => {
|
||||
@ -305,7 +323,22 @@ export const Game = () => {
|
||||
<div className="song-description">von {currentSong.artist}</div>
|
||||
</div>
|
||||
</div>
|
||||
<p className="instruction">Spiele diesen Song mit dem Tonregler!</p>
|
||||
|
||||
<div className="song-player-container">
|
||||
<YouTubePlayer
|
||||
videoId={currentSong.youtubeId}
|
||||
autoplay={true}
|
||||
startTime={currentSong.refrainTime || 45}
|
||||
onReady={handlePlayerReady}
|
||||
onPlayerReady={setYtPlayer}
|
||||
onError={handlePlayerError}
|
||||
className="song-embedded-player"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="music-controls">
|
||||
<p className="instruction">Use the player above to listen, and the tone slider to play!</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@ -521,40 +554,12 @@ export const Game = () => {
|
||||
/>
|
||||
)}
|
||||
|
||||
{role === "composer" && currentSong && currentSong.youtubeId && (
|
||||
<YouTubePlayer
|
||||
videoId={currentSong.youtubeId}
|
||||
autoplay={phase === "composing"}
|
||||
volume={playerVolume}
|
||||
startTime={currentSong.refrainTime || 45}
|
||||
onReady={handlePlayerReady}
|
||||
onError={handlePlayerError}
|
||||
className={phase === "composing" ? "" : "hidden-player"}
|
||||
/>
|
||||
)}
|
||||
|
||||
{playbackError && (
|
||||
<div className="playback-error">
|
||||
{playbackError}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{phase === "composing" && role === "composer" && currentSong && (
|
||||
<div className="player-controls">
|
||||
<div className="volume-controls">
|
||||
<span>Music Volume:</span>
|
||||
<input
|
||||
type="range"
|
||||
min="0"
|
||||
max="100"
|
||||
value={playerVolume}
|
||||
onChange={(e) => setPlayerVolume(parseInt(e.target.value))}
|
||||
className="volume-slider"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{songsLoading && (
|
||||
<div className="songs-loading-indicator">
|
||||
Loading songs...
|
||||
|
@ -264,6 +264,11 @@
|
||||
|
||||
.song-display
|
||||
text-align: center
|
||||
display: flex
|
||||
flex-direction: column
|
||||
align-items: center
|
||||
width: 100%
|
||||
margin-bottom: 30px
|
||||
|
||||
.song-card
|
||||
display: flex
|
||||
@ -274,6 +279,11 @@
|
||||
border-radius: 20px
|
||||
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3)
|
||||
backdrop-filter: blur(10px)
|
||||
background: rgba(255, 255, 255, 0.08)
|
||||
padding: 25px
|
||||
border-radius: 20px
|
||||
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3)
|
||||
backdrop-filter: blur(10px)
|
||||
border: 1px solid rgba(255, 255, 255, 0.2)
|
||||
max-width: 500px
|
||||
margin: 20px auto
|
||||
@ -304,295 +314,13 @@
|
||||
font-size: 16px
|
||||
color: rgba(255, 255, 255, 0.7)
|
||||
|
||||
.phase-header
|
||||
display: flex
|
||||
justify-content: space-between
|
||||
align-items: center
|
||||
width: 100%
|
||||
margin-bottom: 30px
|
||||
|
||||
h3
|
||||
font-size: 24px
|
||||
margin: 0
|
||||
color: $white
|
||||
text-shadow: 0 0 10px rgba(255, 255, 255, 0.3)
|
||||
|
||||
.timer
|
||||
background: rgba(255, 255, 255, 0.1)
|
||||
padding: 10px 20px
|
||||
border-radius: 15px
|
||||
font-size: 18px
|
||||
display: flex
|
||||
align-items: center
|
||||
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2)
|
||||
border: 1px solid rgba(255, 255, 255, 0.1)
|
||||
|
||||
svg
|
||||
margin-right: 10px
|
||||
color: $yellow
|
||||
|
||||
// Improved song selection grid
|
||||
.song-selection
|
||||
width: 100%
|
||||
|
||||
.instruction
|
||||
text-align: center
|
||||
font-size: 20px
|
||||
margin-bottom: 30px
|
||||
color: $white
|
||||
|
||||
.song-grid
|
||||
display: grid
|
||||
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr))
|
||||
gap: 20px
|
||||
margin-top: 20px
|
||||
|
||||
.song-option
|
||||
background: rgba(255, 255, 255, 0.1)
|
||||
border-radius: 15px
|
||||
overflow: hidden
|
||||
cursor: pointer
|
||||
transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275)
|
||||
border: 2px solid transparent
|
||||
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.3)
|
||||
height: 100%
|
||||
|
||||
&:hover:not(.disabled)
|
||||
transform: translateY(-8px) scale(1.03)
|
||||
box-shadow: 0 15px 30px rgba(0, 0, 0, 0.4), 0 0 25px rgba(255, 255, 255, 0.1)
|
||||
background: rgba(255, 255, 255, 0.15)
|
||||
|
||||
&.selected
|
||||
border: 2px solid $yellow
|
||||
box-shadow: 0 0 25px rgba(255, 255, 0, 0.4), 0 10px 30px rgba(0, 0, 0, 0.4)
|
||||
background: rgba(255, 255, 255, 0.15)
|
||||
|
||||
&.disabled
|
||||
opacity: 0.7
|
||||
cursor: default
|
||||
|
||||
.song-image
|
||||
position: relative
|
||||
|
||||
img
|
||||
width: 100%
|
||||
height: 150px
|
||||
object-fit: cover
|
||||
|
||||
.selection-indicator
|
||||
position: absolute
|
||||
top: 10px
|
||||
right: 10px
|
||||
background: $yellow
|
||||
width: 30px
|
||||
height: 30px
|
||||
border-radius: 50%
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: center
|
||||
box-shadow: 0 0 15px rgba(255, 255, 0, 0.7)
|
||||
|
||||
.song-details
|
||||
padding: 15px
|
||||
|
||||
.song-title
|
||||
font-weight: bold
|
||||
font-size: 16px
|
||||
color: $white
|
||||
|
||||
.song-artist
|
||||
font-size: 14px
|
||||
opacity: 0.7
|
||||
margin-top: 5px
|
||||
|
||||
// Results phase improvements
|
||||
.results-phase
|
||||
text-align: center
|
||||
|
||||
h3
|
||||
font-size: 28px
|
||||
margin-bottom: 40px
|
||||
|
||||
.round-results
|
||||
background: rgba(255, 255, 255, 0.08)
|
||||
backdrop-filter: blur(10px)
|
||||
border-radius: 25px
|
||||
padding: 30px
|
||||
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.4)
|
||||
border: 1px solid rgba(255, 255, 255, 0.15)
|
||||
max-width: 600px
|
||||
margin: 0 auto
|
||||
|
||||
.scoreboard
|
||||
.music-controls
|
||||
margin-top: 30px
|
||||
padding-top: 20px
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.1)
|
||||
|
||||
h4
|
||||
margin-bottom: 15px
|
||||
font-size: 20px
|
||||
|
||||
.scores
|
||||
display: grid
|
||||
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr))
|
||||
gap: 10px
|
||||
|
||||
.score-entry
|
||||
background: rgba(255, 255, 255, 0.1)
|
||||
border-radius: 10px
|
||||
padding: 10px 15px
|
||||
display: flex
|
||||
justify-content: space-between
|
||||
align-items: center
|
||||
|
||||
&:nth-child(1)
|
||||
background: linear-gradient(135deg, rgba(255, 215, 0, 0.2), rgba(255, 215, 0, 0.1))
|
||||
box-shadow: 0 0 20px rgba(255, 215, 0, 0.3)
|
||||
|
||||
&:nth-child(2)
|
||||
background: linear-gradient(135deg, rgba(192, 192, 192, 0.2), rgba(192, 192, 192, 0.1))
|
||||
|
||||
&:nth-child(3)
|
||||
background: linear-gradient(135deg, rgba(205, 127, 50, 0.2), rgba(205, 127, 50, 0.1))
|
||||
|
||||
.player-name
|
||||
display: flex
|
||||
align-items: center
|
||||
|
||||
.host-icon
|
||||
color: $yellow
|
||||
margin-left: 5px
|
||||
|
||||
// Responsive adjustments
|
||||
@media (max-width: 900px)
|
||||
.game-layout
|
||||
flex-direction: column
|
||||
|
||||
.main-content
|
||||
margin-right: 0
|
||||
margin-bottom: 20px
|
||||
|
||||
.chat-panel
|
||||
width: 100%
|
||||
max-height: 300px
|
||||
|
||||
// Animations
|
||||
@keyframes slide-in-right
|
||||
0%
|
||||
transform: translateX(30px)
|
||||
opacity: 0
|
||||
100%
|
||||
transform: translateX(0)
|
||||
opacity: 1
|
||||
|
||||
// ...existing animations...
|
||||
|
||||
.song-display
|
||||
width: 100%
|
||||
max-width: 400px
|
||||
display: flex
|
||||
flex-direction: column
|
||||
align-items: center
|
||||
justify-content: center
|
||||
width: 50%
|
||||
margin-right: 20px
|
||||
color: $white
|
||||
text-align: center
|
||||
|
||||
h2
|
||||
font-size: 52pt
|
||||
color: $white
|
||||
margin-bottom: 25px
|
||||
position: relative
|
||||
z-index: 2
|
||||
background: linear-gradient(135deg, $pink, $blue 45%, $mint-green 65%, $yellow 85%, $pink)
|
||||
background-size: 300% 100%
|
||||
animation: title-shimmer 10s infinite alternate ease-in-out, title-float 6s infinite ease-in-out
|
||||
-webkit-background-clip: text
|
||||
background-clip: text
|
||||
-webkit-text-fill-color: transparent
|
||||
filter: drop-shadow(0 0 15px rgba(255, 255, 255, 0.7))
|
||||
letter-spacing: 0.1em
|
||||
font-weight: bold
|
||||
|
||||
&:before
|
||||
content: "ToneGuessr"
|
||||
position: absolute
|
||||
z-index: -1
|
||||
left: 0
|
||||
top: 0
|
||||
background: none
|
||||
-webkit-text-fill-color: transparent
|
||||
filter: blur(15px) brightness(1.3)
|
||||
opacity: 0.6
|
||||
width: 100%
|
||||
height: 100%
|
||||
|
||||
.song-card
|
||||
display: flex
|
||||
flex-direction: row
|
||||
align-items: center
|
||||
background: rgba(255, 255, 255, 0.08)
|
||||
padding: 25px
|
||||
border-radius: 20px
|
||||
box-shadow: 0 4px 30px rgba(0, 0, 0, 0.2), 0 0 20px rgba(255, 255, 255, 0.1)
|
||||
backdrop-filter: blur(10px)
|
||||
border: 1px solid rgba(255, 255, 255, 0.2)
|
||||
max-width: 500px
|
||||
transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275)
|
||||
will-change: transform, box-shadow
|
||||
transform: translateZ(0)
|
||||
backface-visibility: hidden
|
||||
animation: card-pulse 6s infinite alternate ease-in-out
|
||||
|
||||
&:hover
|
||||
transform: translateY(-10px) scale(1.02)
|
||||
box-shadow: 0 15px 40px rgba(0, 0, 0, 0.3), 0 0 30px rgba(255, 255, 255, 0.15)
|
||||
border: 1px solid rgba(255, 255, 255, 0.4)
|
||||
|
||||
img
|
||||
width: 120px
|
||||
height: 120px
|
||||
border-radius: 15px
|
||||
margin-right: 25px
|
||||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4)
|
||||
transition: transform 0.3s ease
|
||||
will-change: transform
|
||||
transform: translateZ(0)
|
||||
animation: album-rotate 10s infinite alternate ease-in-out
|
||||
|
||||
&:hover
|
||||
transform: scale(1.1) rotate(5deg)
|
||||
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.5), 0 0 40px rgba(102, 204, 255, 0.3)
|
||||
|
||||
.song-info
|
||||
display: flex
|
||||
flex-direction: column
|
||||
align-items: flex-start
|
||||
|
||||
.song-names
|
||||
font-size: 28pt
|
||||
color: $white
|
||||
margin-bottom: 10px
|
||||
text-shadow: 0 0 10px rgba(255, 255, 255, 0.5)
|
||||
animation: text-shimmer 5s infinite alternate ease-in-out
|
||||
|
||||
.song-description
|
||||
font-size: 16pt
|
||||
color: $border
|
||||
opacity: 0.8
|
||||
position: relative
|
||||
|
||||
&:after
|
||||
content: ""
|
||||
position: absolute
|
||||
bottom: -5px
|
||||
left: 0
|
||||
width: 0%
|
||||
height: 1px
|
||||
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.7), transparent)
|
||||
transition: all 0.4s ease
|
||||
|
||||
&:hover:after
|
||||
width: 100%
|
||||
|
||||
.chat-window
|
||||
width: 50%
|
||||
@ -963,56 +691,13 @@
|
||||
opacity: 1
|
||||
transform: scale(1.05)
|
||||
|
||||
.volume-controls
|
||||
position: fixed
|
||||
top: 70px
|
||||
right: 20px
|
||||
background: rgba(0, 0, 0, 0.5)
|
||||
padding: 10px 15px
|
||||
border-radius: 10px
|
||||
display: flex
|
||||
align-items: center
|
||||
z-index: 10
|
||||
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3)
|
||||
|
||||
span
|
||||
color: white
|
||||
margin-right: 10px
|
||||
font-size: 14px
|
||||
|
||||
.volume-slider
|
||||
width: 100px
|
||||
height: 6px
|
||||
-webkit-appearance: none
|
||||
appearance: none
|
||||
background: rgba(255, 255, 255, 0.2)
|
||||
border-radius: 3px
|
||||
outline: none
|
||||
|
||||
&::-webkit-slider-thumb
|
||||
-webkit-appearance: none
|
||||
appearance: none
|
||||
width: 16px
|
||||
height: 16px
|
||||
border-radius: 50%
|
||||
background: $yellow
|
||||
cursor: pointer
|
||||
box-shadow: 0 0 10px rgba(255, 255, 0, 0.5)
|
||||
|
||||
&::-moz-range-thumb
|
||||
width: 16px
|
||||
height: 16px
|
||||
border-radius: 50%
|
||||
background: $yellow
|
||||
cursor: pointer
|
||||
box-shadow: 0 0 10px rgba(255, 255, 0, 0.5)
|
||||
|
||||
.playback-error
|
||||
position: fixed
|
||||
bottom: 10px
|
||||
left: 50%
|
||||
transform: translateX(-50%)
|
||||
background: rgba(255, 0, 0, 0.7)
|
||||
margin-left: 10px
|
||||
color: white
|
||||
padding: 8px 20px
|
||||
border-radius: 20px
|
||||
@ -1025,4 +710,114 @@
|
||||
0%, 80%
|
||||
opacity: 1
|
||||
100%
|
||||
opacity: 0
|
||||
opacity: 0
|
||||
|
||||
.player-container
|
||||
position: fixed
|
||||
left: 20px
|
||||
bottom: 20px
|
||||
display: flex
|
||||
flex-direction: column
|
||||
align-items: flex-start
|
||||
z-index: 100
|
||||
background: rgba(0, 0, 0, 0.5)
|
||||
padding: 10px
|
||||
border-radius: 10px
|
||||
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3)
|
||||
max-width: 320px
|
||||
|
||||
.player-controls
|
||||
width: 100%
|
||||
margin-top: 10px
|
||||
position: relative
|
||||
left: auto
|
||||
top: auto
|
||||
right: auto
|
||||
background: none
|
||||
box-shadow: none
|
||||
padding: 0
|
||||
|
||||
.volume-controls
|
||||
width: 100%
|
||||
display: flex
|
||||
align-items: center
|
||||
background: none
|
||||
padding: 5px 0
|
||||
position: static
|
||||
box-shadow: none
|
||||
|
||||
span
|
||||
white-space: nowrap
|
||||
|
||||
.volume-slider
|
||||
flex: 1
|
||||
margin-left: 10px
|
||||
|
||||
.composer-player
|
||||
width: 300px
|
||||
height: 169px
|
||||
border-radius: 8px
|
||||
overflow: hidden
|
||||
|
||||
.composer-player
|
||||
width: 300px
|
||||
height: 169px
|
||||
border-radius: 8px
|
||||
overflow: hidden
|
||||
|
||||
.position-jump-button
|
||||
display: block
|
||||
margin-top: 10px
|
||||
padding: 8px 15px
|
||||
background: linear-gradient(135deg, $yellow, $orange)
|
||||
color: #fff
|
||||
border: none
|
||||
border-radius: 8px
|
||||
font-size: 14px
|
||||
font-weight: 600
|
||||
cursor: pointer
|
||||
transition: all 0.2s ease
|
||||
width: 100%
|
||||
|
||||
&:hover
|
||||
background: linear-gradient(135deg, lighten($yellow, 5%), lighten($orange, 5%))
|
||||
transform: translateY(-2px)
|
||||
box-shadow: 0 4px 15px rgba(255, 204, 0, 0.3)
|
||||
|
||||
&:active
|
||||
transform: translateY(0)
|
||||
|
||||
.player-container
|
||||
width: 100%
|
||||
margin-top: 20px
|
||||
background: rgba(20, 20, 20, 0.5)
|
||||
backdrop-filter: blur(10px)
|
||||
padding: 15px
|
||||
border-radius: 15px
|
||||
border: 1px solid rgba(255, 255, 255, 0.1)
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3)
|
||||
|
||||
h4
|
||||
color: $white
|
||||
margin: 0 0 15px 0
|
||||
text-align: center
|
||||
font-size: 16px
|
||||
|
||||
.embedded-player
|
||||
width: 100%
|
||||
border-radius: 8px
|
||||
overflow: hidden
|
||||
|
||||
.song-player-container
|
||||
width: 100%
|
||||
max-width: 500px
|
||||
margin: 20px auto
|
||||
border-radius: 15px
|
||||
overflow: hidden
|
||||
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.25)
|
||||
background: rgba(0, 0, 0, 0.5)
|
||||
|
||||
.song-embedded-player
|
||||
width: 100%
|
||||
height: auto
|
||||
aspect-ratio: 16 / 9
|
Loading…
x
Reference in New Issue
Block a user