HTML, CSS 및 JavaScript를 사용하여 현대적인 대화형 추첨 휠 구축

Linda Hamilton
풀어 주다: 2024-11-24 07:55:11
원래의
429명이 탐색했습니다.

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

소개

오늘날의 디지털 시대에는 참여와 즐거움을 키우려면 대화형 도구를 사용하여 커뮤니티를 참여시키는 것이 필수적입니다. 경품 행사를 주최하든, 여론 조사를 실시하든, 경쟁을 조직하든 시각적으로 매력적이고 대화형인 추첨 휠을 사용하면 사용자 경험을 크게 향상시킬 수 있습니다. 이 기사에서는 HTML, CSS으로 구축된 대화형 추첨 휠인 Modern Raffle 2024를 만드는 과정을 안내해 드리겠습니다. 자바스크립트. 구조 설정부터 애니메이션 추가, 소셜 공유 기능 통합까지 모든 것을 다룹니다.

? 사용된 기술

이 프로젝트를 구현하기 위해 다음 기술을 활용했습니다.

  • HTML5: 웹페이지를 구성하고 대화형 요소를 만드는 데 사용됩니다.
  • CSS3: 유리 형태, 애니메이션, 반응형 레이아웃을 포함한 현대적인 디자인 원칙으로 애플리케이션 스타일을 지정합니다.
  • JavaScript: 대화형 기능을 추가하고, 사용자 입력을 처리하고, 추첨 휠의 로직과 애니메이션을 관리합니다.
  • 캔버스 API: 추첨 휠을 그리고 애니메이션을 적용하는 데 사용됩니다.
  • Font Awesome: 세련된 모양을 위해 벡터 아이콘을 통합합니다.
  • 구글 폰트 : 깔끔하고 모던한 타이포그래피를 위해 인터 폰트를 활용했습니다.
  • Buy Me a Coffee: 프로젝트 후원을 위해 기부 버튼을 통합했습니다.

?️ 프로젝트 구조

이 프로젝트는 세 가지 주요 파일로 구성됩니다.

  1. index.html: 애플리케이션의 HTML 구조를 포함합니다.
  2. styles.css: 레이아웃과 디자인을 위한 모든 CSS 스타일을 보유합니다.
  3. script.js: 상호작용과 애니메이션을 강화하는 JavaScript 코드가 포함되어 있습니다.

또한 내 웹사이트, LinkedIn, Twitter를 홍보하기 위해 바닥글 섹션이 통합되었으며 지원을 위한 커피 구입 버튼도 포함되어 있습니다.

? 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; 글꼴 계열: '인터', 산세리프; }

몸 {
배경: 선형 그라데이션(135deg, #1e3c72, #2a5298);
색상: #ffffff;
디스플레이: 플렉스;
플렉스 방향: 열; /* 자식을 세로로 쌓기 /
내용 정당화: flex-start; /
맨 위에서 시작 /
항목 정렬: 중앙;
최소 높이: 100vh;
/
바닥글 표시를 허용하기 위해 숨겨진 오버플로 제거 */
오버플로-x: 숨김;
}

/* 컨테이너 스타일 /
.컨테이너 {
배경: rgba(255, 255, 255, 0.05);
배경 필터: 흐림(10px);
패딩: 40px;
테두리 반경: 20px;
텍스트 정렬: 중앙;
너비: 90%;
최대 너비: 900px;
상자 그림자: 0 8px 32px rgba(0, 0, 0, 0.37);
테두리: 1px 단색 rgba(255, 255, 255, 0.18);
애니메이션: fadeIn 1s easy-in-out;
플렉스: 1; /
컨테이너가 커지도록 허용하고 바닥글을 아래로 밀어냅니다. */
디스플레이: 플렉스;
플렉스 방향: 열;
항목 정렬: 중앙;
}

/* 페이드인 애니메이션 */
@keyframes fadeIn {
{불투명도: 0; 변환: 번역Y(-20px); }
{불투명도: 1; 변환: 번역Y(0); }
}

/* 제목 스타일 */
h1 {
여백-하단: 30px;
글꼴 크기: 3rem;
글꼴 두께: 700;
텍스트 그림자: 3px 3px 6px rgba(0,0,0,0.3);
}

/* 입력 섹션 */
.입력 섹션 {
여백 하단: 40px;
너비: 100%;
}

.input-section h2 {
여백 하단: 15px;
글꼴 크기: 1.75rem;
글꼴 두께: 600;
}

/* 입력 그룹 */
.input-group {
디스플레이: 플렉스;
정당화-내용: 센터;
항목 정렬: 중앙;
간격: 10px;
여백 하단: 15px;
}

.input-group 입력 {
패딩: 12px 20px;
너비: 60%;
테두리: 없음;
테두리 반경: 30px;
배경: rgba(255, 255, 255, 0.1);
색상: #ffffff;
글꼴 크기: 1rem;
개요: 없음;
전환: 배경 0.3초 용이함, 상자 그림자 0.3초 용이함;
}

.input-group input::placeholder {
색상: #dddddd;
}

.input-group 입력:초점 {
배경: rgba(255, 255, 255, 0.2);
상자 그림자: 0 0 10px rgba(255, 127, 80, 0.5);
}

.input-group 버튼 {
패딩: 12px 25px;
테두리: 없음;
테두리 반경: 30px;
배경색: #ff7f50;
색상: #fff;
글꼴 크기: 1rem;
글꼴 두께: 600;
커서: 포인터;
디스플레이: 플렉스;
항목 정렬: 중앙;
간격: 8px;
전환: 배경색 0.3초 용이성, 변환 0.2초 용이성, 상자 그림자 0.3초 용이성;
}

.input-group 버튼:hover {
배경색: #ff5722;
변환: 번역Y(-2px);
상자 그림자: 0 4px 10px rgba(0,0,0,0.3);
}

/* 사용자 목록 */

사용자 목록 {

로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

}

userList 리 {

    <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.

로그인 후 복사
로그인 후 복사
로그인 후 복사

}

/* 선정상 */

selectedPrize {

list-style: none;
max-height: 120px;
overflow-y: auto;
text-align: left;
padding: 0 20%;
width: 100%;
로그인 후 복사
로그인 후 복사

}

/* 휠 컨테이너 */
.wheel-컨테이너 {
위치: 상대;
여백 하단: 40px;
너비: 100%;
디스플레이: 플렉스;
플렉스 방향: 열;
항목 정렬: 중앙;
}

.wheel-wrapper {
위치: 상대;
너비: 100%;
최대 너비: 500px;
여백: 0 자동 20px;
}

/* 캔버스 스타일 */
캔버스 {
너비: 100%;
높이: 자동;
테두리 반경: 50%;
상자 그림자: 0 0 20px rgba(0,0,0,0.5);
배경: #000;
전환: 4s 3차 베지어(0.33, 1, 0.68, 1) 변환;
}

/* 포인터 스타일 */
.포인터 {
위치: 절대;
상단: -20px;
왼쪽: 50%;
변환: 번역X(-50%);
글꼴 크기: 2rem;
색상: #ffeb3b;
애니메이션: 2초 무한 바운스;
}

@keyframes 바운스 {
0%, 100% { 변환: 번역X(-50%) 번역Y(0); }
50% { 변환: 번역X(-50%) 번역Y(-10px); }
}

/* 회전 버튼 */

스핀Btn {

padding: 8px 0;
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
font-size: 1rem;
로그인 후 복사
로그인 후 복사

}

spinBtn:hover {

font-size: 1.2rem;
font-weight: 500;
margin-top: 10px;
로그인 후 복사
로그인 후 복사

}

spinBtn:활성 {

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;
로그인 후 복사
로그인 후 복사

}

/* 모달 스타일 */
.모달 {
디스플레이: 없음;
위치: 고정;
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;
텍스트 정렬: 중앙;
상자 그림자: 0 8px 25px rgba(0,0,0,0.5);
위치: 상대;
애니메이션: SlideDown 0.5초 용이성;
}

@keyframes 슬라이드다운 {
{ 변환: 번역Y(-50px); 불투명도: 0; }
{ 변환: 번역Y(0); 불투명도: 1; }
}

.닫기 버튼 {
색상: #bbb;
위치: 절대;
상단: 15px;
오른쪽: 20px;
글꼴 크기: 28px;
글꼴 두께: 굵게;
커서: 포인터;
전환: 색상 0.3초 용이성
}

.닫기 버튼:hover,
.close-버튼:초점 {
색상: #fff;
}

.modal-content h2 {
여백-하단: 20px;
글꼴 크기: 2rem;
글꼴 두께: 700;
}

.modal-content p {
글꼴 크기: 1.25rem;
여백 하단: 25px;
}

공유Btn {

background-color: #28a428;
transform: translateY(-3px);
box-shadow: 0 8px 25px rgba(0,0,0,0.4);
로그인 후 복사
로그인 후 복사

}

shareBtn:hover {

transform: translateY(0);
box-shadow: 0 4px 15px rgba(0,0,0,0.2);
로그인 후 복사

}

/* 바닥글 스타일 /
.바닥글 {
배경: rgba(255, 255, 255, 0.05);
배경 필터: 흐림(10px);
패딩: 20px 0;
border-top: 1px 솔리드 rgba(255, 255, 255, 0.2);
너비: 100%;
/
바닥글이 콘텐츠 아래에 있는지 확인 */
flex-shrink: 0;
}

.footer-container {
디스플레이: 플렉스;
플렉스 방향: 열;
항목 정렬: 중앙;
정당화-내용: 센터;
최대 너비: 900px;
여백: 0 자동;
패딩: 0 20px;
}

.footer-links {
디스플레이: 플렉스;
간격: 20px;
여백 하단: 15px;
}

.footer-links a {
색상: #ffffff;
글꼴 크기: 1rem;
텍스트 장식: 없음;
디스플레이: 플렉스;
항목 정렬: 중앙;
간격: 8px;
전환: 색상 0.3초 용이성, 변환 0.2초 용이성;
}

.footer-links a:hover {
색상: #ff7f50;
변환: 번역Y(-2px);
}

.footer-links a i {
글꼴 크기: 1.2rem;
}

.footer-기부 {
여백 상단: 10px;
}

/* 바닥글 반응형 디자인 */
@media (최소 너비: 600px) {
.footer-컨테이너 {
플렉스 방향: 행;
내용 정당화: 공백 사이;
}

로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

}

/* 사용자 목록의 스크롤바 스타일 */

userList::-webkit-스크롤바 {

    <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 버튼:포커스,

spinBtn:포커스,

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('사용자 이름');
const userList = document.getElementById('userList');
const setPrizeBtn = document.getElementById('setPrizeBtn');
const PrizeInput = document.getElementById('prize');
const selectedPrize = document.getElementById('selectedPrize');
const spinBtn = 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 isSpinning = false;

//휠 구성
const 캔버스 = document.getElementById('raffleWheel');
const ctx = canvas.getContext('2d');
const WheelRadius = canvas.width / 2;
const 색상 = ['#FF5733', '#33FF57', '#3357FF', '#F333FF', '#FF33A8', '#33FFF6', '#FFC300', '#DAF7A6'];
startAngle = 0;
let arc = 0;

// 휠 초기화
함수 초기화Wheel() {
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 < users.length; i ) {
const angle = startAngle i * arc;
ctx.fillStyle = 색상[i % colors.length];
ctx.beginPath();
ctx.moveTo(wheelRadius, WheelRadius);
ctx.arc(wheelRadius,wheelRadius,wheelRadius, angle, angle arc, false);
ctx.closePath();
ctx.fill();

로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

}

// 포인터 화살표 그리기
함수 drawPointer() {
const 포인터 크기 = 20;
ctx.fillStyle = '#FFEB3B';
ctx.beginPath();
ctx.moveTo(wheelRadius - 포인터 크기, 0);
ctx.lineTo(wheelRadius 포인터 크기, 0);
ctx.lineTo(wheelRadius, -pointerSize * 1.5);
ctx.closePath();
ctx.fill();
}

// 사용자 이벤트 추가
addUserBtn.addEventListener('click', addUser);
usernameInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') addUser();
});

// 사용자 추가 기능
함수 addUser() {
const 사용자 이름 = 사용자 이름Input.value.trim();
if (사용자 이름 === "") {
showAlert("올바른 사용자 이름을 입력하세요.");
반품;
}
if (users.includes(사용자 이름)) {
showAlert("이 사용자 이름은 이미 추가되었습니다.");
반품;
}
users.push(사용자 이름);
updateUserList();
usernameInput.value = '';
초기화휠();
}

// 사용자 목록 UI 업데이트
함수 updateUserList() {
userList.innerHTML = '';
users.forEach(사용자 => {
const li = document.createElement('li');
li.textContent = 사용자;
userList.appendChild(li);
});
}

//세트 경품 이벤트
setPrizeBtn.addEventListener('click', setPrize);
PrizeInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') setPrize();
});

// 상품 설정 기능
함수 setPrize() {
const PrizeInputValue = PrizeInput.value.trim();
if (prizeInputValue === "") {
showAlert("유효한 상품을 입력하세요.");
반품;
}
상 = PrizeInputValue;
selectedPrize.textContent = 선정된 상품: ${prize};
PrizeInput.value = '';
}

//스핀버튼 이벤트
spinBtn.addEventListener('click', spinWheel);

// 룰렛 돌리기 기능
함수 spinWheel() {
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 인덱스 = Math.floor((360 - (도 % 360)) / arcd) % users.length;
const 승자 = 사용자[색인];
showWinner(승자);
isSpinning = false;
spinBtn.disabled = false;
}

//부드러운 애니메이션을 위한 이징 기능
기능 easyOut(t, b, c, d) {
t /= d;
t--;
return c * (t * t * t 1) b;
}

//알림 표시 기능
함수 showAlert(메시지) {
경고(메시지);
}

// 승자를 모달로 표시하는 기능
함수 showWinner(승자) {
WinnerText.textContent = ${winner}님이 ${prize}을(를) 획득했습니다! ?;
WinnerModal.style.display = "차단";
}

// 모달 이벤트 닫기
closeBtn.addEventListener('click', () => {
WinnerModal.style.display = "없음";
});
window.addEventListener('click', (이벤트) => {
if (event.target === WinnerModal) {
WinnerModal.style.display = "없음";
}
});

// 트위터에 공유
shareBtn.addEventListener('click', shareOnTwitter);

// 당첨자를 트위터에 공유하는 기능
함수 shareOnTwitter() {
const text = encodeURIComponent(? ${winnerText.textContent} 님 축하드립니다! ${prize} 를 획득하셨습니다! ? #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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:dev.to
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿