패럴랙스를 실제로 보이게 고치고 격자를 걷어낸다
"티가 안 난다"는 지적이 맞았다. 세 가지를 동시에 잘못하고 있었다. 1. 이동량이 모자랐다 여유를 28% 잡아놓고 92px 만 움직였다. 스크롤 1800px 구간에서 5%다. 공식은 이미지를 컨테이너보다 크게 만들고 초과분 전체를 움직이는 것. depth 0.45 -> 높이 145%, translateY(-31.03%). 같은 구간에서 374px. translateY(%) 는 자기 크기 기준이라 컨테이너 높이를 몰라도 맞는다. 2. overflow: hidden 이 view() 타임라인을 죽이고 있었다 overflow: hidden 은 스크롤 컨테이너를 만들고, 그러면 자식의 view() 가 문서가 아니라 그 상자를 기준으로 잡힌다. 이미지는 상자 안에서 늘 같은 자리라 진행도가 고정된다. 콘솔 에러도 없고 computed 값도 정상이라 두 스크롤 위치에서 transform 을 재보고서야 이동 0px 인 것을 알았다. 잘라내는 일은 섹션의 overflow: clip 에 맡겼다. 3. opacity 로 눌러 이미지를 지웠다 어두운 광원 사진을 opacity 0.5 로 깔면 검정도 빛도 같이 죽는다. mix-blend-mode: screen 으로 바꿨다 — 검정은 투명, 밝은 곳만 더해진다. 그래서 불투명도 0.85~1.0 을 써도 본문 대비가 안전하다. 생성 프롬프트도 같은 함정이었다. "어둡게"를 너무 강하게 넣어서 안전한 이미지가 아니라 없는 이미지를 만들었다. 격자 배경 제거 사진이 들어온 뒤로 배경이 두 겹이라 서로 경쟁했고 표로 읽혔다. 배경도 한 섹션에 하나다. 스킬 motion.md 에 넷 다 반영 이동량 공식 · overflow 함정 · screen 합성 · 배경은 한 겹
This commit is contained in:
parent
5a18806fb6
commit
1ed3c95542
11 changed files with 181 additions and 85 deletions
|
|
@ -448,6 +448,81 @@ JS 쪽 판정도 한 곳에 모은다. 설정이 도중에 바뀌면 반영한
|
|||
안 움직이는 섹션이 하나도 없으면 움직임에 의미가 없다는 뜻이고,
|
||||
`design.md` 에 "여기는 의도적으로 정지"라고 적어두지 않으면 다음 사람이 "빠뜨린 것"으로 보고 채운다.
|
||||
|
||||
### 이동량은 절대값이 아니라 컨테이너 대비 비율이다
|
||||
|
||||
**패럴랙스가 "안 보인다"의 대부분은 이동량이 모자란 것이다.**
|
||||
|
||||
공식은 하나다. **배경을 컨테이너보다 크게 만들고, 그 초과분 전체를 움직인다.**
|
||||
|
||||
```
|
||||
이미지 높이 = 컨테이너 × (1 + depth)
|
||||
이동량 = 컨테이너 × depth
|
||||
= 이미지 높이의 depth / (1 + depth)
|
||||
```
|
||||
|
||||
`depth: 0.45` 면 이미지는 145%, 이동은 이미지 자기 높이의 **31%**.
|
||||
섹션이 2000px 이면 **900px** 을 움직인다.
|
||||
|
||||
```css
|
||||
.bg img {
|
||||
height: 145%; /* 1 + depth */
|
||||
animation: bg-par linear both;
|
||||
animation-timeline: view();
|
||||
animation-range: cover 0% cover 100%;
|
||||
}
|
||||
@keyframes bg-par {
|
||||
from { transform: translateY(0); }
|
||||
to { transform: translateY(-31.03%); } /* depth / (1 + depth) */
|
||||
}
|
||||
```
|
||||
|
||||
`translateY(%)` 는 **자기 크기 기준**이라 컨테이너 높이를 몰라도 정확히 맞는다.
|
||||
|
||||
**실측 사례**: 여유를 28% 잡아놓고 `±46px`(총 92px)만 움직였더니 스크롤 1800px 구간에서
|
||||
이동 비율이 5% 였다. 아무도 시차를 느끼지 못했다. 같은 구간에서 **374px** 로 올리자 보였다.
|
||||
CSS-Tricks 의 예제도 `background-position: bottom 0px → bottom -400px`, 즉 400px 이다.
|
||||
|
||||
> 참고: `background-position` 을 애니메이션하는 방법도 있다(CSS-Tricks). 다만 그러면
|
||||
> `<img loading="lazy">` 의 지연 로딩과 반응형 `srcset` 을 잃는다. 무거운 사진이면 `<img>` 를
|
||||
> 절대배치하고 `transform` 을 쓰는 쪽이 낫다.
|
||||
|
||||
### `overflow: hidden` 이 view() 타임라인을 죽인다
|
||||
|
||||
**이것 하나에 패럴랙스가 통째로 멈춘다. 그리고 조용히 멈춘다.**
|
||||
|
||||
`overflow: hidden` 은 **스크롤 컨테이너를 만든다.** 그러면 그 안에 있는 자식의
|
||||
`animation-timeline: view()` 는 문서가 아니라 **그 상자**를 기준으로 잡힌다.
|
||||
자식은 상자 안에서 위치가 변하지 않으므로 진행도가 고정되고, 애니메이션은
|
||||
어중간한 한 프레임에서 굳는다.
|
||||
|
||||
- 콘솔 에러 없음. `animation-name`·`animation-timeline` computed 값도 전부 정상
|
||||
- `getComputedStyle(el).transform` 을 두 스크롤 위치에서 재봐야 알 수 있다. **실측에서 이동 0px**
|
||||
|
||||
**잘라내야 한다면 `overflow: clip` 을 쓰거나 조상 섹션에서 처리해라.**
|
||||
`clip` 은 스크롤 컨테이너를 만들지 않는다.
|
||||
|
||||
### 어두운 배경 위 광원 이미지는 opacity 로 누르지 마라
|
||||
|
||||
`opacity` 는 이미지 전체를 균일하게 죽인다 — 검정도, 빛도 같이. 그래서 어두운 광원 사진을
|
||||
`opacity: 0.5` 로 깔면 **있는지조차 안 보인다.**
|
||||
|
||||
```css
|
||||
.bg img { mix-blend-mode: screen; opacity: 0.9; }
|
||||
```
|
||||
|
||||
`screen` 은 **검정을 투명하게 만들고 밝은 곳만 더한다.** 그래서 불투명도를 높게 유지해도
|
||||
본문 대비를 해치지 않는다. 밝은 이미지(종이·질감)는 반대로 `normal` 이 맞다.
|
||||
|
||||
**생성형 이미지를 배경으로 쓸 때 특히 조심해라.** 프롬프트에 "본문 뒤에 깔리니 어둡게"를
|
||||
너무 강하게 넣으면 안전한 이미지가 아니라 **없는 이미지**가 나온다.
|
||||
대비는 합성 방식으로 풀고, 이미지 자체는 볼 수 있게 만들어라.
|
||||
|
||||
### 배경도 한 섹션에 하나다
|
||||
|
||||
CSS 격자와 사진을 같이 깔았다가 걷어냈다. 두 배경이 서로 경쟁했고,
|
||||
격자는 배경이라기보다 **표**로 읽혔다. 앞에서 "한 층은 고정"이라고 한 것과 같은 이야기다 —
|
||||
층을 늘리는 것과 층이 싸우게 두는 것은 다르다.
|
||||
|
||||
### 패럴랙스에는 기준면이 필요하다
|
||||
|
||||
**배경이 단색이면 패럴랙스는 성립하지 않는다.** 앞의 것이 몇 px 어긋나 봐야
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue