
현재위치 = 현재위치 + 감속비율 * (목표위치 - 현재위치)
![]() | ![]() |
|---|
body{
margin: 0px;
/* 화면에 div 딱 달라붙게 */
}
#wrapper{
width: 100%;
height: 600px;
background-color: beige;
position: relative;
cursor: url("../../images/fruit/banana1.png"), auto;
/* 커서를 바나나 그림으로, 미니언한테 바나나 주려고.. */
}
let img;
let a=0.1; // 비율계수 정의. 1에 가까울 수록 투박함, 0에 가까울 수록 부드러움
let targetX=650; //이미지가 도달할 x축 위치 (일단 임의지정)
let targetY=500;
function createPic(){
img=document.createElement("img");
img.src="../../images/minion.png";
img.style.width=60+"px";
img.style.position="absolute"; //wrapper기준으로 한 위치
img.style.left=200+"px";
img.style.top=150+"px";
document.getElementById("wrapper").appendChild(img); //한 줄로 부착하기 정리
}
function move(){ // 그냥 단 번에 건너뛰기가 아니라 목표지점에 야금야금 다가가는 감속도 공식
//나의 위치= 현재 내 위치 + 비율계수*(남은거리= 목표지점-현재 내 위치)
img.style.left=parseFloat(img.style.left)+a*+(targetX-parseFloat(img.style.left))+"px";
//3.44556 parseInt(3.44556) → 3반환
//3.44556 parseFloat(3.44556) → 3.44556 반환 (더 정교)
img.style.top=parseFloat(img.style.top)+a*(targetY-parseFloat(img.style.top))+"px";
// px을 수식 계산 식에 넣지 않도록 조심!
}
function gameLoop(){
move();
}
window.addEventListener("load",function(){
createPic();
// 마우스 이벤트 연결하기
// mousedown (마우스 누르기만 하면 실행)
// mousemove (마우스 졸졸 따라다님)
document.getElementById("wrapper").addEventListener("mousemove",function(){
// targetX=마우스x값;
// targetY=마우스y값; 으로 연결하면 마우스 따라옴
targetX=event.clientX;
targetY=event.clientY;
});
setInterval("gameLoop()",10);
});
<body>
<div id="wrapper">
</div>
</body>
parseInt 와 parseFloat
parseInt는 문자열을 정수로 변환
parseFloat 문자열을 부동소수점(실수)으로 변환
ex) 3.44556라는 수가 있을 때,
parseInt(3.44556) → 3반환
parseFloat(3.44556) → 3.44556 반환 (더 정교함)
결론: parseFloat을 써야 아주 부드럽게 감속하면서 목표 지점으로 이동 가능
mousedown (마우스 누른 곳에 실행)
mousemove (마우스 졸졸 따라다님)
event: 어떤 일이 발생했을 때 브라우저가 만들어주는 객체 (object)
키보드 이벤트는 key, code를 주로 사용 (event.key, event.code)
clientX, clientY는 마우스 전용 개념 (event.ClientX)
drawer : 서랍
서랍처럼 부드럽게 스르륵 열리는 효과내기
주로 사이드바나 메뉴를 열고 닫는 애니메이션 효과
![]() | ![]() |
|---|
<head>
<title>서랍 효과내기 (drawer)</title>
<style>
body{margin:0px;}
#rect{
height: 150px;
background-color: palevioletred;
position: relative;
border-radius: 6px;
left: -5px;
/* 책갈피처럼 안쪽은 둥글둥글효과 안보이게 숨겨라 */
}
</style>
<script>
let rect;
let a=0.1;
let targetW=35; //목표너비
function init(){ // 프로그램 가동과 동시에 하고싶은 작업을 하는 함수영역
rect=document.getElementById("rect");
rect.style.width=30+"px";
}
function setLength(){ // 감속도 공식은 꼭 left에만 적용x, 물리적 크기, 위치 등 모두 가능
// 나의 너비 = 현재 나의 너비 + 비율 계수*(목표너비-현재 나의 너비)
rect.style.width=parseFloat(rect.style.width)+a*(targetW-parseFloat(rect.style.width))+"px";
// left를 조정 : div 자체가 좌우로 움직인다
// width를 조정 : div의 크기가 늘어난다 (서랍처럼)
}
function gameLoop(){ //길이를 조절하는 함수 끝없이 호출
setLength();
}
window.addEventListener("load",function(){
init();
// 이 시점은 rect를 얻어온 이후 시점이므로...제어하기 위해
rect.addEventListener("mouseover",function(){
targetW=350;
});
rect.addEventListener("mouseout",function(){
targetW=35;
});
setInterval("gameLoop()",10);
});
</script>
</head>
<body>
<div id="rect"></div>
</body>
</html>
여기서 setInterval의 역할:
setInterval은 지정한 시간 간격(여기서는 10ms)마다 지정된 함수를 반복적으로 호출.
이 방식으로 서랍의 width를 점진적으로 변경시켜서 서랍이 부드럽게 열리고 닫히는 애니메이션 효과 만들기
mouseover 마우스 갖다대면 넓어지고 (targetW값 350)
mouseout 마우스 떼면 다시 좁아지기 (targetW값 35)
left를 조정 : div 자체가 좌우로 움직인다
width를 조정 : div의 크기가 늘어난다 (서랍처럼)
js에서는 개발자가 유용하게 사용할 수 있는 기능들을 내장객체란 이름으로 지원 (Built-in Object)
이 객체들 중 수학과 관련된 처리는 Math객체가 담당
날짜, 시간 등은 Date
문자열 처리는 String
JSON 형식은 JSON 내장 객체가 지원됨
let r=Math.random(); // 0.xxxx ~ < 1
console.log(r);
console.log(parseInt(Math.random()*4)); // 0~3사이의 정수
console.log(parseInt(Math.random()*8)); // 0~7사이의 정수
랜덤은 0보다 크고, 절대로 1을 넘어설 수 없는 소수(실수)가 반환됨
(랜덤 값 * (내가 원하는 수+1)) → 내가 원하는 수.xxxx 나옴
→ 소수점은 parseInt로 버리자
자주 쓰이기 때문에 함수파일로 저장하자
js_lib / common.js
<common.js>
function getRandom(n){
return parseInt(Math.random()*(n+1));}
// 원하는 정수를 반환받기 위해서는 n의 값을 호출 시 결정하자
// ex) getRandom(10)을 넘기면 0~10 반환
// ex) getRandom(9)을 넘기면 0~9 반환
getRandom()함수 불러오고 싶을 때는 이렇게 불러오기
<script src="../../js_lib/common.js"></script>

저 반딧불이가 일정시간마다 랜덤한 위치로 돌아다님
마우스로 클릭하면 클릭한 부분으로도 오게 구현
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>랜덤한 반딧불이</title>
<style>
body{margin: 0px;}
#wrapper{
height: 900px;
background-image: url(../../images/bandi/night.jpg);
background-size: 100% 100%;
}
</style>
<script src="../../js_lib/common.js"></script>
<!-- 라이브러리 코드 불러옴 -->
<script>
let targetX=600,targetY=700;
let a=0.1;
let img;
let count=0; //반딧불의 위치를 언제 바꿀지를 결정짓는 변수
function init(){
img=document.createElement("img");
img.src="../../images/bandi/bug.png";
img.style.width=40+"px";
img.style.position="absolute";
img.style.left=100+"px";
img.style.top=100+"px";
document.getElementById("wrapper").appendChild(img); //이미지 반딧불이 이미지 부착
}
function move(){ //야금야금 움직이기
img.style.left=parseFloat(img.style.left)+a*(targetX-parseFloat(img.style.left))+"px";
//x축으로의 부드러운 움직임
img.style.top=parseFloat(img.style.top)+a*(targetY-parseFloat(img.style.top))+"px";
//y축으로의 부드러운 움직임
}
function setPos(){ // 랜덤구하기를 사용한 포지션 정하기
targetX=getRandom(10)*100; // 0~1000 화면의 너비에 사용
targetY=getRandom(9)*100; // 0~900 화면의 높이에 사용
}
function gameLoop(){
count++;
if(count%50==0)setPos(); //50마다 포지션을 바꾸는 함수 호출
move();
}
addEventListener("load", function(){
init();
let wrapper=document.getElementById("wrapper");
wrapper.addEventListener("mousedown",function(){
targetX=event.clientX;
targetY=event.clientY;
});
setInterval("gameLoop()",50);
});
</script>
</head>
<body>
<div id="wrapper"></div>
</body>
</html>
let targetX=600,targetY=700;
function setPos(){ // 랜덤구하기를 사용한 포지션 정하기
targetX=getRandom(10)*100; // 0~1000 화면의 너비에 사용
targetY=getRandom(9)*100; // 0~900 화면의 높이에 사용
}
getRandom() 랜덤 코드 불러와서 활용하기 function move(){ //야금야금 움직이기
img.style.left=parseFloat(img.style.left)+a*(targetX-parseFloat(img.style.left))+"px";
// x축으로의 부드러운 움직임
img.style.top=parseFloat(img.style.top)+a*(targetY-parseFloat(img.style.top))+"px";
// y축으로의 부드러운 움직임
}
감속도 운동 공식을 사용하여 부드러운 움직임 구현 let count=0; //반딧불의 위치를 언제 바꿀지를 결정짓는 변수
function gameLoop(){
count++;
if(count%50==0)setPos(); // 50마다 포지션을 바꾸는 함수 호출
move();
}
getLoop()로 포지션 변경 타이밍 조건 걸고, onload 이벤트에 setInterval로 호출setInterval의 50은 시간 간격 (ms 단위),count % 50 == 0의 50은 횟수 기준배열: 데이터 여러 개가 순서를 가지고 모여있는 집합 상태
개별 요소마다 이름을 부여한 적이 없기 때문에, 요소들에 접근하기 위해서는 가리킬 수단이 필요함
→ 배열로 선언된 데이터는 순서 보장
배열과 반복문은 실과 바늘.
배열♥반복문 조합 압도적으로 사용빈도 높음
<script>
let fruit=[];
fruit [0]="apple";
fruit [1]="banana";
fruit [2]="cherry";
fruit [3]="grape";
fruit [4]="orange";
fruit [5]="peach";
fruit [6]="pineapple";
fruit [7]="watermelon";
fruit [8]="mango";
fruit [9]="kiwi";
for(let i=0; i<fruit.length; i++){
// fruit.length로 배열의 길이 유연하게 설정 (단, =넣으면 안됨)
document.write(fruit[i]+"<br>");}
</script>
배열명.length : 배열 안에 몇 개가 들어 있는지 알려주는 숫자크기가 10인 배열에 0부터 9까지 정수를 채우고, 다시 출력하는 프로그램을 작성하세요.
let num = []; // 빈 배열 생성 (num.length는 0)
for (let i = 0; i < 10; i++) { // 0부터 9까지 각 인덱스에 값 채우기
num[i] = i;
}
for (let i = 0; i < num.length; i++) { // 배열 출력하기
document.write(num[i] + "<br>");
}
let num = []; → [] 는 빈 배열. 처음에는 num.length == 0배열.length = 숫자;를 쓰면 빈 자리만 확보하고 값은 없음(undefined)오늘은 MySQL이 아닌 Oracle설치 후 데이터베이스, user 설정하고
emp,dept 테이블 만들어봄
CREATE TABLESPACE myspace
DATAFILE 'C:\oraclexe\app\oracle\oradata\XE\myspace.dbf'
SIZE 1m;
--지정 후 ctrl + enter (커서가 있는 현재 SQL 문장 한 줄만 실행)
--테이블스페이스만 딱 한 번 생성됨
CREATE USER java
--비번
IDENTIFIED BY ****
--기본 테이블스페이스는 myspace
DEFAULT TABLESPACE myspace
quota unlimited ON myspace;
--myspace 테이블스페이스에 저장할 수 있는 용량은 무제한
--접속권한
GRANT CREATE SESSION TO java;
--테이블에 대한 권한
GRANT CREATE TABLE TO java;
--시퀀스 생성 권한
GRANT CREATE SEQUENCE TO java;
Oracle은 사용자 만들 때 tablespace, quota 관리까지 해줘야 해서 무겁고 세밀한 스타일이고 MySQL은 사용자 만들 때 접속위치(host)랑 권한만 주면 돼서 가볍고 빠른 스타일인 게 느껴진다... 벌써 보고싶다 MySQL ㅠㅠ