이젠 다들 빨라서 별로 느낌없지망 타자기부터 초기 컴퓨터가 보급되던 시절까정,
타이핑이 빠른 사람들을 보면 얼마나 대단해 보이던지 많은 사람들이 타이핑을 빨리치기 위해서
한메타자 연습 프로그램등을 이용해서 주거라고 타이핑연습을 하고, 엑셀 자격증등등을
취득하였당. 그 시절을 생각하면서 산성비 프로그램을 맹글어보장.
실제 맹글어보면 항상 그렇진 않지만 역시 별로 어렵지는 않당.
자바스크립트는 규모가 커지면 자연스럽게 설계가 객체지향방식으로 이어지고, 작으면
함수지향방식의 프로그램으로 이어지는 느낌이 있어 개인적으로 마니 좋아한당.
산성비 프로그램은 처음 프로그램을 공부하는 사람들에게 재미와 흥미, GUI적인 결과
그리고 쉽게 생각할 수 있는 추가 아이디어등 덕분에 로직훈련용으로 아주 좋당.
느낌있게 빨리 결과로 달려가 보장. 가끔은 반대로 답을 찾는 것도 좋을거당.
아래 소스를 그냥 복사하도록 하장.
tajaExcer.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="./tajaStyle.css">
<title>E7E 산성비</title>
<script src="./utils.js"></script>
<script src="./words.js"></script>
</head>
<body>
<div id="container">
<div class="TajaBack" id="tajaBackground">
<div id="ckBox">
회전<input type="checkbox" id="tajaRot" value="merong">
</div>
<div id="ckColor">
색깔<input type="checkbox" id="tajaColor" value="huk">
</div>
</div>
<div class="TajaControl">
<input type=text id="tajaTyping" onkeydown="wordsCheck()">
<input type=button id="tajaStart" value="시작!" autofocus onclick="tajaGoGo()">
</div>
</div>
</body>
</html>
아래 css파일도 그냥 복사해서 같은 폴더에 넣도록 하장(그저 대략 레이아웃용)
tajaStyle.css
#container {
margin:0 auto;
width: 70%;
height: 96vh;
min-width: 1024px;
min-height:768px;
border: 1px solid black;
background-color: gray;
}
.TajaBack {
margin:0 auto;
width: 60%;
height: 90%;
position: relative;
background-color: white;
background-color: gray;
background-image: url("../images/roze09.jpg");
background-repeat: no-repeat;
background-size: 100% 100%;
border: 2px solid black;
overflow: hidden;
}
.TajaControl {
margin:0 auto;
width: 60%;
height:9.5%;
background-color: gold;
border: 1px solid black;
}
#tajaTyping {
width:75%;
height:90%;
line-height: 95%;
background-color: black;
color:yellow;
font-size: 1.3em;
border:3px solid white;
text-align: center;
}
#tajaStart {
width:21%;
height:90%;
color: blue;
line-height: 95%;
font-size:1.8em;
background-color: magenta;
color:white;
border:3px solid white;
}
.txtBox {
display:block;
position:absolute;
left:30px;top:-30px;
width:100px;height:22px;
line-height:22px;
background-color:yellow;
font-size: 1.1em;
font-weight: bold;
text-align:center;
border:2px solid black;
}
#ckBox {
position: absolute;
left:85%;
top:95%;
z-index: 100;
color:orange;
font-weight: bolder;
transform: scale(2);
}
#ckColor {
position: absolute;
left:65%;
top:95%;
z-index: 100;
color:orange;
font-weight: bolder;
transform: scale(2);
}
이제 tajaExcer.html을 웹서버 위에서 실행해 보면 레이아웃 형태가 들어올거시당.
이제 자스 코드를 채우도록 하장. 아래 utils.js는 그냥 랜덤넘버와 랜덤넘버를 이용해서
css용 rgba 색깔 지정 문자열을 맹글어 주는 함수가 들어있당. 누느로 한번 훑고
같은 폴더에 역시 복사 붙여넣기를 하도록 하장.(괘니 분리해 보았당.)
utils.js
/*
특정범위의 정수값 리턴
*/
function f_ranNum(p_startNum,p_endNum){
var v_gap = p_endNum - p_startNum;
return p_startNum + Math.round(Math.random()*v_gap);
}
/*
랜덤 칼라값 리턴
*/
function f_ranColor(){
let v_red = f_ranNum(0,255);
let v_green = f_ranNum(0,255);
let v_blue = f_ranNum(0,255);
let v_alpha = "0."+ f_ranNum(0,9);
if(v_alpha <=0) v_alpha =1; // 0은 완전투명 -> 불투명으로 바꿔줌
return `rgba(${v_red},${v_green},${v_blue},${v_alpha})`;
}
드뎌 핵심 코드당당. (v_jsStudy 배열은 키워드만 모은 배열이당);
대부분의 숫자값은 그저 모양이나 움직임간격등을 위한 대략의 튜닝값이니 쪼메 무시하장
코드에 모두 주석을 다랐지만, 핵심만 한번 더 설명하면
1. 시작할 때 배열의 키워드 단어들을 div태그에 담아서 천정 밖에 숨겨둔당.
2. 시작을 누르면 wordsManufacture 함수와 wordsMove함수가 동작하는데
onDiv 배열이 두 함수의 연결고리로 동작하게 된당.
wordsManufacture함수는 타이머를 이용 주기적으로 랜덤하게 키워드를 골라와서
onDiv배열에 담고, wordsMove함수는 onDiv배열에 담긴 키워드만 화면에 보여주고
역시 타이머를 이용하여 주기적으로 랜덤한 속도로 아래로 떨어뜨리게 된당.
3. 엔터키 치면, 사용자가 입력한 문자열이 onDiv 배열에 있는지 체크하여
onDiv에서 제거하고, 천정밖으로 다시 보낸당
4. 바닥까지 그냥 내려간 키워드도 다시 천정밖으로 보낸당.
아래 words.js도 복사 붙여넣기로 같은 폴더에 넣고 tajaExcer.html을 실행하장.
words.js
/*
자바스크립트 & CSS & HTML 자주쓰는 키워드들
*/
const v_jsStudy = [
//?
"use strict","var","Number","String","Boolean","Array []","Object {}","true","false","null","NaN",
"undefined","infinite","JSON","case","for","while","switch","continue","break","function","return",
"if elseif else","&& and","|| or","typeof","instanceof","new","==","===","trim","indexOf","replace",
"split","substr","push","splice","sort","this","call","apply","bind","stringify","parse","regexp //",
"test","$1 $2","i++","++i", "i +=3","Math","random","ceil","floor","sin","cos","round","FileReader",
"prototype","readAsDataURL","readAsText","result",
//?
"window","location","history","navigator","screen","userAgent","opener","open","close","frames",
"self","top","innerWidth","innerHeight","href","reload","replace","setTimeout","clearTimeout",
//?
"document","write","getElementById","getElementsByName","getElementsByTagName","getElementsByClassName",
"querySelector","querySelectorAll","styleSheets","cssRules","cssText","style","selectorText","innerHTML",
"children","parentElement","createElement","setAttribute","getAttribute","appendChild",
//?
"onload","onclick","onchange","onmouseover","onmousemove","ondragover","ondrop","ondragstart","onunload",
"onkeydown","clientX","clientY","key","onmousedown","onmouseup","onfocus","onblur","stopPropagation",
"preventDefault","addEventListener","dataTransfer",
//?
"display","position","z-index","overflow","transform","visibility","background","margin","padding","border",
"opacity","block","inline","static","relative","absolute","hidden","auto","visible","width","height","auto",
"text-align","line-height","rotate","translate","skew","scale","id #","class .",
//?
"a","input","img","div","p","h1~h6","pre","span","ul","ol","li","select","option","textarea","form","audio",
"video","canvas","svg","table","tr","td",
//?
"type","name","value","pattern","action","method","required","readonly","disabled","checked","download",
"target","accept","rowspan","colspan","rows","cols","data-",
//?
"button","radio","checkbox","date","color","file","submit","reset"
];
/*
전체 흐름
window.onload -> tajaInit 함수호출
시작 클릭 -> tajaGoGo 함수호출
tajaGoGo -> wordManufacture, wordsMove 함수 호출, 이후 각각 무한 재귀호출
사용자 엔터키 이벤트 -> wordsCheck 함수호출
onDiv 배열이 가장 중요한 역할!
*/
/*
전역변수 선언
movTime : 떨어지는 속도
makeTime : 글자박스 선택 주기(시간)
tajaStart : 시작여부
tajaTyping: 사용자 타이핑 입력 텍스트상자
onDiv : 화면에서 움직이는 div만 담을 배열
*/
const movTime = 800;
const makeTime = 2000;
let tajaStart,tajaTyping,movTimer,makeTimer,tajaRot,tajaColor;
const onDiv = [];
const imgURLs=[
"https://lh3.googleusercontent.com/p/AF1QipORTRgJJGxbL7NW2MctPvCqRHS1xAA0eSq2M9P3=s680-w680-h510",
"https://cdn.pixabay.com/photo/2013/10/04/21/13/woman-190897_1280.jpg",
"https://cdn.pixabay.com/photo/2013/02/09/01/31/charlize-theron-79562_1280.jpg",
"https://cdn.pixabay.com/photo/2023/01/21/15/18/ai-generated-7734358_1280.jpg",
"https://cdn.pixabay.com/photo/2021/12/15/16/04/lady-gaga-6872913_1280.jpg",
"https://cdn.pixabay.com/photo/2015/10/20/16/29/people-998019_1280.jpg",
"https://cdn.pixabay.com/photo/2018/12/25/14/18/mime-3894351_1280.jpg",
"https://cdn.pixabay.com/photo/2023/06/30/09/39/lady-gaga-8098036_1280.jpg",
"https://cdn.pixabay.com/photo/2023/01/21/15/08/ai-generated-7734220_1280.jpg",
"https://cdn.pixabay.com/photo/2019/09/17/06/57/figurine-4482670_1280.jpg",
"https://cdn.pixabay.com/photo/2023/01/03/11/10/geisha-7694154_1280.jpg",
"https://pds.saramin.co.kr/company/logo/201607/12/oa6q54_g0wk-vbc6f6_logo.png",
"https://cdn.pixabay.com/photo/2016/02/16/13/19/street-1203300_1280.jpg"
]
//3초 마다 백그라운드 이미지 바꾸깅, 동영상으로 하면 더 재밌을깡?
function backImgChg(){
tajaBackground.style.backgroundImage = `url(${imgURLs[Math.floor(Math.random()*imgURLs.length)]})`;
setTimeout(backImgChg,3000);
}
/*
v_jsStudy 배열에서 단어를 뽑아 화면에 보이기
*/
function wordsManufacture() {
let wordRanId = Math.round(Math.random() * (v_jsStudy.length - 1));
let wordRanX = Math.round(Math.random() * 500);
let newDiv = document.querySelector(`#word${wordRanId}`);
let wordWidth = newDiv.innerHTML.length * 12; // 글자길이에 맞춰 대략 div 넓이 주기
newDiv.style.width = `${wordWidth}px`;
newDiv.style.left = `${wordRanX}px`;
newDiv.style.display = "block";
onDiv.push(newDiv);
makeTimer=setTimeout(wordsManufacture, makeTime);
}
/*
뽑은 단어를 가진 DIV 움직이기
*/
function wordsMove() {
let v_bottomLimit=parseInt(tajaBackground.getBoundingClientRect().height);
for (let i = 0; i < onDiv.length; i++) {
let speed = Math.round(Math.random() * 20) + 1; // 개별 떨어지는 속도 랜덤
if(!onDiv[i].style.top) {
onDiv[i].style.top="-30px" //이런 경우 잘 디버깅하면 굳!
}
onDiv[i].style.top = (parseInt(onDiv[i].style.top) + speed) + "px";
if(tajaColor.checked){
onDiv[i].style.color = f_ranColor();
onDiv[i].style.backgroundColor = f_ranColor();
}else {
onDiv[i].style.color = "white";
onDiv[i].style.backgroundColor = "black";
}
let randomGak = Math.floor(Math.random()*360);
if(tajaRot.checked){
onDiv[i].style.transform = `rotate(${randomGak}deg)`;
}else {
onDiv[i].style.transform = "rotate(0deg)";
}
if (parseInt(onDiv[i].style.top) > v_bottomLimit) {
// onDiv[i].style.display = "none";
onDiv[i].style.top = "-30px";
onDiv.splice(i,1);
}
}
movTimer=setTimeout(wordsMove, movTime);
}
/*
시작 함수로 글자만드는 함수와 글자 움직임함수 불러줘잉!
*/
let v_isRun = false;
function tajaGoGo() {
if(!v_isRun){
wordsManufacture();
wordsMove();
v_isRun = true;
tajaStart.value="멈춤";
tajaTyping.focus();
return;
}
clearTimeout(movTimer);
clearTimeout(makeTimer);
tajaStart.value="시작";
v_isRun = false;
return;
}
/*
사용자가 글자입력후 엔터키 치면 처리~
*/
function wordsCheck() {
let wordAnswer = tajaTyping.value;
if(event.key == "Enter") {
for (var i = 0; i < onDiv.length; i++) {
if (onDiv[i].innerHTML == wordAnswer) {
onDiv[i].style.display = "none";
onDiv[i].style.top = "-30px"; // 초기치로 되돌림
onDiv.splice(i,1);
}
}
tajaTyping.value = "";
}
}
/*
v_jsStudy 배열 만큼 div 태그 만들고
시작 클릭과, 엔터키 입력 이벤트 함수에 연결
*/
function tajaInit() {
tajaBackground = document.querySelector("#tajaBackground");
tajaTyping = document.querySelector("#tajaTyping");
tajaStart = document.querySelector("#tajaStart");
tajaRot = document.querySelector("#tajaRot");
tajaColor = document.querySelector("#tajaColor");
for (let i = 0; i < v_jsStudy.length; i++) {
let movDiv = document.createElement("div");
movDiv.setAttribute("id",`word${i}`);
movDiv.setAttribute("class","txtBox");
movDiv.innerHTML = v_jsStudy[i];
tajaBackground.appendChild(movDiv);
}
backImgChg();
}
/*
페이지 로딩되면 자동 초기화및 백그라운드이미지 변화(내맘!)
*/
window.onload = tajaInit;
분명 훨씬 더 다양한 재밌는 아이디어들이 마구 솟아날거시당.(시도하고 즐겨랑!)
인생에서 빼는 건 별로 좋은 선택이 아니당. 꼬꾸라지더라도 젊을 때는 달려랑.
나의 경우 화장실 다녀오니 아래 이미지와 같은 충격적 결과를 만났당.
첨 산성비 프로그램을 만들 때가 생각난당.
SF적인 꿈을 꾸며 욜씨미 하려했지만 , 기본기능이 생각보다 쉽게 구현되어
금새 의지와 의욕을 분리수거해서 버리고 말았당.
삶이 쉽지 않은 이유도 마찬가지인 것 같당.
쉬우면 분명 재미가 덜 할 거시다. 쉽지 않음을 통해 도전의지를 얻도록 하장.
가끔 우산없는 사람에게 우산을 씌워주고 싶은 배려의 마음은
당신이 아직 삶을 즐길 이유가 있음을 알려줄거시당.
그대가 알칼리가 아니고 산성이어서 건강을 해칠지라도
그대라는 시에 내리는 그대라는 산성비에 날 널어서 짜고 싶당.~~
https://www.youtube.com/watch?v=lHEOj3d7YS4
대충 이미지 검색 왕창 다운로띵 ajax 2 (0) | 2023.07.17 |
---|---|
대충 이미지 검색 왕창 다운로띵 ajax 1 (2) | 2023.07.16 |
근시안과 노안엔 돋보기를 ... (1) | 2023.07.10 |
사랑(Heart)은 오락가락(Swing) (2) | 2023.07.06 |
볼튕기기로 배우는 인생 (2) | 2023.07.06 |