액세스가 가능하고 반응형의 적응형 3D 게임 메뉴를 빌드하는 방법에 관한 기본 개요입니다.
이 게시물에서는 3D 게임 메뉴 구성 요소를 빌드하는 방법에 대한 생각을 공유하고자 합니다. 이 demo
<ph type="x-smartling-placeholder">동영상을 선호한다면 이 게시물의 YouTube 버전을 참고하세요.
개요
비디오 게임은 사용자에게 창의적이고 특이한 메뉴, 애니메이션, 3D 공간에서도 활용할 수 있습니다. 새로운 AR/VR 게임에서는 메뉴가 마치 우주에 떠다니죠. 오늘은 이 효과의 본질을 다시 만들 것이지만 적응형 색 구성표와 사용자를 위한 숙박 시설까지 더해졌기 때문에 움직임이 적은 것을 선호합니다.
HTML
게임 메뉴는 버튼 목록입니다. 이를 HTML로 표현하는 가장 좋은 방법은 다음과 같습니다.
<ul class="threeD-button-set">
<li><button>New Game</button></li>
<li><button>Continue</button></li>
<li><button>Online</button></li>
<li><button>Settings</button></li>
<li><button>Quit</button></li>
</ul>
버튼 목록은 스크린 리더 기술에 잘 알려져 있으며 는 JavaScript나 CSS 없이도 작동합니다.
CSS
버튼 목록의 스타일 지정은 다음과 같은 상위 단계로 분류됩니다.
- 맞춤 속성 설정
- Flexbox 레이아웃
- 장식용 유사 요소가 포함된 맞춤 버튼
- 요소를 3D 공간에 배치
맞춤 속성 개요
커스텀 속성은 의미 있는 속성을 지정하여 값을 명확하게 구분하는 데 도움이 됩니다. 임의의 값으로 바꾸는 것을 허용하므로, 반복되는 코드와 공유를 피할 수 있습니다. 가치를 얻을 수 있다는 것입니다.
다음은 CSS 변수로 저장된 미디어 쿼리(맞춤 설정이라고도 함)입니다. 미디어라고 합니다. 이들은 전역적이며 는 코드를 간결하고 읽기 쉽게 유지하기 위해 다양한 선택기에서 사용됩니다. 이 게임 메뉴 구성요소에서 모션 사용 환경설정, 시스템 색상 스키마, 및 색상 범위 기능을 디스플레이.
@custom-media --motionOK (prefers-reduced-motion: no-preference);
@custom-media --dark (prefers-color-scheme: dark);
@custom-media --HDcolor (dynamic-range: high);
다음 사용자 지정 속성은 색 구성표를 관리하고 마우스 버튼을 누른 상태에서 마우스 오버를 통해 게임 메뉴를 대화형으로 만들기 위한 위치 값 커스텀 이름 지정 속성은 값 또는 값의 결과에 대한 친숙한 이름입니다.
.threeD-button-set {
--y:;
--x:;
--distance: 1px;
--theme: hsl(180 100% 50%);
--theme-bg: hsl(180 100% 50% / 25%);
--theme-bg-hover: hsl(180 100% 50% / 40%);
--theme-text: white;
--theme-shadow: hsl(180 100% 10% / 25%);
--_max-rotateY: 10deg;
--_max-rotateX: 15deg;
--_btn-bg: var(--theme-bg);
--_btn-bg-hover: var(--theme-bg-hover);
--_btn-text: var(--theme-text);
--_btn-text-shadow: var(--theme-shadow);
--_bounce-ease: cubic-bezier(.5, 1.75, .75, 1.25);
@media (--dark) {
--theme: hsl(255 53% 50%);
--theme-bg: hsl(255 53% 71% / 25%);
--theme-bg-hover: hsl(255 53% 50% / 40%);
--theme-shadow: hsl(255 53% 10% / 25%);
}
@media (--HDcolor) {
@supports (color: color(display-p3 0 0 0)) {
--theme: color(display-p3 .4 0 .9);
}
}
}
밝은 테마 및 어두운 테마 배경 원뿔 배경
밝은 테마는 생동감 있는 cyan
~deeppink
원뿔 효과를 사용합니다.
그라데이션
어두운 테마에는 어둡고 은은한 원뿔 그라데이션이
적용됩니다. 무엇을 자세히 알아보려면
원뿔 그라데이션으로 적용할 수 있습니다. conic.style을 참고하세요.
html {
background: conic-gradient(at -10% 50%, deeppink, cyan);
@media (--dark) {
background: conic-gradient(at -10% 50%, #212529, 50%, #495057, #212529);
}
}
3D 관점 사용 설정
요소가 웹페이지의 3D 공간에 존재하려면
관점
초기화해야 합니다 body
요소에 원근을 넣기로 선택했습니다.
표시 영역 단위를 사용하여
원하는 스타일을 만들었습니다.
body {
perspective: 40vw;
}
이것은 관점이 미칠 수 있는 영향의 유형입니다.
<ul>
버튼 목록 스타일 지정
이 요소는 전체 버튼 목록 매크로 레이아웃뿐만 아니라 양방향 3D 플로팅 카드입니다. 이를 실현할 수 있는 방법을 소개합니다
버튼 그룹 레이아웃
Flexbox는 컨테이너 레이아웃을 관리할 수 있습니다. Flex의 기본 방향 변경
flex-direction
를 사용하여 행에서 열로 변환하고 각 항목의 크기가
align-items
의 콘텐츠를 stretch
에서 start
로 변경하여 콘텐츠를 변경할 수 있습니다.
.threeD-button-set {
/* remove <ul> margins */
margin: 0;
/* vertical rag-right layout */
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 2.5vh;
}
다음으로 컨테이너를 3D 공간 컨텍스트로 설정하고 CSS clamp()
를 설정합니다.
함수를 사용하여 카드가 읽을 수 있는 회전 지점 이상으로 회전하지 않도록 합니다. 알림
클램프의 중간값이 맞춤 속성이라는 것을 알 수 있습니다. 이러한 --x
및 --y
마우스 입력 시 JavaScript에서 설정
어떻게 해야 하는지에 대해
이야기해 보겠습니다
.threeD-button-set {
…
/* create 3D space context */
transform-style: preserve-3d;
/* clamped menu rotation to not be too extreme */
transform:
rotateY(
clamp(
calc(var(--_max-rotateY) * -1),
var(--y),
var(--_max-rotateY)
)
)
rotateX(
clamp(
calc(var(--_max-rotateX) * -1),
var(--x),
var(--_max-rotateX)
)
)
;
}
다음으로, 방문하는 사용자의 움직임이 괜찮으면 브라우저에 힌트를
이 항목의 변환은 이동하면서
will-change
또한 변환에 transition
를 설정하여 보간 유형을 사용 설정합니다. 이
마우스가 카드와 상호작용하면 애니메이션이 원활하게
적용할 수 있습니다. 애니메이션은 지속적으로 실행되는 애니메이션입니다.
3D 공간을 나타내는 3D 이미지를 반환합니다.
구성요소와 상호작용하지 않을 때 발생합니다.
@media (--motionOK) {
.threeD-button-set {
/* browser hint so it can be prepared and optimized */
will-change: transform;
/* transition transform style changes and run an infinite animation */
transition: transform .1s ease;
animation: rotate-y 5s ease-in-out infinite;
}
}
rotate-y
애니메이션은 50%
에 중간 키프레임만 설정합니다.
브라우저에서 0%
및 100%
를 요소의 기본 스타일로 기본 설정합니다. 이
은 번갈아 가며 같은 지점에서 시작하고 끝나야 하는 애니메이션의 약칭입니다.
있습니다. 이는 무한 번갈아 반복되는 애니메이션을 설명하는 좋은 방법입니다.
@keyframes rotate-y {
50% {
transform: rotateY(15deg) rotateX(-6deg);
}
}
<li>
요소 스타일 지정
각 목록 항목 (<li>
)에는 버튼과 테두리 요소가 포함되어 있습니다. 이
display
스타일이 변경되어 항목에
::marker
position
스타일
relative
로 설정되므로 다음 버튼 의사 요소가
버튼이 사용되는 전체 영역 내에서 자동 광고 소재를 실행합니다.
.threeD-button-set > li {
/* change display type from list-item */
display: inline-flex;
/* create context for button pseudos */
position: relative;
/* create 3D space context */
transform-style: preserve-3d;
}
<button>
요소 스타일 지정
상태 및 상호작용 유형이 많기 때문에 버튼의 스타일을 지정하는 것은 어려울 수 있습니다. 고려해야 합니다 이러한 버튼은 균형 잡혀있기 때문에 빠르게 복잡해집니다. 애니메이션 및 상호작용으로 구성됩니다.
초기 <button>
스타일
다음은 다른 상태를 지원하는 기본 스타일입니다.
.threeD-button-set button {
/* strip out default button styles */
appearance: none;
outline: none;
border: none;
/* bring in brand styles via props */
background-color: var(--_btn-bg);
color: var(--_btn-text);
text-shadow: 0 1px 1px var(--_btn-text-shadow);
/* large text rounded corner and padded*/
font-size: 5vmin;
font-family: Audiowide;
padding-block: .75ch;
padding-inline: 2ch;
border-radius: 5px 20px;
}
버튼 의사 요소
버튼의 테두리는 일반적인 테두리가 아니라 절대 위치입니다. pseudo-elements가 있습니다.
이러한 요소는 3D로 제작된 3D 원근법을 보여주는 데 있습니다. 이러한 유사 요소 중 하나가 버튼에서 다른 곳으로 밀려나고 하나는 사용자에게 더 가까이 당겨집니다 그 효과는 다음 항목에서 가장 두드러집니다. 상단 및 하단 버튼
.threeD-button button {
…
&::after,
&::before {
/* create empty element */
content: '';
opacity: .8;
/* cover the parent (button) */
position: absolute;
inset: 0;
/* style the element for border accents */
border: 1px solid var(--theme);
border-radius: 5px 20px;
}
/* exceptions for one of the pseudo elements */
/* this will be pushed back (3x) and have a thicker border */
&::before {
border-width: 3px;
/* in dark mode, it glows! */
@media (--dark) {
box-shadow:
0 0 25px var(--theme),
inset 0 0 25px var(--theme);
}
}
}
3D 변환 스타일
아래 transform-style
는 preserve-3d
로 설정되어 하위 요소가 간격을 둘 수 있습니다.
z
축에 자신을 위치시킵니다. transform
가 --distance
로 설정됩니다.
맞춤 속성(마우스를 올려 놓았을 때 증가됨)
포커스가 필요합니다.
.threeD-button-set button {
…
transform: translateZ(var(--distance));
transform-style: preserve-3d;
&::after {
/* pull forward in Z space with a 3x multiplier */
transform: translateZ(calc(var(--distance) / 3));
}
&::before {
/* push back in Z space with a 3x multiplier */
transform: translateZ(calc(var(--distance) / 3 * -1));
}
}
조건부 애니메이션 스타일
사용자가 모션에 괜찮은 경우 버튼은 브라우저에
변환 속성이 변경될 준비가 되어 있어야 하고 전환이
transform
및 background-color
속성. 인코더-디코더 아키텍처를
은은하게 흔들리는 효과가 있는 것 같았습니다.
.threeD-button-set button {
…
@media (--motionOK) {
will-change: transform;
transition:
transform .2s ease,
background-color .5s ease
;
&::before,
&::after {
transition: transform .1s ease-out;
}
&::after { transition-duration: .5s }
&::before { transition-duration: .3s }
}
}
마우스 오버 및 포커스 상호작용 스타일
상호작용 애니메이션의 목표는 이미지를 구성하는 레이어를 넓히는 것입니다.
평평하게 표시되는 버튼 이렇게 하려면 --distance
변수를 설정합니다.
처음에는 1px
로 변경합니다. 다음 코드 예에 표시된 선택 도구는
버튼이 표시된 기기가 버튼에 마우스를 가져가거나 포커스가 있는지 확인
활성화되고 있지 않습니다. 이 경우에는 CSS를 적용하여
있습니다.
- 마우스 오버 배경 색상을 적용합니다.
- 거리를 넓힙니다 .
- 바운스 이징 효과를 추가합니다.
- 의사 요소 전환을 시차를 두고 진행합니다.
.threeD-button-set button {
…
&:is(:hover, :focus-visible):not(:active) {
/* subtle distance plus bg color change on hover/focus */
--distance: 15px;
background-color: var(--_btn-bg-hover);
/* if motion is OK, setup transitions and increase distance */
@media (--motionOK) {
--distance: 3vmax;
transition-timing-function: var(--_bounce-ease);
transition-duration: .4s;
&::after { transition-duration: .5s }
&::before { transition-duration: .3s }
}
}
}
reduced
모션 환경설정의 3D 관점은 여전히 매우 깔끔했습니다.
상단 및 하단 요소는 효과를 섬세하게 보여줍니다.
JavaScript를 통한 일부 기능 개선
이 인터페이스는 키보드, 스크린 리더, 게임패드, 터치 및 키보드 등 간단한 자바스크립트 터치를 추가하여 두 가지 작업을 쉽게 할 수 있습니다. 시나리오에 관한 것입니다
지원 화살표 키
Tab 키는 메뉴를 탐색하는 데 좋은 방법이지만
게임패드에서 포커스를 이동합니다. 이
GUI에 자주 사용되는 oving-ux 라이브러리
챌린지 인터페이스는 화살표 키를 자동으로 처리합니다. 아래 코드는
.threeD-button-set
내에서 포커스를 트랩하고
버튼 하위 요소를 사용할 수 있습니다.
import {rovingIndex} from 'roving-ux'
rovingIndex({
element: document.querySelector('.threeD-button-set'),
target: 'button',
})
마우스 시차 상호작용
마우스를 추적한 후 메뉴를 기울이면 AR 및 VR을 모방합니다. 마우스 대신 가상 포인터가 있을 수 있는 비디오 게임 인터페이스입니다. 요소가 포인터를 하이퍼 인지하는 것은 재미있을 수 있습니다.
이것은 작은 추가 기능이므로
사용자의 모션 환경설정입니다. 또한 설정 과정에서 버튼 목록을 저장합니다.
querySelector
를 사용하여 구성요소를 메모리에 추가하고 요소의 경계를
menuRect
입니다. 이 경계를 사용하여 카드에 적용되는 회전 오프셋을 결정하세요.
기반으로 합니다.
const menu = document.querySelector('.threeD-button-set')
const menuRect = menu.getBoundingClientRect()
const { matches:motionOK } = window.matchMedia(
'(prefers-reduced-motion: no-preference)'
)
다음으로 마우스 x
및 y
위치를 허용하고 반환하는 함수가 필요합니다.
카드를 회전하는 데 사용할 수 있는 값입니다. 다음 함수는 마우스를 사용해
위치를 사용하여 상자의 어느 면이 들어 있고 얼마인지 구분할 수 있습니다. 이
delta가 반환됩니다.
const getAngles = (clientX, clientY) => {
const { x, y, width, height } = menuRect
const dx = clientX - (x + 0.5 * width)
const dy = clientY - (y + 0.5 * height)
return {dx,dy}
}
마지막으로 마우스가 움직이는 것을 확인하고 위치를 getAngles()
함수에 전달합니다.
델타 값을 맞춤 속성 스타일로 사용합니다. 덧셈을 하기 위해 20으로 나눈 값입니다.
델타를 낮추고 경사를 줄이게 하려면 더 좋은 방법이 있을 수 있습니다. 만약
--x
및 --y
속성을 처음부터
clamp()
함수를 사용하면 셀 간격이 넓을 때
카드를 읽을 수 없는 위치에 놓습니다.
if (motionOK) {
window.addEventListener('mousemove', ({target, clientX, clientY}) => {
const {dx,dy} = getAngles(clientX, clientY)
menu.attributeStyleMap.set('--x', `${dy / 20}deg`)
menu.attributeStyleMap.set('--y', `${dx / 20}deg`)
})
}
번역 및 경로
다른 쓰기 모드에서 게임 메뉴를 테스트할 때 한 가지 실수가 있었고 있습니다.
<button>
요소에 사용자의 writing-mode
에 대한 !important
스타일이 있음
에이전트 스타일 시트입니다. 이는 게임 메뉴 HTML을 변경해야 했습니다.
선택할 수 있습니다. 버튼 목록을 링크 목록으로 변경하면
메뉴 방향을 변경하기 위한 속성(<a>
요소에 브라우저가 없음)
제공된 !important
스타일
결론
이제 제가 어떻게 했는지 알게 되었으니 어떻게 해야 할까요?‽ ph 가속도계를 추가할 수 있나요? 휴대전화에서 타일로 메뉴를 회전시키면 개선할 수 있는가 어떻게 해야 할까요?
접근방식을 다각화하고 웹에서 빌드하는 방법을 모두 알아보겠습니다. 데모를 만들고 링크를 트윗하여 추가하면 됩니다. 아래 커뮤니티 리믹스 섹션을 공유해 주세요
커뮤니티 리믹스
표시할 내용이 아직 없습니다.