UIUX _국비과정 0517 | Notion

오늘 하루는 피그마를 다뤄본다.

ringed-tartan-f02.notion.site

 

 

UIUX _국비과정 0520 | Notion

오늘까지 피그마

ringed-tartan-f02.notion.site

 

 

 

에어비엔비 따라 만들기

 

프로토타입과 인터럭션

 

실제 에어비엔비 사이트의 모바일 버전을 따라 만들어보기도 하고,

프로토타입과 인터럭션을 사용해보며 페이지가 넘어가는 방법을 설정해보기도 했다.

근데 이걸로 디자인과 설계를 해놓으면 개발자가 다 자바스크립트로 짜야한다는 거..

이래서 디자이너와 개발자가 싸우는구나 알게된 수업이다

ㅠㅠ 이런걸 배울 수록 자바스크립트를 더 잘해야 하는구나 싶은 생각뿐

실제 해보며 아는 기능이 대부분이고 피그마는 단축키가 핵심인것같다.

그래서.. 피그마 수업부터는 정리한 내용들이 거의 없음..

추가로 내가 피그마에 관심있어하니 강사님이

 

OvenApp.io

Oven(오븐)은 HTML5 기반의 무료 웹/앱 프로토타이핑 툴입니다. (카카오 제공)

ovenapp.io

 

이런 것도 알려주셨다. 카카오에서 만든 오븐이라는 틀.

피그마와 비슷한데 기능이 훨씬 적다고 한다. 그래도 카카오에서 만들었으니 다음 개발자들은 이걸 쓰는듯..?(아닐 수 있음)

배너 안에서 풍선이 떨어지는 효과를 자바스크립트를 통해 만들어보자.

 

배너 닫기 부분 구현 전까지.

풍선이 랜덤으로 내려오는 효과 구현

// 배너
// 이미지 10개 
// 사용할 예정
// 사운드를 삽입할 수도 있다. 이번에는 생략

// 필요한 부분들을 객체화
let banner = document.getElementById('banner');
let img = banner.getElementsByTagName('img'); // 베열형식, 동일한 태그를 배열로 가지고 온다
let toggle = document.getElementById('toggle');

// 배너의 높이 가지고 오기
// 높이에 따라 동작이 달라진다
// css 속성값을 가지고 올 수 있다
let banner_height = getComputedStyle(banner).height;

// 풍선을 객체형태로 만들어 관리해주기
// 여러가지 정보를 하나로 묶어서 실제 풍선이 움직일 때 동작을 해야한다.
// 전역변수
let cast = [];

// 객체생성방식
// 이렇게도 할 수 있지만 이번의 경우엔 다른 방식으로 해보겠다.
// let ballInfo = {
//     x : x,
//     y : y,
//     size : size,
//     angle : angle,
//     speed : speed
// }

// 풍선 객체 생성 함수
// num -> 인덱스 번호
function set_balloon(num){
    let x = Math.floor(Math.random() * (500 - 10) + 10); // x축 10 ~ 500
    let y = Math.floor(Math.random() * (400 - 120) + 120); // y축 120 ~ 400
    let size = Math.floor(Math.random() * (200 - 100) + 100); // 크기 범위  100 ~ 200
    let angle = Math.floor(Math.random() * (360 - 0) + 0); // 회전하는 각도 범위 0 ~ 360
    let speed = Math.random() * (2 - 0) + 0; // 속도 0 ~ 2

    cast[num] = { // cast = [{},{},{},{},... {}]
        x : x,
        y : -y, // y축은 -일 수록 올라가고, +일 수록 내려간다
        size : size,
        angle : angle,
        speed : speed
    }
}

// 각각의 풍선 초기화 함수
function ball_init() {
    for (let i = 0; i < img.length; i++) {
        // 풍선 객체들을의 속성 초기화
        set_balloon(i)
        img[i].style.left= '-9999px'; // 풍선의 최초 x좌표  Object.style.css 속성 = "값을 줄 땐 문자열처리"
        img[i].style.top = '-9999px'; // 풍선의 최초 y좌표
    }
}

function animate_balloon() {
    for (let i = 0; i < img.length; i++) {
        // 풍선 속성 변경
        img[i].style.left = cast[i].x + 'px'; // css 속성 문법에 맞춰 단위를 붙여야 함. 
        img[i].style.top = cast[i].y + 'px';
        img[i].style.transform = 'rotate(' + cast[i].angle + 'deg)'; // 회전각 초기화

        if (cast[i].y < parseInt(banner_height)){
            // 풍선이 화면에 보임
            // 1 ~ 3 하나의 풍선이 가지는 속도
            cast[i].y += 1 + cast[i].speed;
            cast[i].angle += cast[i].speed; 
        }else{
            // 풍선이 배너 영역을 지나서 화면 밖으로 나갔을 때
            set_balloon(i);
        }
    }
}

ball_init();

// (호출해서 실행하고 싶은 함수, 시간)
setInterval(function(){
    animate_balloon();
}, 1000 / 30);

 

배너 열기, 닫기 기능 추가

toggle.onclick = function(){
    // 속성(id, class 등) 중에 class 가 있으면 읽어와라
    let attr = banner.getAttribute('class'); // class 속성이 가지고 있는 값을 읽어온다
    if (attr === 'active'){
        // 베너닫기
        banner.removeAttribute('class'); // 해당 속성을 제거
        toggle.innerHTML = '배너 열기';
        return false; // a 태그에 링크속성 제거
    }else {
        banner.setAttribute('class', 'active'); // 해당 속성을 추가
        toggle.innerHTML = '배너 닫기';
        return false;
    }
};

 

 

브라우저 콘솔창을 열어보면 배너를 열고 닫았을 때 active 속성이 사라지고, 추가되며 글씨가 바뀌는 것을 알 수 있다.

 

 

전체 코드 :

// 배너
// 이미지 10개 
// 사용할 예정
// 사운드를 삽입할 수도 있다. 이번에는 생략

// 필요한 부분들을 객체화
let banner = document.getElementById('banner');
let img = banner.getElementsByTagName('img'); // 베열형식, 동일한 태그를 배열로 가지고 온다
let toggle = document.getElementById('toggle');

// 배너의 높이 가지고 오기
// 높이에 따라 동작이 달라진다
// css 속성값을 가지고 올 수 있다
let banner_height = getComputedStyle(banner).height;

// 풍선을 객체형태로 만들어 관리해주기
// 여러가지 정보를 하나로 묶어서 실제 풍선이 움직일 때 동작을 해야한다.
// 전역변수
let cast = [];

// 객체생성방식
// 이렇게도 할 수 있지만 이번의 경우엔 다른 방식으로 해보겠다.
// let ballInfo = {
//     x : x,
//     y : y,
//     size : size,
//     angle : angle,
//     speed : speed
// }

// 풍선 객체 생성 함수
// num -> 인덱스 번호
function set_balloon(num){
    let x = Math.floor(Math.random() * (500 - 10) + 10); // x축 10 ~ 500
    let y = Math.floor(Math.random() * (400 - 120) + 120); // y축 120 ~ 400
    let size = Math.floor(Math.random() * (200 - 100) + 100); // 크기 범위  100 ~ 200
    let angle = Math.floor(Math.random() * (360 - 0) + 0); // 회전하는 각도 범위 0 ~ 360
    let speed = Math.random() * (2 - 0) + 0; // 속도 0 ~ 2

    cast[num] = { // cast = [{},{},{},{},... {}]
        x : x,
        y : -y, // y축은 -일 수록 올라가고, +일 수록 내려간다
        size : size,
        angle : angle,
        speed : speed
    }
}

// 각각의 풍선 초기화 함수
function ball_init() {
    for (let i = 0; i < img.length; i++) {
        // 풍선 객체들의 속성 초기화
        set_balloon(i)
        img[i].style.left= '-9999px'; // 풍선의 최초 x좌표  Object.style.css 속성 = "값을 줄 땐 문자열처리"
        img[i].style.top = '-9999px'; // 풍선의 최초 y좌표
    }
}

function animate_balloon() {
    for (let i = 0; i < img.length; i++) {
        // 풍선 속성 변경
        img[i].style.left = cast[i].x + 'px'; // css 속성 문법에 맞춰 단위를 붙여야 함. 
        img[i].style.top = cast[i].y + 'px';
        img[i].style.transform = 'rotate(' + cast[i].angle + 'deg)'; // 회전각 초기화

        if (cast[i].y < parseInt(banner_height)){
            // 풍선이 화면에 보임
            // 1 ~ 3 하나의 풍선이 가지는 속도
            cast[i].y += 1 + cast[i].speed;
            cast[i].angle += cast[i].speed; 
        }else{
            // 풍선이 배너 영역을 지나서 화면 밖으로 나갔을 때
            set_balloon(i);
        }
    }
}

ball_init();

// (호출해서 실행하고 싶은 함수, 시간)
setInterval(function(){
    animate_balloon();
}, 1000 / 30);

toggle.onclick = function(){
    // 속성(id, class 등) 중에 class 가 있으면 읽어와라
    let attr = banner.getAttribute('class'); // class 속성이 가지고 있는 값을 읽어온다
    if (attr === 'active'){
        // 베너닫기
        banner.removeAttribute('class'); // 해당 속성을 제거
        toggle.innerHTML = '배너 열기';
        return false; // a 태그에 링크속성 제거
    }else {
        banner.setAttribute('class', 'active'); // 해당 속성을 추가
        toggle.innerHTML = '배너 닫기';
        return false;
    }
};

 

처음에 배울때는 같은 코드를 안보고 칠 수 있을 정도로 계속 쳐보는 것이 더 좋다.

그러면서 이해하는 것.

강사님이 주는 코드는 최대한 분석해 놓을 것.

 

 

이번에는 제이쿼리로 위 코드를 바꿔 볼 것이다.

 

제이쿼리 ver.

let $banner = $('#banner');
let $img = $banner.find('img');
let $toggle = $('#toggle');

let $banner_height = $banner.css('height');

let cast = [];

function set_balloon(num){
    let x = Math.floor(Math.random() * (500 - 10) + 10); // x축 10 ~ 500
    let y = Math.floor(Math.random() * (400 - 120) + 120); // y축 120 ~ 400
    let size = Math.floor(Math.random() * (200 - 100) + 100); // 크기 범위  100 ~ 200
    let angle = Math.floor(Math.random() * (360 - 0) + 0); // 회전하는 각도 범위 0 ~ 360
    let speed = Math.random() * (2 - 0) + 0; // 속도 0 ~ 2

    cast[num] = { // cast = [{},{},{},{},... {}]
        x : x,
        y : -y, // y축은 -일 수록 올라가고, +일 수록 내려간다
        size : size,
        angle : angle,
        speed : speed
    };
}

function ball_init(){
    // each 함수 사용 
    // 배열 $img 을 가지고 와 하나씩 확인 
    $img.each(function(i){
        set_balloon(i);
        $img.eq(i)
            .css('left','-9999px')
            .css('top', '-9999px')
    });
}

function animate_balloon(){
    $img.each(function(i){
        $img.eq(i)
        .css('left', cast[i].x + 'px')
        .css('top',cast[i].y + 'px')
        .css('transform', 'rotate(' + cast[i].angle + 'deg)');

        if (cast[i].y < parseInt($banner_height)){
            // 풍선이 화면에 보임
            // 1 ~ 3 하나의 풍선이 가지는 속도
            cast[i].y += 1 + cast[i].speed;
            cast[i].angle += cast[i].speed; 
        }else{
            // 풍선이 배너 영역을 지나서 화면 밖으로 나갔을 때
            set_balloon(i);
        }
    });
}

ball_init();

// (호출해서 실행하고 싶은 함수, 시간)
setInterval(function(){
    animate_balloon();
}, 1000 / 30);

 

문법을 익히기 위해 노력할 것.

스크립트에서 해당 메소드의 이름, 제이쿼리에서 메소드의 이름 이해

 

 

이걸 다 할 줄 알아야 진정한 기술탑재 프론트엔드 엔지니어

 

다음에 볼 시험) 자바스크립트로 프로그램짜기, 그걸 제이쿼리로 바꾸기

해 볼 것 : 계산기 자바스크립트 코드를 제이쿼리 방식으로 바꾸기

 

계산기 코드 :

// 변수 선언

//document.cal.result // 폼태그를 접근하는 방식 -> 여기서는 아이디나 클래스가 하나하나 선언되어있지 않아 사용 불가
let inp = document.forms['cal'];
let input = inp.getElementsByTagName('input'); // 배열형식으로 값을 가지고 온다
let cls_btn = document.getElementsByClassName('cls_btn')[0]; // 배열형식
let result_btn = document.getElementsByClassName('result_btn')[0]; //배열형식


// 버튼 3그룹 
// 1. clear
// 2. 숫자버튼
// 3. 결과버튼

// 계산기 초기화(clear)
function clr(){
  inp['result'].value = 0; // 결과창

}


// 계산기 입력 처리 함수
 function calc(value){
 // 입력이 들어가면 0을 지움
  if (inp['result'].value == 0){
    inp['result'].value = '';
  }

  // 입력값을 결과창에 출력
  inp['result'].value += value;
}
  

// 계산 결과 처리 함수
function my_result(){
 
  let result = inp['result'].value;
  let cal = eval(result)

  //결과창에 표시
  inp['result'].value = cal;
}


// 이벤트 핸들러
// -------------------------------------------------------------------
// 숫자 및 사칙연산 버튼
for(var i = 0; i < input.length;i++){

  // 숫자와 사칙 연산자만 입력 처리
 if(input[i].value != '=' && input[i].value != 'clear'){
  input[i].onclick = function(){
    calc(this.value); // 숫자의 속성값 의미
  };
 }

} // end for


// 초기화  버튼
cls_btn.onclick = function(){
  clr();
}

// 결과 버튼
result_btn.onclick = function(){
  my_result();
}

 

구현화면 :

계산이 잘 된다.

하지만 알아보니 eval 함수는 보안 이슈가 있어서 될 수 있으면 쓰지 말아야 한다고.

스스로 풀어볼땐 eval 함수를 쓰지 않는 방법으로 풀어야겠다.

작성 : 2024. 5. 14. 17:12

 

오늘은 '자바스크립트를 이용한 cbt (전자문제풀이기) 프로그래밍'으로 그동안 배운 css와 자바스크립트의 문법을 정리했다.

'자바스크립트는 백엔드든 프론트든 아주 유용하니 꼭 공부를 많이 해둘 것' 이라는 강사님의 조언도 계속되었다.

화면구현할때

  1. 요소구성
  2. css 디자인
  3. 스크립트 적용

위 순서로 진행되야 한다! 

 

이렇게 css 를 하나하나 정리하는 과정이 정말 필요했다.

 

 

오늘 만들어 볼 것은 이런 틀을 가진 html, css 를 자바스크립트를 이용해 문제를 내보내고, 바꾸고, 점수를 매기며 동적으로 변화시키는 것.

-> css 를 정렬할 때는 그리드, 플렉스, 마진 등 하나를 정해서 만들어야 혼선이 생기지 않는다.

-> 자바스크립트에서 이벤트 주는 방식을 정리할 것.

-> 객체에 대한 이해가 있어야 함.

객체는 속성과 메서드로 되어있다.

- 속성은 특징, 메서드는 행위

- 메서드를 함수형태로 처리하는 것이 ‘기능’

- 뭘 객체로 봐야하는지 알아야 한다.

- 정답은 없음

완성된 코드와 결과 화면 :

// 메소드를 만들 때 1 메소드, 1 기능 
// 너무 많은 메소드를 넣으면 유지보수가 어려움

// 문제 객체
// 세 개를 값으로 가지는 객체 생성
function Question(text, choice, answer){
    this.text = text;
    this.choice = choice;
    this.answer = answer;
}

// 퀴즈 정보 객체
// 문제를 푸는 동안 점수 누적, 몇 문제 남았는지, 진행상황 등 정보 관리를 위한 객체
// 점수, 질문, 질문순서, 정답 확인

function Quiz(questions) {
    this.score = 0; // 점수
    this.questions = questions; // 질문
    this.questionIndex = 0; // 질문 순서
    
    // 정답 확인 기능
    // 프로토타입으로 빼둔다.
    // 메모리 한 번만 할당, 동일한 타입의 객체가 공유해서 사용할 수 있도록 한다. -> 자바의 static과 같은 의미
    // 공유 -> 메모리 효율성이 높아진다
}

// 정답 확인 메소드
Quiz.prototype.correctAnswer = function(answer) {
    // 사용자의 답과 해당 문제의 답 비교
    return answer == this.questions[this.questionIndex].answer;
}

// 문제 데이터
// 배열로 만들어 값을 활용 -> text, choice, answer
// 배열은 세미콜론을 찍으면 안된다
let questions = [
    new Question('다음 중 최초의 사용 웹 브라우저는?', ['모자이크', '인터넷 익스플로어', '구글 크롬', '넷스케이프 네비게이터'], '넷스케이프 네비게이터'),
    new Question('웹 브라우저에서 스타일을 작성하는 언어는?', ['HTML', 'jQuery', 'CSS', 'XML'], 'CSS'),
    new Question('명령어 기반의 인터페이스를 의미하는 용어는?', ['GUI', 'CLI', 'HUD', 'SI'], 'CLI'),
    new Question('css 속성 중 글자의 굵기를 변경하는 속성은?', ['font-size', 'font-style', 'font-weight', 'font-variant'], 'font-weight')
];

// 퀴즈 객체 생성
let quiz = new Quiz(questions);

// 문제 출력 함수
// 문제를 계속 변경할 수 있어야 한다.
function update_quiz(){
    let question = document.getElementById('question');
    let choice = document.querySelectorAll('.btn'); // 배열 형식
    let idx = quiz.questionIndex + 1; // 문제의 번호

    // 문제 출력
    question.innerHTML = '문제' + idx + ' ) ' + quiz.questions[quiz.questionIndex].text;

    // 선택항목 출력
    for(let i = 0; i < 4; i++) {
        choice[i].innerHTML = quiz.questions[quiz.questionIndex].choice[i];
    }

    progress();
}

// 문제 진행 정보 표시(현재 문제 번호/총 문제수)
function progress(){
    let progress = document.getElementById('progress');
    progress.innerHTML = '문제 ' + (quiz.questionIndex + 1) + ' / ' + quiz.questions.length;
}

// 결과 표시
function result(){
    let quiz_div = document.getElementById('quiz');

    let per = parseInt(quiz.score*100) / quiz.questions.length;

    let txt = '<h1>결과</h1>' + '<h2 id="score"> 당신의 점수 : ' + quiz.score + '/' +
                quiz.questions.length + '<br><br>' + per + '점</h2>';

    quiz_div.innerHTML = txt; // 결과 출력

    if (per < 60){
        txt += '<h2 style = "color:red"> 좀 더 분발하세요 </h2>'
        quiz_div.innerHTML = txt;
    } else if (per >= 60 && per < 80){
        txt += '<h2 style = "color:red"> 무난한 점수입니다. </h2>'
        quiz_div.innerHTML = txt;
    } else if (per >= 80){
        txt += '<h2 style = "color:red"> 훌륭합니다. </h2>'
        quiz_div.innerHTML = txt;
    }
}

//-----------------------------------------------
let btn = document.querySelectorAll('.btn'); // 배열 형식

// 입력 및 정답 확인 함수
function checkAnswer(i) {
    btn[i].addEventListener('click',function(){
        let answer = btn[i].innerText;

        if(quiz.correctAnswer(answer)) {
            alert("정답입니다.");
            // 문제를 맞춘 갯수를 세서 *25로 점수를 환산할 예정
            quiz.score++;
        } else {
            alert("오답입니다.");
        }

        // 다음 문제로 진행 처리
        if (quiz.questionIndex < quiz.questions.length-1){
            quiz.questionIndex++;
            update_quiz();
        }else{
            result();
        }
            
    });
}

// 4개의 버튼 이벤트 처리
for (let i = 0; i < btn.length; i++) {
    checkAnswer(i)
}

update_quiz();

 

 

 

기본적인 코드이니 이 코드를 잘 이해하고 이해가 안되면 따라쳐서 어느정도 외워둘 것.

0510에 조별로 사이트 하나를 정해서 스토리보드를 짜고 화면을 구현해보라는 미션을 받았다.

완벽하진 않지만.. 80% 정도의 퀄리티로 완성이 되었다!

초반엔 맥북에어 기준 이런 모양이지만,, 다른 모니터로 보면 footer가 깨졌다.

-> 그런데 제출 후 다시 해서 해결했다ㅋㅋ 제출 후라는게 어이없지만 어쨌든 해결해서 속이 시원하다!

해결방법은 너무나도 당연하게 footer 에 width: 100%; 를 주면 되는거였음;

footer가 아니라 난 자꾸 footerbg에 엉뚱하게 값을 늘리고 줄이고 있었다.

 

근데 문제는.. 

 

이렇게 최소 사이즈를 안정해서인지 비율을 줄일때 문제가 나타난다.

그래서 80% 퀄이라는 것..

자바스크립트를 전혀 안했기 때문에 사실 기능하게 만드는 것에 있어서는 80%도 한참 못미치지만..

일단 css와 html만으로 똑같이(는 아니더라도 최대한 비슷하게) 만들었으니 스스로 칭찬하자는 의미의 '80%'이기도 하다.

 

 

css

    <style>

        * {
            box-sizing: border-box;
        }

        div {
            display: block;
            unicode-bidi: isolate;
        }

        body {
            font-family: "맑은 고딕", Verdana, Tahoma;
            font-size: 10pt;
            line-height: 160%;
            color: #000;
            padding: 0;
            margin: 0;
            background-color: #FBFBFB;
        }

        .container {
            width: 925px;
            margin: 0 auto;
            padding: 0;
        }

        #logo {
            position: relative;
            max-width: 1020px;
            min-width: 320px;
            height: 70px;
            margin: 0 auto;
        }

        .navigation {
            background-color: rgb(254, 34, 89);
        }

        #logoYogiyo {
            background-size: 90px;
            overflow: hidden;
            margin: 20px 10px;
        }

        .items mask {
            margin-top: 20px;
        }

        .item {
            border-color: rgb(122, 121, 121);
            background-color: #fff;
            float: left;
            position: relative;
            padding: 0;
            border: 1px solid #dddd;
            overflow: hidden;
            padding-left: 10px;
            margin: 5px;
            /* 이미지 아래 여백 줄이기!!!!!!의 완벽한 답을 찾음 */
            line-height: 0;
        }

        .item image {
            margin-left: auto;
            margin-right: auto;
            border: 0;
            max-width: 100%;
            /* height: auto; */
            /* vertical-align: bottom; */

        }

        .search {
            padding: 125px 100px 70px;
            background-image: url("./images/bg-top.png");
            background-repeat: no-repeat;
            background-position: center;
        }

        .search .ico-loc {
            background: #fff url("images/sprite-icon.png") no-repeat 0 0;
            background-size: 400px;
            width: 40px;
            height: 40px;
            border-radius: 4px;
            border: none;
        }

        .search .form-control {
            border: none;
            border-right: 0;
            border-radius: 4px;
            border-top-right-radius: 0;
            border-bottom-right-radius: 0;
            height: 40px;
            width: 300px;
            box-shadow: inset 0 0 0 rgba(0, 0, 0, 0);
            transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
        }

        .category-title {
            position: absolute;
            top: 7%;
            left: 7%;
            color: #333;
            font-size: 110%;
            font-weight: bold;
        }

        #cart .btn-login {
            position: relative;
            top: 0;
            left: 0;
            margin: 15px 0 7px;
            width: 150px;
            max-height: 40px;
            padding: 7px 0;
            text-align: center;
            font-size: 18px;
            border-radius: 5px;
            background: #fa0050;
            border: 1px solid #ea7266;
            color: #fff;
        }

        #cart .btn-warning {
            margin: 15px 10px 7px 5px;
            width: 130px;
            max-height: 40px;
            padding: 7px 0;
            font-size: 18px;
            border-radius: 5px;
            border-color: #ff8a00;
            background: #ff8a00;
            color: #fff;
        }

        #cart {
            margin-top: 5px;
            margin-right: 10px;
            float: right;
        }

        .cancel {
            height: 40px;
            width: 30px;
            border: none;
            margin-left: -5px;
            color: #fa0050;
            background-color: #fff;
        }

        #whereAddress {
            background: #ff8a00;
            height: 40px;
            width: 60px;
            border: none;
            color: #fff;
            border-radius: 5px;
            border-top-left-radius: 0;
            border-bottom-left-radius: 0;
            margin-left: -5px;

        }

        .input {
            position: relative;
            border-collapse: separate;
            text-align: center;
        }

        #wrapper {
            height: auto;
            min-height: 100%;
            padding-bottom: 400px;
            position: relative;
        }

        footer {
            background: #FBFBFB;
            padding-bottom: 65px;
            font-size: 12px;
            color: #999;
            height: 400px;
            position: absolute;
            transform: translateY(120%);
            border-top: 1px solid #e4e4e4;
            width: 100%;
        }

        .footermenu {
            /* width: 1600px; */
            background: #FBFBFB;
            border-top: 1px solid #d9d9d9;
            border-bottom: 1px solid #d9d9d9;
        }

        .footermenu ul {
            list-style-type: none;
            max-width: 1020px;
            margin: 0 auto;
            padding-left: 0;
            overflow: hidden;
            padding: 15px 0 13px;
        }

        .footermenu ul li {
            display: inline;
            margin: 20px;
        }

        .footermenu li a span {
            display: inline-block;
            width: 16px;
            height: 16px;
            margin: -1px 5px 0 0;
            vertical-align: middle;
        }

        .footermenu li a {
            float: right;
            margin-right: 20px;
        }

        a #facebook {
            background: url("images/img-footer1.png") no-repeat 0 -70px;
        }

        a #blog {
            background: url("images/img-footer1.png") no-repeat -16px -70px;
        }

        .company-logo a {
            display: block;
            background: url("images/img-footer1.png") no-repeat;
            width: 70px;
            height: 29px;
            text-indent: -999em;
            overflow: hidden;
            margin: 32px 45px 0;
            float: left;

        }

        .address {
            max-width: 1020px;
            display: block;
            margin-block-start: 2em;
            margin-block-end: 1em;
            margin-inline-start: 50px;
            margin-inline-end: 50px;
            /* 엄격하게 정렬, 정확한 이해를 위해 좀 더 찾아볼 예정.. */
            unicode-bidi: isolate;
        }

        .service-info {
            margin: 30px 150px;
        }

        .service-info .img {
            display: inline-block;
            width: 38px;
            height: 38px;
            margin: 0 5px 0 10px;
            vertical-align: middle;
            float: left;
        }

        .service-info .text {
            display: inline-block;
            vertical-align: baseline;
            float: left;
        }

        .service .img {
            background: url("images/img-footer1.png") no-repeat 0 -30px;
        }

        .review .img {
            background: url("images/img-footer1.png") no-repeat -38px -30px;
        }

        .call {
            font-size: 18px;
            text-align: center;
        }

        .callcenter {
            text-align: center;
            vertical-align: middle;
        }

        .copyright {
            margin: 5px 160px;
        }

        .all-footer {
            margin-left: 130px;
        }
    </style>

html

    <body>

        <header>
            <div class="navigation">
                <div id="logo">
                    <img src="./images/logo-yogiyo.png" width="90" height="38" id="logoYogiyo">
                    <a id="cart">
                        <button type="button" id="topMenu" value="rogin" class="btn-login">로그인</button>
                        <button type="button" id="orderPad" class="btn-warning">주문표(0)</button>
                    </a>
                </div>
            </div>
            <nav>

                <div class="search">
                    <div class="input">
                        <button class="ico-loc">&nbsp;</button>
                        <input type="search" class="form-control" placeholder=" 건물명,도로명,지번으로 검색하세요.">
                        <span id="button_search_address" class="input_btn">
                            <button class="cancel">X</span></button>
                        <button id="whereAddress">검색</button>
                    </span>
                </div>
            </div>
        </nav>
    </header>

    <div class="container">

        <div id="wrapper">

            <div id="page_center">
                <div class="items mask">
                    <div class="item">
                        <p class="category-title">전체보기</p>
                        <img src="./images/category-01.png" width="200" height="200">
                    </div>
                    <div class="item">
                        <p class="category-title">1인분 주문</p>
                        <img src="./images/category-onedish.png" width="200" height="200">
                    </div>
                    <div class="item">
                        <p class="category-title">프랜차이즈</p>
                        <img src="./images/category-10.png" width="200" height="200">
                    </div>
                    <div class="item">
                        <p class="category-title">치킨</p>
                        <img src="./images/category-02.png" width="200" height="200">
                    </div>
                    <div class="item">
                        <p class="category-title">피자/양식</p>
                        <img src="./images/category-03.png" width="200" height="200">
                    </div>
                    <div class="item">
                        <p class="category-title">중국집</p>
                        <img src="./images/category-04.png" width="200" height="200">
                    </div>
                    <div class="item">
                        <p class="category-title">한식</p>
                        <img src="./images/category-05.png" width="200" height="200">
                    </div>
                    <div class="item">
                        <p class="category-title">일식/돈까스</p>
                        <img src="./images/category-06.png" width="200" height="200">
                    </div>
                    <div class="item">
                        <p class="category-title">족발/보쌈</p>
                        <img src="./images/category-07.png" width="200" height="200">
                    </div>
                    <div class="item">
                        <p class="category-title">야식</p>
                        <img src="./images/category-08.png" width="200" height="200">
                    </div>
                    <div class="item">
                        <p class="category-title">분식</p>
                        <img src="./images/category-09.png" width="200" height="200">
                    </div>
                    <div class="item">
                        <p class="category-title">카페/디저트</p>
                        <img src="./images/category-11.png" width="200" height="200">
                    </div>
                    <div class="item">
                        <p class="category-title">편의점/마트</p>
                        <img src="./images/category-convenience-store.png" width="200" height="200">
                    </div>
                </div>
            </div>
        </div>

    </div>

    <footer>
        <div class="footerbg">
            <div class="footermenu">
                <ul>
                    <li>이용약관</li>
                    <li>개인정보처리방침</li>
                    <li>포인트정책</li>
                    <li>회사소개</li>
                    <li>요기요사장님</li>
                    <li>입점문의</li>
                    <li>공지사항</li>
                    <li>
                        <a
                            href="https://www.facebook.com/Yogiyokorea/"
                            class="facebook"
                            rel="noopener noreferrer"
                            target="_blank">
                            <span id="facebook"></span>페이스북</a>
                        <a
                            href="https://blog.naver.com/rgpkorea"
                            class="blog"
                            rel="noopener noreferrer"
                            target="_blank">
                            <span id="blog"></span>블로그</a>
                    </li>
                </ul>
            </div>
        </div>
        <div class="all-footer">
            <div class="address">
                <div class="company-info">
                    <div class="company-logo">
                        <a href="#">요기요</a>
                    </div>
                    <strong>주식회사 위대한 상상</strong>
                    <p>
                        서울시 서초구 서초대로38길 12 마제스타시티 타워2 17층 | 대표이사 : 전준희 | 사업자등록번호:211-88-68802
                        <br>
                        개인정보담당자 : privacy@yogiyo.co.kr | 제휴문의 : partnership@yogiyo.co.kr | 고객만족센터 :
                        support@yogiyo.co.kr | 호스팅 제공자: 카페24 주식회사</p>
                </div>

                <div class="service-info">
                    <div class="service">
                        <span class="img"></span>
                        <span class="text">요기요<br>안심센터</span>
                    </div>
                    <div class="review">
                        <span class="img"></span>
                        <span class="text">요기요 100%<br>클린리뷰</span>
                    </div>
                    <p class="callcenter">
                        <strong class="call">고객만족센터 1661-5270 (유료)</strong>
                        24시간, 연중무휴</p>
                </div>
                <br>
                <p class="copyright">주식회사 위대한상상은 통신판매중개자이며 통신판매의 당사자가 아닙니다. 따라서 상품/ 거래정보 및 거래와
                    관련하여 요기요에 등록된 판매자의 고의 또는 과실로 소비자에게 발생하는 손해에 대해 주식회사 위대한상상은 책임을 지지 않습니다. 상품 및 거래에
                    관하여 보다 정확한 정보는 해당 판매자에게 직접 확인하여 주시기 바랍니다. Copyright YOGIYO. All Rights Reserved.</p>
            </div>
        </div>
    </footer>
</body>

 

시련과 고난의 코드다.

그냥 무작정 따라한것도 아니고 내가 아는 것을 여기저기 끼워맞추다보니 이렇게 됐다.

이게 정리가 부족한 탓인 것 같다..!

css의 각 기능이 화면에서 어떤 작용을 하는지 정리를 좀 해야할 것 같다.

 

 

이날의 글이 없었던 이유는 종일 UIUX 화면설계 시험을 봤기 때문!

작성 : 2024. 5. 10.

 

오늘은 조을 나눠 종일 팀플을 했다.

오전에 잠깐 스토리보드를 마무리하고,,

이게 내가 썼던 description 이고

이게 강사님이 알려주신 방향으로 수정한거다.

 

내가 전에 만들다 만 것과 비교해보면 얼마나 홈페이지 동작에 대해 이해가 낮은지 알 수 있다..

조별 과제는 역할분담을 해서 스토리보드를 만드는 것이었다.

1. 한 쇼핑몰 선정, 할 수 있는 수준까지

2. 각자 화면설계 및 스토리보드 설명

3. 스토리보드 2장~3장씩 만들기

4. 하나의 ppt로 만들어 공유

5. 그 중 한 페이지를 html로 만들기 각자 한 장 화면 구현

오늘 하루의 과제. → 무리하지 말것

우리는 요기요를 구현해보기로 했다. 온라인숍은 따로 없고 모바일 버전만 있었지만 그래서인지 가장 간단해보였다. (아니었음;)

 

 

 

 

작성 : 2024. 5. 9.

 

자소서를 써야함.. 국비지원 수업을 20%쯤 진행하고 나니 우리학원에선 자소서를 쓰라고 한다.


 

자소서를 쓰기에 앞서 원하는 기업들을 쭉 살펴봤다.

원래는 어떤 기업을 가고 싶은지 살펴봤는데 어떤 개발을 하고 싶은지를 더 생각해봐야 하는 것 같다!

프론트엔드와 웹퍼블리셔 일이 나와 잘 맞을 거라 생각했는데 데이터분석을 이용한 인공지능쪽도 관심이 많이 간다.. 전에 일하던 곳에서 자폐스펙트럼 아이들을 보며 자폐스펙트럼어린이들의 사고방식이 인공지능이 만들어진 원리와 많이 비슷하다는 것을 느끼고 부터는 인공지능에 관심이 많이 생겼다..

관심분야가 넓다보니 뭘 배우고 파고 들어야 할지 고민이 많이 되는데

강사님의 조언은 그래도 언어는 선택해서 파고, 지금 그걸 고민하기 보단 얇고 넓게 프레임워크나 언어를 많이 접해보라는 것이었다!

강사님이 지금 하는 고민의 80%는 쓸모가 없다고ㅎㅎ 지금은 그냥 무조건 많이 열심히 공부하라고 하신다.

자바는 그냥 어떤 언어든 기본이고, 자바스크립트는 많이 알 수록 좋고 프론트에 관심이 있으면 뷰와 리액트를 더 공부해보라고 하셨다. 또, 수업에서는 자바와 스프링을 기본으로 가지고 가니 그 부분에 집중하면 좋을 거라고도 하셨다. 내가 할 수 있을 것 같은건 프론트인데 뭔가 이 분야에서 계속 오래 일한다면 파고 싶은건 인공지능 쪽인것 같다. 개발자 진로에 대해 대화를 하다보면 여실히 느껴진다. 할 수 있을 것 같은거에 집중하기 보단 하고 싶은 것에 집중하기 위해 지금은 기초를 다져야 할 때다.

정보처리산업기사는 일단 필기만 보고, 데이터 분석과 관련된 자격증을 좀 알아봐야겠다.

조급함을 가지지 말고 서서히 분야를 넓혀나가야겠다.

그래서 정리해보면 자바는 기본 중에 기본 그냥 한국사람의 한국어 느낌인거고 기업에서는 프레임워크를 다룰 줄 아는지를 중요하게 생각하므로 자바 스프링부트, 자바스크립트의 리액트, 제이쿼리 등을 추가로 공부할 것

그리고 관심분야로 확장을 위해 파이선을 배우고 데이터분석 자격증을 따 볼 것.

이 틀로 공부를 하다 뭔가 궁금하고 해보고 싶은 게 생기면 최대한 해 볼 것!

그리고 요즘 회사들은 자바스크립트를 타입스크립트로 바꾸는 일을 많이 하는 것 같다.

그리니 타입스크립트도 관심가지고 배워둘것. 이건 너무 부담가지지말고 자바를 좀 열심히 하다보면 금방 배울 수 있다고 하니 자바와 자바스크립트를 열심히 해야겠다.

작성 :2024. 5. 9. 18:14

 

* 중복선택 가능 여부를 표기하는 것이 별것 아닌 것 같지만 굉장히 중요한 의미를 가진다.

* 스토리보드의 한줄 한줄은 우리가 구현해야 할 코드를 의미한다.

* 디자인 반영에 대한 요구사항도 기입 가능

 

아래는 같은 설명, 다른 느낌

위 쪽이 내가 썼던 description이고 아래 쪽이 강사님이 만든 description이다.

뭔가 아직 큰 틀을 못 읽겠다. 한 페이지, 한 페이지에서 정확히 어떤 일을 하겠다 하는 기준을 가지고 파악하지 않으면 이건 쓸 수가 없는 것 같다.

 

강사님이 만든 description으로 구현된 화면

오늘은 관리자가 보는 버전으로 스토리보드를 만들어보았다.

관리자 버전의 로그인 화면

 

GNB에서 이런 식으로 뒤에 덜 중요한 부분을 연하게 처리하니 가독성이 훨씬 더 좋아진다.

 

사용자 버전의 화면에만 익숙했지,, 내가 관리자가 되어 페이지를 관리한다는게 낯설고 뭘 해야 할지 정말 감이 안잡혔다.

 

밑에 두 화면설계는 스스로 해봤지만 description을 어떻게 써야하는지 모르겠다!

잘 쓰여진 화면설계도를 좀 구글링해봐야겠다.

+ Recent posts