이미지 리사이즈

css:resize

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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Answer</title>
<style>
.resizable {
resize: both;
border: 2px solid blue;
overflow: hidden;
position: relative;
}

.resizable::after{
position: absolute;
display: block;
bottom: 0;
right: 0;
width: 10px;
height: 10px;
background-color: blue;
content: "";
cursor: nwse-resize;
}
</style>
</head>
<body>
<h1>Answer</h1>
<form name="image">
<input type="text" name="src" value="./example.jpg">
<button type="submit">불러오기</button>
</form>
<script>
const MAX_WIDTH = 800;
const MIN_WIDTH = 300;

const generateRandomId = () => btoa(Math.random()).substr(0, 12);
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
const wrap = mutation.target;
switch (mutation.attributeName) {
case 'style': {
let nextWidth = parseInt(wrap.style.width);
if (nextWidth > MAX_WIDTH) {
nextWidth = MAX_WIDTH;
} else if (nextWidth < MIN_WIDTH) {
nextWidth = MIN_WIDTH;
}

wrap.style.width = `${nextWidth}px`;
wrap.style.height = `${nextWidth / wrap.dataset.ratio}px`;
}
}
});
});

const loadImage = (src) => {
const id = generateRandomId();
const img = new Image();
img.src = `${src}?v=${id}`;
img.id = id;
img.onload = (event) => {
const _img = document.getElementById(id);
const _wrap = _img.parentElement;
const { width, height } = _img.getBoundingClientRect();

_wrap.style.width = `${width}px`;
_wrap.style.height = `${height}px`;
_wrap.dataset.ratio = String((width / height).toFixed(2));
_img.style.width = '100%';
_img.style.height = '100%';
};


const wrap = document.createElement('div');
wrap.classList.add('resizable');
wrap.appendChild(img);
document.body.appendChild(wrap);
observer.observe(wrap, {
attributes: true,
});
}

document.forms.image.addEventListener('submit', (event) => {
event.preventDefault();

const src = event.target.src.value;
if (src) {
loadImage(src);
}
});

</script>
</body>
</html>

js:resize

  • 시간될 때 구현해보자.
  • handler 를 만들고, nw, ne, sw, se 방향에 childNode를 각각 만들고 after content 로 영역을 생성해야한다.

여담

  • 컴포넌트의 기본 단위라고 생각되는 것들에 대해 vanila 로 스니펫을 많이 만들어봐야될 것 같다.
  • react-movable React 와 여러 Util Class 를 사용하여 Commits on Aug 12, 2019 부터 만든 것 같은데, 90m 안에 가능했던걸까.