CSS&JS/👀Study and Copy

[Hyperplexed]패럴랙스 드래그 슬라이드

arancia_ 2023. 6. 14. 13:20

[Hyperplexed]Award Winning Animation With Only 20 Lines Of CSS?

데모 : https://ohikmyeong.github.io/hpp-drag-slider

 

Award Winning Animation With Only 20 Lines Of CSS?

 

ohikmyeong.github.io

드래그로 부드럽게 이동하는 이미지 슬라이더다. 특징은 드래그 안의 이미지가 드래그 동작에 맞춰 다른 속도로 움직여서 그 효과가 더 좋게 보인다. 핵심개념은 css의 object-position과 js에서 animate()를 사용한다.

다른 개체에도 적용시킬 수 있도록 클래스화 시켰고, html에 data-* 대신, 클래스를 이용하는 만큼 constructor안에 상황을 저장하도록 했다.

 

HTML

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Award Winning Animation With Only 20 Lines Of CSS?</title>
    <link rel="stylesheet" href="./style.css"/>
    <script src="./main.js" type="module"></script>
</head>
<body>
    <div id="wrapper">
        <a href="https://www.youtube.com/watch?v=PkADl0HubMY">[Hyperplexed]Award Winning Animation With Only 20 Lines Of CSS?</a>
        <h1>Smooth Drag Slider</h1>
        <ul id="slider"></ul>
    </div>
</body>
</html>
cs

CSS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
@charset "utf-8";
*{margin:0;padding:0;box-sizing:border-box;}
body{
    background:#000;
    color:#fff;
}
 
a{background:#222;color:mediumspringgreen;
padding:10px;}
 
#wrapper{
    display:flex; flex-flow:column nowrap;
    justify-content:flex-start; align-items:center;
    gap:1rem;
    position:relative;
    overflow:hidden;
    width:100%;height:100vh;
    user-select:none;
}
 
#slider{
    display:flex;
    gap:40px;
    position:absolute;
    top:50%;left:50%;
    transform:translate(0,-50%);
    cursor:pointer;
}
 
#slider li{
    position:relative; overflow:hidden;
    height:45vmin; aspect-ratio:1/1.35;
    border-radius:4px;
    background:rgba(255,255,255,.5);
}
 
#slider li img{
    width:100%; height:100%;
    object-fit:cover;
    object-position:0% 50%;
}
cs

main.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import { SmoothDragSlider } from "./SmoothDragSlider.js";
 
const imgs = [
    "https://images.unsplash.com/photo-1511201173873-c327e63eb6c4?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1160&q=80",
    "https://images.unsplash.com/photo-1686245535496-277ecf86ae2e?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80",
    "https://plus.unsplash.com/premium_photo-1686174386454-1e303af1c90d?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1932&q=80",
    "https://images.unsplash.com/photo-1685987300287-6c1dc4d0508e?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80",
    "https://images.unsplash.com/photo-1685495975736-d2a34edbe638?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1471&q=80",
    "https://images.unsplash.com/photo-1474511320723-9a56873867b5?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1472&q=80",
    "https://plus.unsplash.com/premium_photo-1664299499486-0855b1d9e22d?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1483&q=80",
    "https://images.unsplash.com/photo-1685195629553-637e7c296152?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80",
    "https://images.unsplash.com/photo-1685859744475-8a15fea4d2bf?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80",
    "https://images.unsplash.com/photo-1686245535496-277ecf86ae2e?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80",
    "https://plus.unsplash.com/premium_photo-1686174386454-1e303af1c90d?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1932&q=80",
    "https://images.unsplash.com/photo-1685987300287-6c1dc4d0508e?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80",
    "https://images.unsplash.com/photo-1685495975736-d2a34edbe638?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1471&q=80",
    "https://images.unsplash.com/photo-1474511320723-9a56873867b5?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1472&q=80",
    "https://plus.unsplash.com/premium_photo-1664299499486-0855b1d9e22d?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1483&q=80",
    "https://images.unsplash.com/photo-1685195629553-637e7c296152?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80",
    "https://images.unsplash.com/photo-1685859744475-8a15fea4d2bf?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80",
    "https://images.unsplash.com/photo-1511201173873-c327e63eb6c4?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1160&q=80",
];
 
const $slider = document.getElementById('slider');
imgs.forEach(img=>{
    const $li = document.createElement('LI');
    const $img = new Image();
    $img.src = img;
    $img.setAttribute('draggable',false);
    $li.appendChild($img);
    $slider.appendChild($li);
});
 
new SmoothDragSlider($slider);
cs

SmoothDragSlider.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
export class SmoothDragSlider{
    constructor($slider){
        this.$slider = $slider;
 
        this.mouseDownAt = 0;
        this.mouseDelta = 0;
        this.maxDelta = window.innerWidth / 2;
        this.percentage = 0;
        this.lastPercentage = 0;
        this.init();
    }//constructor
 
    init(){
        this.add_mouse_down();
    }//init
    
    add_mouse_down(){
        window.addEventListener('mousedown',this.on_mouse_down,{once:true});
    }//add_mouse_down
 
    on_mouse_down = e =>{
        const {clientX} = e;
        this.mouseDownAt = clientX;
 
        window.addEventListener('mousemove'this.on_mouse_move);
        window.addEventListener('mouseup',this.clear);
    }//on_mouse_down
 
    on_mouse_move = e =>{
        const {clientX} = e;
        this.maxDelta = this.$slider.offsetWidth;
        this.mouseDelta = this.mouseDownAt - clientX;
        this.percentage = (this.mouseDelta / this.maxDelta) * -100 + this.lastPercentage;
        if(this.percentage > 0){ 
            this.percentage = 0;
        }else if(this.percentage < -100){
            this.percentage = -100;
        }
        // this.$slider.style.transform = `translate(${this.percentage}%, -50%)`;
        this.$slider.animate({
            transform : `translate(${this.percentage}%, -50%)`
        },{
            duration : 1200
            fill : "forwards"
        });
 
        const $$img = this.$slider.querySelectorAll('IMG');
        $$img.forEach($img =>{
            // $img.style.objectPosition = `${100 + this.percentage}% 50%`;
            $img.animate({
                objectPosition : `${100 + this.percentage}% 50%`
            },{
                duration : 1200
                fill : "forwards"
            });
        });
    }//on_mouse_move
 
    clear = (e) =>{
        this.lastPercentage = this.percentage;
        window.removeEventListener('mousemove',this.on_mouse_move);
        this.add_mouse_down();
    }//clear
}//class-SmoothDragSlider
cs