한동안 저는 CSS로 이런 3D 씬을 만들어 놀았습니다 — 보통 제 생방송에서 만들죠.
3D CSS 반응형 스턴트 비행기! 🛩️
루프와 롤을 도는 것이 가능합니다! 😎
마우스 움직임에 반응합니다 🐭
👉 https://t.co/A1zNmfEzzi via @CodePen pic.twitter.com/87D7LIXLr2
— Jhey 🐻🛠 (Exploring Opportunities ✨) (@jh3yy) March 27, 2021
각 데모는 CSS로 다른 일을 시도하거나 일을 수행하는 방법을 연구할 수 있는 기회입니다. 저는 종종 스트림에서 무엇을 시도해 볼지 제안을 받습니다. 최근 제안 중 하나는 “3D”로 인쇄하는 프린터였습니다. 그리고 제가 만든 것이 바로 이것입니다!
📢 CSS 프린트 샵이 무료로 개점합니다! 😅
무료 인쇄! 😮
이미지 URL을 입력하면 3D CSS 프린터가 이를 인쇄해 드립니다 😁
👉 https://t.co/UWTDAyUadn via @CodePen pic.twitter.com/z3q9dJavYv
— Jhey 🐻🛠 (Exploring Opportunities ✨) (@jh3yy) April 22, 2021
CSS로 3D 아이템 만들기
I’ve written about making things 3D with CSS before. The general gist is that most scenes are a composition of cuboids.
직육면체를 만들기 위해 CSS 변환을 사용하여 직육면체의 면을 배치할 수 있습니다. 이 마법같은 속성은 transform-style
입니다. 이 속성을 preserve-3d
로 설정하면 요소를 세 번째 차원에서 변환할 수 있습니다.
* {
transform-style: preserve-3d;
}
이러한 장면을 몇 개 만들어 보면 작업 속도를 높이는 방법을 배우기 시작합니다. 저는 HTML 프리프로세서로 Pug를 사용하는 것을 좋아합니다. mixin 기능을 사용하면 직육면체를 더 빠르게 생성할 수 있습니다. 이 기사의 마크업 예시는 Pug를 사용합니다. 하지만 각 CodePen 데모에서는 “View Compiled HTML” 옵션을 사용하여 HTML 출력을 볼 수 있습니다:
mixin cuboid()
.cuboid(class!=attributes.class)
- let s = 0
while s < 6
.cuboid__side
- s++
이렇게 사용하면 +cuboid()(class="printer__top")
이렇게 생성됩니다:
<div class="cuboid printer__top">
<div class="cuboid__side"></div>
<div class="cuboid__side"></div>
<div class="cuboid__side"></div>
<div class="cuboid__side"></div>
<div class="cuboid__side"></div>
<div class="cuboid__side"></div>
</div>
그리고 저는 직육면체를 배치하기 위해 사용하는 일정한 블록의 CSS가 있습니다. 여기서 즐거움은 CSS 사용자 정의 속성을 활용하여 직육면체의 속성을 정의할 수 있다는 것입니다(위의 동영상에서 보여준 것과 같이):
.cuboid {
// Defaults
--width: 15;
--height: 10;
--depth: 4;
height: calc(var(--depth) * 1vmin);
width: calc(var(--width) * 1vmin);
transform-style: preserve-3d;
position: absolute;
font-size: 1rem;
transform: translate3d(0, 0, 5vmin);
}
.cuboid > div:nth-of-type(1) {
height: calc(var(--height) * 1vmin);
width: 100%;
transform-origin: 50% 50%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) rotateX(-90deg) translate3d(0, 0, calc((var(--depth) / 2) * 1vmin));
}
.cuboid > div:nth-of-type(2) {
height: calc(var(--height) * 1vmin);
width: 100%;
transform-origin: 50% 50%;
transform: translate(-50%, -50%) rotateX(-90deg) rotateY(180deg) translate3d(0, 0, calc((var(--depth) / 2) * 1vmin));
position: absolute;
top: 50%;
left: 50%;
}
.cuboid > div:nth-of-type(3) {
height: calc(var(--height) * 1vmin);
width: calc(var(--depth) * 1vmin);
transform: translate(-50%, -50%) rotateX(-90deg) rotateY(90deg) translate3d(0, 0, calc((var(--width) / 2) * 1vmin));
position: absolute;
top: 50%;
left: 50%;
}
.cuboid > div:nth-of-type(4) {
height: calc(var(--height) * 1vmin);
width: calc(var(--depth) * 1vmin);
transform: translate(-50%, -50%) rotateX(-90deg) rotateY(-90deg) translate3d(0, 0, calc((var(--width) / 2) * 1vmin));
position: absolute;
top: 50%;
left: 50%;
}
.cuboid > div:nth-of-type(5) {
height: calc(var(--depth) * 1vmin);
width: calc(var(--width) * 1vmin);
transform: translate(-50%, -50%) translate3d(0, 0, calc((var(--height) / 2) * 1vmin));
position: absolute;
top: 50%;
left: 50%;
}
.cuboid > div:nth-of-type(6) {
height: calc(var(--depth) * 1vmin);
width: calc(var(--width) * 1vmin);
transform: translate(-50%, -50%) translate3d(0, 0, calc((var(--height) / 2) * -1vmin)) rotateX(180deg);
position: absolute;
top: 50%;
left: 50%;
}
사용자 정의 속성을 사용하면 직육면체의 다양한 특성을 제어할 수 있습니다.
--width
: 평면상의 직육면체 너비--height
: 평면상의 직육면체 높이--depth
: 평면상의 직육면체 깊이--x
: 평면상의 X 위치--y
: 평면상의 Y 위치
직육면체를 장면에 넣고 회전시키기 전까지는 별 볼 일 없습니다. 다시 말하지만, 저는 무언가를 만들 때 장면을 조작하기 위해 사용자 정의 속성을 사용합니다. Dat.GUI 여기서 매우 유용하게 사용됩니다.
데모를 검사하면 컨트롤 패널을 사용하여 장면에 대한 CSS 사용자 정의 속성을 업데이트합니다. CSS 사용자 정의 속성의 범위는 중복 코드를 많이 절약하고 DRY하게 유지합니다.
여러 가지 방법
CSS에서 많은 것들과 마찬가지로, 그것을 수행하는 방법이 하나 이상 있습니다. 종종 큐비죤드(cuboids)로 장면을 구성하고 필요에 따라 물체를 배치할 수 있습니다. 하지만 관리하기가 까다로울 수 있습니다. 물건을 그룹화하거나 어떤 종류의 컨테이너를 추가할 필요가 있는 경우가 종종 있습니다.
의자가 이동할 수 있는 자체 서브 장면인 이 예시를 고려해보세요.
최근의 많은 예시들은 그렇게 복잡하지 않습니다. 저는 압출(extrusion)을 사용하고 있습니다. 이는 제가 만들고 있는 것을 2D 요소로 매핑할 수 있음을 의미합니다. 예를 들어, 제가 최근에 만든 헬리콥터입니다.
.helicopter
.helicopter__rotor
.helicopter__cockpit
.helicopter__base-light
.helicopter__chair
.helicopter__chair-back
.helicopter__chair-bottom
.helicopter__dashboard
.helicopter__tail
.helicopter__fin
.helicopter__triblade
.helicopter__tail-light
.helicopter__stabilizer
.helicopter__skids
.helicopter__skid--left.helicopter__skid
.helicopter__skid--right.helicopter__skid
.helicopter__wing
.helicopter__wing-light.helicopter__wing-light--left
.helicopter__wing-light.helicopter__wing-light--right
.helicopter__launchers
.helicopter__launcher.helicopter__launcher--left
.helicopter__launcher.helicopter__launcher--right
.helicopter__blades
그런 다음 믹신(mixin)을 사용하여 모든 컨테이너에 큐비주이드(cuboids)를 넣을 수 있습니다. 그리고 각 큐비주이드에 필요한 “두께”를 적용합니다. 두께는 범위 지정된 사용자 정의 속성에 의해 결정됩니다. 이 데모는 헬리콥터를 구성하는 큐비주이드에 대한 --thickness
속성을 전환합니다. 이는 처음 시작한 2D 매핑이 어떻게 보였는지 아이디어를 제공합니다.
이것이 CSS로 3D 물체를 만드는 기본적인 방법입니다. 코드를 파고들면 확실히 몇 가지 트릭을 발견할 것입니다. 그러나 일반적으로 장면을 스캐폴딩하고, 큐비주이드로 채우고, 큐비주이드를 색칠합니다. 종종 큐비주이드의 면을 구분하기 위해 색상의 다른 음영이 필요합니다. 추가적인 세부 사항은 큐비주이드 측면에 추가할 수 있는 것이거나 큐비주이드에 적용할 수 있는 변환일 수 있습니다. 예를 들어, Z축을 따라 회전하고 이동합니다.
간소화된 예시를 생각해보겠습니다.
.scene
.extrusion
+cuboid()(class="extrusion__cuboid")
압출을 사용하여 큐비주이드를 생성하는 새로운 CSS는 다음과 같을 수 있습니다. 각 면의 색상에 대한 범위 지정된 사용자 정의 속성을 포함하는 방식을 주목하세요. 여기서 :root
아래에 몇 가지 기본값이나 폴백 값을 넣는 것이 좋을 것입니다.
.cuboid {
width: 100%;
height: 100%;
position: relative;
}
.cuboid__side:nth-of-type(1) {
background: var(--shade-one);
height: calc(var(--thickness) * 1vmin);
width: 100%;
position: absolute;
top: 0;
transform: translate(0, -50%) rotateX(90deg);
}
.cuboid__side:nth-of-type(2) {
background: var(--shade-two);
height: 100%;
width: calc(var(--thickness) * 1vmin);
position: absolute;
top: 50%;
right: 0;
transform: translate(50%, -50%) rotateY(90deg);
}
.cuboid__side:nth-of-type(3) {
background: var(--shade-three);
width: 100%;
height: calc(var(--thickness) * 1vmin);
position: absolute;
bottom: 0;
transform: translate(0%, 50%) rotateX(90deg);
}
.cuboid__side:nth-of-type(4) {
background: var(--shade-two);
height: 100%;
width: calc(var(--thickness) * 1vmin);
position: absolute;
left: 0;
top: 50%;
transform: translate(-50%, -50%) rotateY(90deg);
}
.cuboid__side:nth-of-type(5) {
background: var(--shade-three);
height: 100%;
width: 100%;
transform: translate3d(0, 0, calc(var(--thickness) * 0.5vmin));
position: absolute;
top: 0;
left: 0;
}
.cuboid__side:nth-of-type(6) {
background: var(--shade-one);
height: 100%;
width: 100%;
transform: translate3d(0, 0, calc(var(--thickness) * -0.5vmin)) rotateY(180deg);
position: absolute;
top: 0;
left: 0;
}
이 예제에서는 세 가지 톤을 사용했습니다. 하지만 종종 더 많이 필요할 수 있습니다. 이 데모는 그것을 결합하지만 범위 지정된 사용자 정의 속성을 변경할 수 있게 합니다. “thickness” 값은 cuboid의 이 extrusion을 변경합니다. 변환과 크기는 “extrusion” 클래스를 가진 포함 요소에 영향을 미칩니다.
프린터를 기초 작업하는
시작하기 전에 필요한 모든 조각을 기초 작업할 수 있습니다. 연습을 하면 이것이 더 명확해집니다. 하지만 일반 규칙은 모든 것을 상자로 시각화하려는 것입니다. 그것이 어떻게 쪼개질지에 대해 좋은 아이디어를 제공합니다:
.scene
.printer
.printer__side.printer__side--left
.printer__side.printer__side--right
.printer__tray.printer__tray--bottom
.printer__tray.printer__tray--top
.printer__top
.printer__back
여기서 우리가 목표로 하는 것을 시각화할 수 있는지 확인해보세요. 두 측면 조각은 중간에 간격을 남깁니다. 그런 다음 상단에 놓이는 cuboid와 뒤쪽을 채우는 cuboid가 있습니다. 그런 다음은 페이퍼 트레이를 만드는 두 개의 cuboids입니다.
이 단계에 도달하면, cuboids를 채우는 것이 그려집니다:
.scene
.printer
.printer__side.printer__side--left
+cuboid()(class="cuboid--side")
.printer__side.printer__side--right
+cuboid()(class="cuboid--side")
.printer__tray.printer__tray--bottom
+cuboid()(class="cuboid--tray")
.printer__tray.printer__tray--top
+cuboid()(class="cuboid--tray")
.printer__top
+cuboid()(class="cuboid--top")
.printer__back
+cuboid()(class="cuboid--back")
우리가 cuboid--side
와 같은 클래스 이름을 재사용할 수 있는 방법을 확인해보세요. 이 cuboids는 같은 두께와 같은 색상을 사용할 가능성이 높습니다. 그들의 위치와 크기는 포함 요소에 의해 결정됩니다.
이를 조립하면 이런 것을 얻을 수 있습니다.
데모를 터트리면 프린터를 구성하는 다른 cuboids를 볼 수 있습니다. extrusion을 끄면 평坦한 포함 요소를 볼 수 있습니다.
일부 세부 사항 추가
이제 여러분은 각 측면에 색상을 추가하는 것만으로는 얻을 수 없는 더 많은 세부 사항이 있다는 것을 발견할 수 있습니다. 이것은 추가 세부 사항을 추가하는 방법을 찾는 것에 내려압니다. 우리는 추가하고 싶은 것에 따라 다른 옵션을 가지고 있습니다.
이미지나 기본적인 색상 변경이 필요한 경우, background-image
를 사용하여 그라데이션 등을 층층이 쌓을 수 있습니다.
예를 들어, 프린터의 상단에는 디테일이 있고, 프린터의 출력구가 있습니다. 이 코드는 윗쪽 큐브 오브 오브 탑의 상단을 다룹니다. 그라데이션은 프린터의 출력구와 디테일을 처리합니다:
.cuboid--top {
--thickness: var(--depth);
--shade-one: linear-gradient(#292929, #292929) 100% 50%/14% 54% no-repeat, linear-gradient(var(--p-7), var(--p-7)) 40% 50%/12% 32% no-repeat, linear-gradient(var(--p-7), var(--p-7)) 30% 50%/2% 12% no-repeat, linear-gradient(var(--p-3), var(--p-3)) 0% 50%/66% 50% no-repeat, var(--p-1);
}
곰 로고의 경우, background-image
를 사용하거나 의사 요소를 사용하여 위치를 지정할 수 있습니다:
.cuboid--top > div:nth-of-type(1):after {
content: '';
position: absolute;
top: 7%;
left: 10%;
height: calc(var(--depth) * 0.12vmin);
width: calc(var(--depth) * 0.12vmin);
background: url("https://assets.codepen.io/605876/avatar.png");
background-size: cover;
transform: rotate(90deg);
filter: grayscale(0.5);
}
더 포괄적인 디테일을 추가해야 한다면, 큐브 믹신을 사용하지 않는 것이 좋습니다. 예를 들어, 프린터의 상단에는 img
요소를 사용하여 미리보기 화면이 있습니다:
.printer__top
.cuboid.cuboid--top
.cuboid__side
.cuboid__side
.cuboid__side
.cuboid__side
.screen
.screen__preview
img.screen__preview-img
.cuboid__side
.cuboid__side
좀 더 디테일을 추가하고 종이를 넣기에 준비가 되었습니다!
종이의 여정
종이가 없는 프린터가 뭐가 있겠습니까? 종이를 프린터로 날려 보내고 반대쪽으로 발사하는 애니메이션을 원합니다. 이와 비슷한 데모: 어디서나 클릭하여 종이 한 장을 프린터에 공급하고 인쇄합니다.
큐브로 종이 덩어리를 추가한 다음, 단일 종이로 작동하는 별도의 요소를 사용할 수 있습니다:
.paper-stack.paper-stack--bottom
+cuboid()(class="cuboid--paper")
.paper-stack.paper-stack--top
.cuboid.cuboid--paper
.cuboid__side
.paper
.paper__flyer
.cuboid__side
.cuboid__side
.cuboid__side
.cuboid__side
.cuboid__side
그러나 종이를 프린터로 날려 보내는 애니메이션은 시행착오가 필요합니다. DevTools 검사기에서 다양한 변환을 사용해 보는 것이 좋습니다. 이는 물건이 어떻게 보일지 확인하는 좋은 방법입니다. 종종 래퍼 요소를 사용하는 것이 더 쉽습니다. .paper
요소를 사용하여 전송을 하고, .paper__flyer
를 사용하여 종이를 공급하는 애니메이션을 합니다.
:root {
--load-speed: 2;
}
.paper-stack--top .cuboid--paper .paper {
animation: transfer calc(var(--load-speed) * 0.5s) ease-in-out forwards;
}
.paper-stack--top .cuboid--paper .paper__flyer {
animation: fly calc(var(--load-speed) * 0.5s) ease-in-out forwards;
}
.paper-stack--top .cuboid--paper .paper__flyer:after {
animation: feed calc(var(--load-speed) * 0.5s) calc(var(--load-speed) * 0.5s) forwards;
}
@keyframes transfer {
to {
transform: translate(0, -270%) rotate(22deg);
}
}
@keyframes feed {
to {
transform: translate(100%, 0);
}
}
@keyframes fly {
0% {
transform: translate3d(0, 0, 0) rotateY(0deg) translate(0, 0);
}
50% {
transform: translate3d(140%, 0, calc(var(--height) * 1.2)) rotateY(-75deg) translate(180%, 0);
}
100% {
transform: translate3d(140%, 0, var(--height)) rotateY(-75deg) translate(0%, 0) rotate(-180deg);
}
}
거기에서 상당히 많은 calc
사용을 발견할 것입니다. 애니메이션 타임라인을 구성하기 위해 CSS 사용자 정의 속성을 활용할 수 있습니다. 속성을 참조하여 체인에서 각 애니메이션에 대한 올바른 지연을 계산할 수 있습니다. 종이는 동시에 전달되고 날아갑니다. 하나의 애니메이션은 컨테이너를 이동하고, 다른 애니메이션은 종이를 회전합니다. 이 애니메이션이 끝나면 feed
애니메이션으로 종이가 프린터에 공급됩니다. 애니메이션 지연은 동시에 실행되는 처음 두 애니메이션의 기간과 같습니다.
이 데모를 실행하세요. 여기서 저는 컨테이너 요소를 빨간색과 녹색으로 표시했습니다. .paper__flyer
의 의사 요소를 사용하여 종이 조각을 나타냅니다. 하지만 컨테이너 요소가 어려운 작업을 수행합니다.
언제 종이가 다른 쪽에서 나오는지 궁금할 수도 있습니다. 그러나 사실 종이는 전체적으로 동일한 요소가 아닙니다. 프린터에 들어가는 요소를 사용합니다. 그리고 종이가 프린터에서 날아가는 경우 다른 요소를 사용합니다. 이는 추가 요소가 우리의 삶을 더 쉽게 만드는 또 다른 경우입니다.
종이는 루프를 수행하기 위해 하나 이상의 요소를 사용하고, 그 후 종이가 해당 요소의 가장자리에 위치됩니다. 더 많은 색상의 컨테이너 요소로 이 데모를 실행하면 작동 방식을 보여줍니다.
다시 한 번, 이것은 시행착오가 필요하며, 컨테이너 요소의 사용을 어떻게 활용할 수 있는지 생각해보아야 합니다. 오프셋 transform-origin
을 가진 컨테이너를 갖는 것으로 루프를 생성할 수 있습니다.
인쇄
모든 준비가 완료되었습니다. 이제 실제로 무언가를 인쇄하는 단계입니다. 이를 위해 사용자가 이미지의 URL을 입력할 수 있는 폼을 추가할 것입니다.
form.customer-form
label(for="print") Print URL
input#print(type='url' required placeholder="URL for Printing")
input(type="submit" value="Print")
일부 스타일링을 적용하면 다음과 같은 결과를 얻을 수 있습니다.
폼의 기본 동작과 required
및 type="url"
의 사용으로 인해 우리는 URL만 받아들입니다. 이를 더욱 발전시키기 위해 pattern
을 사용하여 특정 이미지 유형을 확인할 수 있습니다. 그러나 랜덤 이미지에 대한 좋은 URL은 이미지 유형을 포함하지 않을 수 있습니다. 예를 들어 https://source.unsplash.com/random와 같은 경우입니다.
폼을 제출할 때의 동작이 원하는 대로 작동하지 않으며, 또한 인쇄 애니메이션이 로드 시 한 번만 실행됩니다. 이 문제를 해결하기 위해 프린터에 특정 클래스가 적용될 때만 애니메이션을 실행하는 방법이 있습니다.
폼을 제출할 때 URL에 대한 요청을 보내고 장면 내의 이미지에 대한 src
를 설정할 수 있습니다. — 한 이미지는 프린터의 화면 미리보기이고, 다른 하나는 종이 한쪽에 있는 이미지입니다. 실제로 인쇄할 때마다 인쇄된 각 종이에 대한 새 요소를 추가할 것입니다. 이렇게 하면 각 인쇄가 더미에 추가되는 것처럼 보입니다. 로드 시 종이 한 장을 제거할 수 있습니다.
폼 제출을 처리하는 것부터 시작하겠습니다. 기본 이벤트를 방지하고 PROCESS
함수를 호출할 것입니다.
const PRINT = e => {
e.preventDefault()
PROCESS()
}
const PRINT_FORM = document.querySelector('form')
PRINT_FORM.addEventListener('submit', PRINT)
이 함수는 이미지 소스에 대한 요청을 처리합니다.
let printing = false
const PREVIEW = document.querySelector('img.screen__preview-img')
const SUBMIT = document.querySelector('[type="submit"]')
const URL_INPUT = document.querySelector('[type="url"]')
const PROCESS = async () => {
if (printing) return
printing = true
SUBMIT.disabled = true
const res = await fetch(URL_INPUT.value)
PREVIEW.src = res.url
URL_INPUT.value = ''
}
또한 printing
변수를 true
로 설정하여 현재 상태를 추적하고 양식의 버튼을 비활성화합니다.
이미지를 설정하는 대신 이미지에 대한 요청을 하는 이유는 무엇일까요? 절대 URL을 가진 이미지가 필요합니다. 위에서 언급한 “Unsplash” URL을 사용하고 이미지 간에 공유하면 작동하지 않을 수 있습니다. 이는 서로 다른 이미지가 표시되는 시나리오를 만날 수 있기 때문입니다.
이미지 소스를 얻은 후에는 미리보기 이미지 소스를 해당 URL로 설정하고 양식의 입력 값을 재설정합니다.
애니메이션을 트리거하기 위해 미리보기 이미지의 “load” 이벤트에 연결할 수 있습니다. 이벤트가 발생하면 인쇄할 종이 조각의 새 요소를 생성하고 printer
요소에 추가합니다. 동시에 printing
클래스를 프린터에 추가합니다. 이를 사용하여 종이 애니메이션의 첫 번째 부분을 트리거할 수 있습니다:
PREVIEW.addEventListener('load', () => {
PRINTER.classList.add('printing')
const PRINT = document.createElement('div')
PRINT.className = 'printed'
PRINT.innerHTML = `
<div class="printed__spinner">
<div class="printed__paper">
<div class="printed__papiere">
<img class="printed__image" src=${PREVIEW.src}/>
</div>
</div>
<div class="printed__paper-back"></div>
</div>
`
PRINTER.appendChild(PRINT)
// 설정된 시간 후에 상태 재설정
setTimeout(() => {
printing = false
SUBMIT.removeAttribute('disabled')
PRINTER.classList.remove('printing')
}, 4500)
})
설정된 시간 후에 상태를 재설정할 수 있습니다. 대안으로 animationend
이벤트를 디바운스하는 것이 있지만, 애니메이션이 얼마나 걸릴지 알고 있으므로 setTimeout
을 사용할 수 있습니다.
그러나 인쇄가 올바른 비율이 아닙니다. 이는 이미지를 종이 조각에 맞게 확대해야 하기 때문입니다. 이를 위해 작은 조각의 CSS가 필요합니다:
.printed__image {
height: 100%;
width: 100%;
object-fit: cover;
}
프린터 앞쪽의 조명이 프린터가 바쁜 것을 알리는 것도 깔끔할 것입니다. 프린터가 인쇄 중일 때 조명 중 하나의 색상을 조정할 수 있습니다:
.progress-light {
background: hsla(var(--progress-hue, 104), 80%, 50%);
}
.printing {
--progress-hue: 10; /* 빨간색으로 해석 */
}
이렇게 합치면 CSS와 약간의 JavaScript로 만든 “작동하는” 프린터가 완성됩니다.
그게 바로 전부입니다!
우리는 CSS, 약간의 JavaScript, 그리고 Pug를 활용하여 기능적인 3D 프린터를 만드는 방법을 살펴보았습니다. 다음 이미지 링크를 URL 필드에 추가하거나 원하는 다른 이미지를 선택하고 한 번 시도해 보세요!
https://source.unsplash.com/random
이를 달성하기 위해 다양한 것들을 다루었습니다.
- CSS로 3D 물체를 만드는 방법
- Pug 믹신 사용
- DRY를 유지하기 위해 스코프 지정된 사용자 지정 CSS 속성 사용
- 3D 장면을 만들기 위한 압출 사용
- JavaScript로 폼 처리
- 사용자 지정 속성으로 애니메이션 타임라인 구성
이러한 데모를 만드는 재미는 많은 경우 특정 모양을 만들거나 특정 애니메이션을 구성하는 문제를 해결해야 한다는 것입니다. 무언가를 하는 방법은 종종 한 가지 이상입니다.
3D CSS로 어떤 멋진 것들을 만들 수 있을까요? 보고 싶습니다!
언제나 그렇듯이 읽어주셔서 감사합니다. 더 보고 싶으신가요? 트위터에서 저를 찾아보세요 또는 라이브 스트림을 확인하세요!
3D CSS 프린터에 대한 자주 묻는 질문 (FAQ)
3D CSS 프린터란 무엇인가요?
A 3D CSS Printer is a unique concept that uses Cascading Style Sheets (CSS), a style sheet language used for describing the look and formatting of a document written in HTML, to create a 3D representation of a printer. This innovative approach allows developers to create interactive and visually appealing web elements that can enhance user experience.
3D CSS 프린터는 어떻게 작동하나요?
A 3D CSS Printer works by using CSS properties to create a 3D model of a printer. It uses properties such as transform, perspective, and animation to create the 3D effect. The printer is made up of multiple elements, each styled and positioned to create the overall 3D effect. The animation property is then used to create the printing effect.
3D CSS 프린터를 맞춤화할 수 있나요?
네, 3D CSS 프린터를 맞춤화할 수 있습니다. 색상, 크기, 심지어 애니메이션 속도를 변경할 수 있습니다. 이는 프린터의 CSS 속성을 수정하여 수행됩니다. 예를 들어, 프린터 요소의 배경색 속성을 수정하여 색상을 변경할 수 있습니다.
3D CSS 프린터를 내 웹사이트에 통합하는 방법은 무엇인가요?
3D CSS 프린터를 웹사이트에 통합하려면 CSS 및 HTML 코드를 웹사이트 코드에 복사해야 합니다. CSS 코드는 HTML 문서의 head 섹션에 포함되어야 하며, HTML 코드는 웹페이지에서 프린터가 나타낼 위치에 배치해야 합니다.
3D CSS 프린터를 애니메이션으로 만들 수 있나요?
예, 3D CSS 프린터를 애니메이션으로 만들 수 있습니다. 애니메이션은 CSS 애니메이션 속성을 사용하여 달성됩니다. 이 속성을 사용하면 애니메이션의 시작 및 종료 상태와 중간 단계를 정의하는 키 프레임을 생성할 수 있습니다.
3D CSS 프린터를 지원하는 브라우저는 어떤 것들이 있나요?
3D CSS 프린터는 CSS 변환 및 애니메이션 속성을 지원하는 모든 최신 브라우저에서 작동해야 합니다. 이에 해당하는 브라우저로는 Google Chrome, Mozilla Firefox, Safari, Microsoft Edge 등이 있습니다.
3D CSS 프린터를 상업적 목적으로 사용할 수 있나요?
예, 3D CSS 프린터를 상업적 목적으로 사용할 수 있습니다. 그러나 사용하는 코드의 라이선스 조건을 확인하여 적합성을 확인하는 것이 항상 좋습니다.
3D CSS 프린터를 만들기 위해 어떤 기술이 필요한가요?
3D CSS 프린터를 만들기 위해서는 HTML과 CSS에 대한 좋은 이해가 필요합니다. transform, perspective, animation과 같은 CSS 속성에 익숙해져야 하며, 기본적인 3D 모델링 지식도 도움이 되지만 필수는 아닙니다.
3D CSS 프린터에 JavaScript를 사용할 수 있나요?
네, JavaScript를 3D CSS 프린터에 사용할 수 있습니다. 프린터는 CSS만으로도 만들 수 있지만, JavaScript를 사용하면 사용자 액션에 따라 애니메이션을 시작하거나 중지하는 등의 상호작용을 추가할 수 있습니다.
3D CSS 프린터에 대해 더 배울 수 있는 자료가 있나요?
3D CSS 프린터에 대해 더 배울 수 있는 많은 온라인 자료가 있습니다. SitePoint, CSS-Tricks, MDN Web Docs와 같은 웹사이트에는 CSS 애니메이션과 3D 변환에 관한 포괄적인 튜토리얼과 가이드가 있습니다. YouTube에도 이에 관한 많은 동영상 튜토리얼이 있습니다.