1. デザインのタイプ
【ミニマル・フローティング・ミュージックプレーヤー】
アルバムアートが回転し、再生に合わせて情報パネルがスライド展開する、立体的でインタラクティブなデザイン。レコードがスピンするような情緒的な演出と、モダンなフラットUIを融合させた、視覚的にも楽しめるオーディオプレイヤーです。
2. デザインの特徴
- 動的なレイアウト展開
再生を開始すると、曲情報とタイムラインが背後からスライドして現れるインタラクティブな設計。 - レコード風アニメーション
再生中にアルバム画像がスムーズに回転し、視覚的に再生状態を伝える情緒的な演出を実現。
3. 紹介コード
<div class="player-wrapper">
<div class="player">
<div class="player__bar">
<div class="player__album">
<div class="player__albumImg active-song"
data-author="アーティスト名"
data-song="曲名"
data-src="音楽ファイルURL"
style="background-image: url(画像URL)">
</div>
<div class="player__albumImg"
data-author="アーティスト名"
data-song="曲名"
data-src="音楽ファイルURL"
style="background-image: url(画像URL)">
</div>
</div>
<div class="player__controls">
<div class="player__prev">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><path d="M26.695 34.434v31.132L54.5 49.998z"/><path d="M24.07 34.434v31.132c0 2.018 2.222 3.234 3.95 2.267l27.804-15.568c1.706-.955 1.707-3.578 0-4.533L28.02 32.168c-2.957-1.655-5.604 2.88-2.649 4.533l27.805 15.564v-4.533L25.371 63.3l3.95 2.267V34.435c-.001-3.387-5.251-3.387-5.251-.001z"/><g><path d="M55.5 34.434v31.132l27.805-15.568z"/><path d="M52.875 34.434v31.132c0 2.018 2.222 3.234 3.949 2.267 9.27-5.189 18.537-10.379 27.805-15.568 1.705-.955 1.705-3.578 0-4.533L56.824 32.168c-2.957-1.655-5.604 2.88-2.648 4.533l27.803 15.564v-4.533L54.176 63.3l3.949 2.267V34.435c0-3.387-5.25-3.387-5.25-.001z"/></g></svg>
</div>
<div class="player__play">
<svg class="icon play" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><path d="M51.109 30.335l-36-24A2 2 0 0 0 12 8v48a2.003 2.003 0 0 0 2 2c.388 0 .775-.113 1.109-.336l36-24a2 2 0 0 0 0-3.329z"/></svg>
<svg class="icon pause" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><path d="M22.537 8.046h17.791c1.104 0 2.003.898 2.003 1.993v79.912a2.005 2.005 0 0 1-2.003 2.003h-17.79a2.005 2.005 0 0 1-2.003-2.003V10.04c0-1.095.898-1.993 2.002-1.993zM59.672 8.046h17.8c1.095 0 1.993.898 1.993 1.993v79.912a2.003 2.003 0 0 1-1.993 2.003h-17.8a1.997 1.997 0 0 1-1.993-2.003V10.04c0-1.095.889-1.993 1.993-1.993z"/></svg>
</div>
<div class="player__next">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><path d="M26.695 34.434v31.132L54.5 49.998z"/><path d="M24.07 34.434v31.132c0 2.018 2.222 3.234 3.95 2.267l27.804-15.568c1.706-.955 1.707-3.578 0-4.533L28.02 32.168c-2.957-1.655-5.604 2.88-2.649 4.533l27.805 15.564v-4.533L25.371 63.3l3.95 2.267V34.435c-.001-3.387-5.251-3.387-5.251-.001z"/><g><path d="M55.5 34.434v31.132l27.805-15.568z"/><path d="M52.875 34.434v31.132c0 2.018 2.222 3.234 3.949 2.267 9.27-5.189 18.537-10.379 27.805-15.568 1.705-.955 1.705-3.578 0-4.533L56.824 32.168c-2.957-1.655-5.604 2.88-2.648 4.533l27.803 15.564v-4.533L54.176 63.3l3.949 2.267V34.435c0-3.387-5.25-3.387-5.25-.001z"/></g></svg>
</div>
</div>
</div>
<div class="player__timeline">
<p class="player__author"></p>
<p class="player__song"></p>
<div class="player__timelineBar"><div id="playhead"></div></div>
</div>
</div>
</div>
<style>
/* --- プレイヤーのスタイル --- */
.player-wrapper {
position: relative;
width: 100%;
min-height: 250px;
background: #ffeff5;
display: flex;
justify-content: center;
align-items: center;
margin: 40px 0;
border-radius: 15px;
font-family: sans-serif;
}
.player {
position: relative;
width: 380px;
z-index: 10;
}
.icon {
display: inline-block;
width: 2em;
height: 2em;
font-size: 24px;
fill: #D7DCE2;
transition: all .2s ease-in-out;
}
.player__album {
width: 115px;
height: 115px;
border-radius: 50%;
margin-right: 15px;
position: relative;
transform: translateY(-50px);
transition: all .4s ease-in-out;
flex-shrink: 0;
}
.player.play .player__album {
transform: translateY(-65px);
}
.player__album:before {
content: '';
width: 25px;
height: 25px;
position: absolute;
z-index: 5;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: #fff;
border-radius: 50%;
}
.player__albumImg {
background-size: cover;
background-position: center;
background-repeat: no-repeat;
width: 100%;
height: 100%;
border-radius: 50%;
position: relative;
z-index: 2;
display: none;
box-shadow: 0 5px 15px rgba(0,0,0,0.1);
}
.player.play .player__albumImg {
box-shadow: 0 15px 35px rgba(0,0,0,0.2);
}
.player__albumImg.active-song { display: block; }
.player__bar {
background: #fff;
padding: 10px 15px;
height: 90px;
display: flex;
justify-content: flex-start;
align-items: center;
border-radius: 15px;
box-shadow: 0 30px 56px 6px rgba(0, 0, 0, 0.1);
position: relative;
z-index: 3;
}
.player__controls {
display: flex;
align-items: center;
margin-left: 5px;
}
.player__prev, .player__play, .player__next {
cursor: pointer;
height: 70px;
width: 70px;
display: flex;
justify-content: center;
align-items: center;
border-radius: 12px;
transition: all .2s ease-in-out;
}
.player__prev { transform: rotate(180deg); margin-right: 2px; }
.player__play { margin-right: 2px; position: relative; }
.player__next { margin-left: -5px; }
.player__prev:hover, .player__play:hover, .player__next:hover { background: #D7DCE2; }
.player__prev:hover svg, .player__play:hover svg, .player__next:hover svg { fill: #fff; }
.player.play .pause { display: inline-block; }
.player.play .play { display: none; }
.player:not(.play) .pause { display: none; }
.player:not(.play) .play { display: inline-block; }
.player__timeline {
background: #fff6fb;
height: 95px;
border-radius: 15px;
position: absolute;
bottom: 0;
left: 10px;
right: 10px;
transform: translateY(0);
transition: all .3s ease-in-out;
z-index: 1;
padding-left: 160px;
display: flex;
flex-direction: column;
justify-content: center;
}
.player.play .player__timeline {
transform: translateY(-90%);
}
.player__timelineBar {
background: #E7E7E7;
width: 95%;
height: 4px;
border-radius: 15px;
margin-top: 13px;
position: relative;
}
.player #playhead {
position: absolute;
top: 0; left: 0;
border-radius: 15px;
width: 0;
height: 100%;
background: #fd6d94;
}
.player__author { line-height: 1; font-weight: bold; margin: 15px 0 6px 0; font-size: 14px; }
.player__song { line-height: 1; margin: 0; font-size: 12px; color: #949494; }
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js"></script>
<script>
// <![CDATA[
$(document).ready(function () {
var audioElement = document.createElement('audio');
function setAudioSrc() {
audioElement.setAttribute('src', $('.active-song').attr('data-src'));
}
setAudioSrc();
var tl = new TimelineMax({repeat: -1});
tl.to('.player__albumImg', 8, {
rotation: '360deg',
ease: Power0.easeNone
});
tl.pause();
$('.player__play').click(function () {
if ($('.player').hasClass('play')) {
$('.player').removeClass('play');
audioElement.pause();
TweenMax.to('.player__albumImg', 0.4, { scale: 1, ease: Back.easeOut.config(1.7) });
tl.pause();
} else {
$('.player').addClass('play');
audioElement.play();
TweenMax.to('.player__albumImg', 0.4, { scale: 1.1, ease: Back.easeOut.config(1.7) });
tl.resume();
}
});
audioElement.addEventListener("timeupdate", function () {
var duration = this.duration;
var currentTime = this.currentTime;
var percentage = (currentTime / duration) * 100;
$('#playhead').css('width', percentage + '%');
});
function updateInfo() {
$('.player__author').text($('.active-song').attr('data-author'));
$('.player__song').text($('.active-song').attr('data-song'));
}
updateInfo();
function changeSong(next) {
var active = $('.player__albumImg.active-song');
active.removeClass('active-song');
var target = next ? (active.is(':last-child') ? $('.player__albumImg:first-child') : active.next())
: (active.is(':first-child') ? $('.player__albumImg:last-child') : active.prev());
target.addClass('active-song');
updateInfo();
setAudioSrc();
if ($('.player').hasClass('play')) {
audioElement.play();
}
}
$('.player__next').click(function() { changeSong(true); });
$('.player__prev').click(function() { changeSong(false); });
});
// ]]>
</script>




コメントを投稿