ホームページ > ウェブフロントエンド > CSSチュートリアル > HTML、CSS、JavaScript を使用して最新のインタラクティブな抽選ホイールを構築する

HTML、CSS、JavaScript を使用して最新のインタラクティブな抽選ホイールを構築する

Linda Hamilton
リリース: 2024-11-24 07:55:11
オリジナル
482 人が閲覧しました

Building a Modern Interactive Raffle Wheel with HTML, CSS, and JavaScript

はじめに

今日のデジタル時代では、参加と興奮を促進するには、インタラクティブなツールを使ってコミュニティに参加することが不可欠です。プレゼントを主催する場合でも、投票を実施する場合でも、コンテストを企画する場合でも、視覚的に魅力的でインタラクティブな抽選ホイールを使用すると、ユーザー エクスペリエンスが大幅に向上します。この記事では、HTMLCSS、および で構築されたインタラクティブな抽選ホイールである Modern Raffle 2024 を作成するプロセスについて説明します。 JavaScript。構造のセットアップからアニメーションの追加、ソーシャル共有機能の統合まで、すべてをカバーします。

?使用されている技術

このプロジェクトを実現するために、次のテクノロジーを活用しました:

  • HTML5: Web ページの構造化とインタラクティブな要素の作成用。
  • CSS3: グラスモーフィズム、アニメーション、レスポンシブ レイアウトなどの最新のデザイン原則を使用してアプリケーションをスタイルします。
  • JavaScript: インタラクティブ性を追加し、ユーザー入力を処理し、抽選ホイールのロジックとアニメーションを管理します。
  • キャンバス API: 抽選ホイールの描画とアニメーション化用。
  • Font Awesome: ベクター アイコンを組み込んで洗練された外観を実現します。
  • Google Fonts: Inter フォントを使用して、クリーンでモダンなタイポグラフィを実現しました。
  • コーヒーを買ってください: プロジェクトをサポートするための寄付ボタンを統合しました。

⁉️ プロジェクトの構造

プロジェクトは 3 つの主要なファイルで構成されています:

  1. Index.html: アプリケーションの HTML 構造が含まれます。
  2. style.css: レイアウトとデザインのためのすべての CSS スタイルを保持します。
  3. script.js: インタラクティブ性とアニメーションを強化する JavaScript コードが含まれています。

さらに、私の Web サイト、LinkedIn、Twitter を宣伝するために フッター セクションが組み込まれており、サポートのための Buy Me a Coffee ボタンが含まれています。

? HTML (index.html)

HTML 構造は、参加者と賞品の入力セクション、抽選ホイール、勝者を発表するモーダル、プロモーション用のフッターなど、抽選アプリケーションの主要コンポーネントを設定します。

ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー


html





モダン ラッフル 2024








?モダン ラッフル 2024 ?

    <div class="input-section">
        <h2>Add Participants</h2>
        <div class="input-group">
            <input type="text">


<pre class="brush:php;toolbar:false">
? CSS (styles.css)
The CSS file is meticulously crafted to ensure a modern and premium look, incorporating glassmorphism, smooth animations, responsive design, and accessibility features. Below is the complete CSS with detailed explanations of enhancements and fixes.

ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

/* スタイルのリセットと基本スタイル */

  • { ボックスのサイズ設定: ボーダーボックス; マージン: 0; パディング: 0; フォントファミリー: 'Inter'、サンセリフ; }

ボディ{
背景: 線形グラデーション(135度, #1e3c72, #2a5298);
色: #ffffff;
表示: フレックス;
フレックス方向: 列; /* 子を垂直方向に積み重ねます /
justify-content: flex-start; /
上から開始 /
align-items: center;
最小高さ: 100vh;
/
フッターを表示できるようにオーバーフローの非表示を削除 */
オーバーフロー-x: 非表示;
}

/* コンテナ スタイル /
.container {
背景: rgba(255, 255, 255, 0.05);
背景フィルター:blur(10px);
パディング: 40px;
境界半径: 20px;
text-align: 中央;
幅: 90%;
最大幅: 900px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.37);
ボーダー: 1px ソリッド rgba(255, 255, 255, 0.18);
アニメーション: フェードイン 1 秒イーズインアウト;
フレックス: 1; /
コンテナーの成長を許可し、フッターを下に押し込みます */
表示: フレックス;
フレックス方向: 列;
align-items: center;
}

/* フェードイン アニメーション */
@keyframes fadeIn {
から { 不透明度: 0;変換:translateY(-20px); }
{ 不透明度: 1;変換:translateY(0); }
}

/* 見出しスタイル */
h1 {
margin-bottom: 30px;
フォントサイズ: 3rem;
フォントの太さ: 700;
text-shadow: 3px 3px 6px rgba(0,0,0,0.3);
}

/* 入力セクション */
.input-section {
margin-bottom: 40px;
幅: 100%;
}

.input-section h2 {
margin-bottom: 15px;
フォントサイズ: 1.75rem;
フォントの太さ: 600;
}

/* 入力グループ */
.input-group {
表示: フレックス;
justify-content: center;
align-items: center;
ギャップ: 10px;
margin-bottom: 15px;
}

.input-group input {
パディング: 12px 20px;
幅: 60%;
境界線: なし;
境界半径: 30px;
背景: rgba(255, 255, 255, 0.1);
色: #ffffff;
フォントサイズ: 1rem;
概要: なし;
トランジション: 背景 0.3 秒イーズ、ボックスシャドウ 0.3 秒イーズ;
}

.input-group input::placeholder {
色: #dddddd;
}

.input-group input:focus {
背景: rgba(255, 255, 255, 0.2);
box-shadow: 0 0 10px rgba(255, 127, 80, 0.5);
}

.input-group ボタン {
パディング: 12px 25px;
境界線: なし;
境界半径: 30px;
背景色: #ff7f50;
色: #fff;
フォントサイズ: 1rem;
フォントの太さ: 600;
カーソル: ポインタ;
表示: フレックス;
align-items: center;
ギャップ: 8px;
トランジション: 背景色 0.3 秒イーズ、変換 0.2 秒イーズ、ボックスシャドウ 0.3 秒イーズ;
}

.input-group button:hover {
背景色: #ff5722;
変換:translateY(-2px);
box-shadow: 0 4px 10px rgba(0,0,0,0.3);
}

/* ユーザーリスト */

ユーザーリスト {

ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

}

userList li {

    <div class="input-section">
        <h2>Add Participants</h2>
        <div class="input-group">
            <input type="text">


<pre class="brush:php;toolbar:false">
? CSS (styles.css)
The CSS file is meticulously crafted to ensure a modern and premium look, incorporating glassmorphism, smooth animations, responsive design, and accessibility features. Below is the complete CSS with detailed explanations of enhancements and fixes.

ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

}

/* 選ばれた賞品 */

選択された賞品 {

list-style: none;
max-height: 120px;
overflow-y: auto;
text-align: left;
padding: 0 20%;
width: 100%;
ログイン後にコピー
ログイン後にコピー

}

/* ホイールコンテナ */
.wheel-container {
位置: 相対;
margin-bottom: 40px;
幅: 100%;
表示: フレックス;
フレックス方向: 列;
align-items: center;
}

.wheel-wrapper {
位置: 相対;
幅: 100%;
最大幅: 500px;
マージン: 0 自動 20px;
}

/* キャンバス スタイル */
キャンバス {
幅: 100%;
高さ: 自動;
境界半径: 50%;
box-shadow: 0 0 20px rgba(0,0,0,0.5);
背景: #000;
遷移: 変換 4s cubic-bezier(0.33, 1, 0.68, 1);
}

/* ポインター スタイル */
.pointer {
位置: 絶対;
上: -20px;
左: 50%;
変換:translateX(-50%);
フォントサイズ: 2rem;
色: #ffeb3b;
アニメーション: 2 秒間無限にバウンス;
}

@keyframes バウンス {
0%、100% { 変換: 変換X(-50%) 変換Y(0); }
50% { 変換: 変換X(-50%) 変換Y(-10px); }
}

/* スピンボタン */

スピンボタン {

padding: 8px 0;
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
font-size: 1rem;
ログイン後にコピー
ログイン後にコピー

}

スピンボタン:ホバー {

font-size: 1.2rem;
font-weight: 500;
margin-top: 10px;
ログイン後にコピー
ログイン後にコピー

}

スピンボタン:アクティブ {

padding: 15px 35px;
border: none;
border-radius: 50px;
background-color: #32cd32;
color: #fff;
font-size: 1.25rem;
font-weight: 600;
cursor: pointer;
box-shadow: 0 6px 20px rgba(0,0,0,0.3);
transition: background-color 0.3s ease, transform 0.2s ease, box-shadow 0.3s ease;
display: flex;
align-items: center;
gap: 10px;
margin: 0 auto;
ログイン後にコピー
ログイン後にコピー

}

/* モーダル スタイル */
.modal {
表示: なし。
位置: 固定;
z インデックス: 100;
左: 0;
上: 0;
幅: 100%;
高さ: 100%;
オーバーフロー: 自動;
背景色: rgba(0,0,0,0.8);
アニメーション: fadeInModal 0.5 秒の容易さ;
}

@keyframes fadeInModal {
から { 不透明度: 0; }
{ 不透明度: 1; }
}

.modal-content {
背景色: rgba(30, 30, 30, 0.95);
マージン: 10% 自動;
パディング: 30px;
境界半径: 15px;
幅: 90%;
最大幅: 600px;
text-align: 中央;
box-shadow: 0 8px 25px rgba(0,0,0,0.5);
位置: 相対;
アニメーション: slideDown 0.5 秒の容易さ;
}

@keyframes slideDown {
{ 変換:translateY(-50px); から不透明度: 0; }
に { 変換:translateY(0);不透明度: 1; }
}

.close-button {
色: #bbb;
位置: 絶対;
上: 15px;
右: 20px;
フォントサイズ: 28px;
フォントの太さ: 太字;
カーソル: ポインタ;
トランジション: カラー 0.3 秒イーズ;
}

.close-button:hover,
.close-button:focus {
色: #fff;
}

.modal-content h2 {
margin-bottom: 20px;
フォントサイズ: 2rem;
フォントの太さ: 700;
}

.modal-content p {
フォントサイズ: 1.25rem;
margin-bottom: 25px;
}

シェアボタン {

background-color: #28a428;
transform: translateY(-3px);
box-shadow: 0 8px 25px rgba(0,0,0,0.4);
ログイン後にコピー
ログイン後にコピー

}

shareBtn:ホバー {

transform: translateY(0);
box-shadow: 0 4px 15px rgba(0,0,0,0.2);
ログイン後にコピー

}

/* フッタースタイル /
.footer {
背景: rgba(255, 255, 255, 0.05);
背景フィルター:blur(10px);
パディング: 20px 0;
border-top: 1px ソリッド rgba(255, 255, 255, 0.2);
幅: 100%;
/
フッターがコンテンツの下にあることを確認します */
フレックスシュリンク: 0;
}

.footer-container {
表示: フレックス;
フレックス方向: 列;
align-items: center;
justify-content: center;
最大幅: 900px;
マージン: 0 自動;
パディング: 0 20px;
}

.footer-links {
表示: フレックス;
ギャップ: 20px;
margin-bottom: 15px;
}

.footer-links a {
色: #ffffff;
フォントサイズ: 1rem;
テキスト装飾: なし;
表示: フレックス;
align-items: center;
ギャップ: 8px;
トランジション: カラー 0.3 秒の容易さ、変換 0.2 秒の容易さ;
}

.footer-links a:hover {
色: #ff7f50;
変換:translateY(-2px);
}

.footer-links a i {
フォントサイズ: 1.2rem;
}

.footer-donate {
margin-top: 10px;
}

/* フッターのレスポンシブ デザイン */
@media (最小幅: 600px) {
.footer-container {
フレックス方向: 行;
justify-content: space-between;
}

ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

}

/* ユーザーリストのスクロールバースタイル */

userList::-webkit-scrollbar {

    <div class="input-section">
        <h2>Add Participants</h2>
        <div class="input-group">
            <input type="text">


<pre class="brush:php;toolbar:false">
? CSS (styles.css)
The CSS file is meticulously crafted to ensure a modern and premium look, incorporating glassmorphism, smooth animations, responsive design, and accessibility features. Below is the complete CSS with detailed explanations of enhancements and fixes.

ログイン後にコピー

}

userList::-webkit-scrollbar-track {

list-style: none;
max-height: 120px;
overflow-y: auto;
text-align: left;
padding: 0 20%;
width: 100%;
ログイン後にコピー
ログイン後にコピー

}

userList::-webkit-scrollbar-thumb {

padding: 8px 0;
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
font-size: 1rem;
ログイン後にコピー
ログイン後にコピー

}

userList::-webkit-scrollbar-thumb:hover {

font-size: 1.2rem;
font-weight: 500;
margin-top: 10px;
ログイン後にコピー
ログイン後にコピー

}

/* アクセシビリティのためのボタンのフォーカス状態 */
.input-group ボタン:フォーカス、

スピンボタン:フォーカス、

shareBtn:フォーカス {

padding: 15px 35px;
border: none;
border-radius: 50px;
background-color: #32cd32;
color: #fff;
font-size: 1.25rem;
font-weight: 600;
cursor: pointer;
box-shadow: 0 6px 20px rgba(0,0,0,0.3);
transition: background-color 0.3s ease, transform 0.2s ease, box-shadow 0.3s ease;
display: flex;
align-items: center;
gap: 10px;
margin: 0 auto;
ログイン後にコピー
ログイン後にコピー

}

background-color: #28a428;
transform: translateY(-3px);
box-shadow: 0 8px 25px rgba(0,0,0,0.4);
ログイン後にコピー
ログイン後にコピー

// DOM 要素の選択
const addUserBtn = document.getElementById('addUserBtn');
const usernameInput = document.getElementById('username');
const userList = document.getElementById('userList');
const setPrizeBtn = document.getElementById('setPrizeBtn');
const awardInput = document.getElementById('賞');
const selectedPrize = document.getElementById('selectedPrize');
const pinBtn = document.getElementById('spinBtn');
const winnerModal = document.getElementById('winnerModal');
const closeBtn = document.querySelector('.close-button');
const winnerText = document.getElementById('winnerText');
const shareBtn = document.getElementById('shareBtn');

// 状態変数
let users = [];
let 賞品 = "なし";
let isSpinning = false;

// ホイール構成
const Canvas = document.getElementById('raffleWheel');
const ctx = Canvas.getContext('2d');
const WheelRadius = Canvas.width / 2;
const Colors = ['#FF5733', '#33FF57', '#3357FF', '#F333FF', '#FF33A8', '#33FFF6', '#FFC300', '#DAF7A6'];
startAngle = 0 にします;
円弧 = 0 にします;

// ホイールを初期化します
関数initializeWheel() {
if (users.length === 0) {
ctx.clearRect(0, 0, Canvas.width, Canvas.height);
戻る;
}
arc = (2 * Math.PI) / users.length;
drawWheel();
}

// ラッフルホイールを引く
関数drawWheel() {
ctx.clearRect(0, 0, Canvas.width, Canvas.height);
for (let i = 0; i const angle = startAngle i * arc;
ctx.fillStyle = Colors[i % Colors.length];
ctx.beginPath();
ctx.moveTo(wheelRadius, WheelRadius);
ctx.arc(wheelRadius, WheelRadius, WheelRadius, angle, angle arc, false);
ctx.closePath();
ctx.fill();

ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

}

// ポインタ矢印を描画します
functiondrawPointer() {
const pointerSize = 20;
ctx.fillStyle = '#FFEB3B';
ctx.beginPath();
ctx.moveTo(wheelRadius - pointerSize, 0);
ctx.lineTo(wheelRadius pointerSize, 0);
ctx.lineTo(wheelRadius, -pointerSize * 1.5);
ctx.closePath();
ctx.fill();
}

// ユーザーイベントを追加
addUserBtn.addEventListener('click', addUser);
usernameInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') addUser();
});

// ユーザーを追加する関数
function addUser() {
const ユーザー名 = ユーザー名Input.value.trim();
if (ユーザー名 === "") {
showAlert("有効なユーザー名を入力してください。");
戻る;
}
if (users.includes(ユーザー名)) {
showAlert("このユーザー名はすでに追加されています。");
戻る;
}
users.push(ユーザー名);
updateUserList();
ユーザー名入力.値 = '';
初期化ホイール();
}

// ユーザーリスト UI を更新します
function updateUserList() {
userList.innerHTML = '';
users.forEach(user => {
const li = document.createElement('li');
li.textContent = ユーザー;
userList.appendChild(li);
});
}

// 賞品イベントを設定
setPrizeBtn.addEventListener('click', setPrize);
priorityInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') setPrize();
});

// 賞品を設定する関数
function setPrize() {
const priorityInputValue = priorityInput.value.trim();
if (prizeInputValue === "") {
showAlert("有効な賞品を入力してください。");
戻る;
}
賞品 = 賞品入力値;
selectedPrize.textContent = 選択された賞品: ${prize};
賞品入力.値 = '';
}

// スピンボタンイベント
スピンBtn.addEventListener('クリック', スピンホイール);

// ホイールを回転させる関数
関数スピンホイール() {
if (isSpinning) return;
if (users.length === 0) {
showAlert("少なくとも 1 人のユーザーを追加してください。");
戻る;
}
if (賞品 === "なし") {
showAlert("賞品を設定してください。");
戻る;
}

ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

}

// ホイールを停止して勝者を発表する関数
関数 stopRotateWheel() {
const 度 = startAngle * 180 / Math.PI 90;
const arcd = arc * 180 / Math.PI;
const Index = Math.floor((360 - (度 % 360)) / arcd) % users.length;
const 勝者 = ユーザー[インデックス];
showWinner(勝者);
isSpinning = false;
pinBtn.disabled = false;
}

// スムーズなアニメーションのためのイージング関数
functioneaseOut(t, b, c, d) {
t /= d;
t--;
return c * (t * t * t 1) b;
}

// アラートを表示する関数
function showAlert(message) {
アラート(メッセージ);
}

// モーダルで勝者を表示する関数
関数 showWinner(勝者) {
winnerText.textContent = ${winner} が ${prize} を獲得しました! ?;
勝者Modal.style.display = "ブロック";
}

// モーダルイベントを閉じる
closeBtn.addEventListener('click', () => {
勝者Modal.style.display = "なし";
});
window.addEventListener('click', (イベント) => {
if (event.target ===勝者Modal) {
勝者Modal.style.display = "なし";
}
});

// Twitter でシェア
shareBtn.addEventListener('click', shareOnTwitter);

// 当選者をTwitterで共有する機能
関数 shareOnTwitter() {
const text = encodeURIComponent(? ${winnerText.textContent} さん、おめでとうございます! ${賞} を獲得しました! ? #Giveaway #Community);
const url = encodeURIComponent('https://gladiatorsbattle.com');
const twitterUrl = https://twitter.com/intent/tweet?text=${text}&url=${url};
window.open(twitterUrl, '_blank');
}

// ホイールの初期セットアップ
初期化ホイール();

    <div class="input-section">
        <h2>Add Participants</h2>
        <div class="input-group">
            <input type="text">


<pre class="brush:php;toolbar:false">
? CSS (styles.css)
The CSS file is meticulously crafted to ensure a modern and premium look, incorporating glassmorphism, smooth animations, responsive design, and accessibility features. Below is the complete CSS with detailed explanations of enhancements and fixes.

ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

以上がHTML、CSS、JavaScript を使用して最新のインタラクティブな抽選ホイールを構築するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート