23. copying to the clipboard
๋ด์ฉ
์ ๊ธ์ ์น ์ ํ๋ฆฌ์ผ์ด์
์์ ์ฌ์ฉ์์ ํด๋ฆฝ๋ณด๋๋ก ๋ฐ์ดํฐ๋ฅผ ๋ณต์ฌํ๋ ๋ฐฉ๋ฒ์ ๋ํ ์ค๋ช
์
๋๋ค.
์ ํ๋ฆฌ์ผ์ด์
์ ์ผ๋ถ์ธ 'box' ๊ฐ์ฒด์ ๋ณํ ์์ฑ ๊ฐ์ ์ฌ์ฉ์ ํด๋ฆฝ๋ณด๋๋ก ๋ณต์ฌํ๋ ๊ณผ์ ์ ๋ด๊ณ ์์ต๋๋ค.
์ด๋ฅผ ์ํด, HTML ํ
ํ๋ฆฟ์ ๋ฒํผ์ ํด๋ฆญ ์ด๋ฒคํธ ๋ฆฌ์ค๋๋ฅผ ์ถ๊ฐํ๊ณ , ์๋ฐ์คํฌ๋ฆฝํธ ํ์ผ์์ 'copy' ๋ฉ์๋๋ฅผ ์ ์ํฉ๋๋ค.
์ด ๋ฉ์๋๋ navigator.clipboard.writeText
ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ๋น๋๊ธฐ์ ์ผ๋ก ํด๋ฆฝ๋ณด๋์ ํ
์คํธ๋ฅผ ๋ณต์ฌํฉ๋๋ค.async
์ await
๊ตฌ๋ฌธ์ ์ฌ์ฉํ์ฌ ๋น๋๊ธฐ ์ฝ๋๋ฅผ ์ฒ๋ฆฌํฉ๋๋ค.
๋ง์ง๋ง์ผ๋ก, ์ฌ์ฉ์์๊ฒ ์ฑ๊ณต์ ์ผ๋ก ๋ณต์ฌ๋์๋ค๋ ํผ๋๋ฐฑ์ ์ ๊ณตํ๊ธฐ ์ํด ์๋ฆผ(alert
) ํจ์๋ฅผ ์ฌ์ฉํฉ๋๋ค.
์ด ๊ณผ์ ์ ์ต์ ๋ธ๋ผ์ฐ์ ์์ ์ง์๋๋ ํด๋ฆฝ๋ณด๋ API๋ฅผ ํ์ฉํ๋ฉฐ, ๊ตฌํ ๋ธ๋ผ์ฐ์ ์์๋ ์๋ํ์ง ์์ ์ ์์์ ์ธ๊ธํฉ๋๋ค.
<!DOCTYPE>
<html>
<head>
<title>CSS3 Perspective Playground</title>
<link rel="stylesheet" type="text/css" href="main.css" />
</head>
<body>
<div id="app">
<h2>CSS3 Perspective Playground</h2>
<main>
<section class="settings">
<div class="settings-container">
<label>perspective: {{ perspective }}px;</label>
<input type="range" min="0" max="999" v-model="perspective" />
<label>rotateX: {{ rotateX }}deg; </label>
<input type="range" min="-180" max="180" v-model="rotateX" />
<label>rotateY: {{ rotateY }}deg; </label>
<input type="range" min="-180" max="180" v-model="rotateY" />
<label>rotateZ: {{ rotateZ }}deg; </label>
<input type="range" min="-180" max="180" v-model="rotateZ" />
<button type="button" @click.prevent="reset">Reset</button>
<button type="button" @click.prevent="copy">Copy</button>
</div>
</section>
<section class="output">
<div class="box-container">
<div class="box" :style="box"></div>
</div>
</section>
</main>
</div>
<css-doodle>
:doodle {
@grid: 1x3 / 100vmax;
position: absolute;
top: 0; left: 0;
z-index: 0;
}
@size: 100% 150%;
position: absolute;
background: @m(100, (
linear-gradient(transparent, @p(
#FFFDE1@repeat(2, @p([0-9a-f])),
#FB3569@repeat(2, @p([0-9a-f]))
))
@r(0%, 100%) @r(0%, 100%) /
@r(1px) @r(23vmin)
no-repeat
));
will-change: transform;
animation: f 50s linear calc(-50s / @size() * @i()) infinite;
@keyframes f {
from { transform: translateY(-100%) }
to { transform: translateY(100%) }
}
</css-doodle>
<script src="https://unpkg.com/css-doodle@0.6.1/css-doodle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.4.9/vue.global.min.js"></script>
<script src="app.js"></script>
</body>
</html>
Vue.createApp({
data() {
return {
perspective: 100,
rotateX: 0,
rotateY: 0,
rotateZ: 0
}
},
computed: {
box() {
return {
transform: `
perspective(${this.perspective}px)
rotateX(${this.rotateX}deg)
rotateY(${this.rotateY}deg)
rotateZ(${this.rotateZ}deg)
`
}
}
},
methods: {
reset() {
this.perspective = 100
this.rotateX = 0
this.rotateY = 0
this.rotateZ = 0
},
async copy() {
let text = `transform:${this.box.transform};`
await navigator.clipboard.writeText(text)
alert("CSS Copied to Clipboard!")
}
}
}).mount('#app')
html {
box-sizing: border-box;
width: 100%;
height: 100%;
}
*,
*:before,
*:after {
box-sizing: inherit;
padding: 0;
margin: 0;
}
body {
font-family: sans-serif;
height: 100%;
margin: 0;
background: #261c33;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center
}
h2 {
color: #8d81f3;
text-align: center;
font-size: 40px;
margin: 20px;
}
main {
display: flex;
justify-content: space-around;
align-items: center;
height: 420px;
max-width: 768px;
margin: 0 auto;
font-family: monospace, sans-serif;
font-size: 22px;
}
main label{
display: block;
}
main input[type="range"] {
display: block;
margin-bottom: 10px;
width: 200px;
}
section.settings {
width: 50%;
z-index: 2;
}
.box-container {
padding: 50px;
border: 1px solid #8d81f3;
}
.box {
width: 150px;
height: 150px;
background: #8d81f3;
}
button {
background-color: #8d81f3;
color: #fff;
display: inline-block;
font-size: 20px;
padding: 10px;
outline: none;
border: none;
margin-right: 10px;
}
label{
color: #fff;
}