작업기간 : 2024.08.10 ~ 08.17 

역할 : 게시판 디자인 및 디자인 총괄// 화면 정의서 작성 (유저 페이지)// 사이트 맵 작성

 

- 2024.08.05 제작의도 및 기획안 작성

- 2024.08.10 사이트맵 작성, 메인페이지 피그마로 디자인

 

사이트맵 초안)

 

사이트맵 수정 및 최종)

* 관리자 페이지 기능 축소

 

 

 

- 2024.08.11 ~ 08.14 피그마로 와이어프레임 작성 (회원가입, 로그인, 멍스토리, 멍SOS)

회원가입, 프로필 등록, 로그인

 

 

 

멍스토리

 

 

멍SOS

 

 

 

- 2024.08.16 ~ 08.17 피그마로 와이어프레임 작성 및 수정 (멍스토리와 멍SOS 글 수정, 삭제)

멍스토리 로그인 정보와 글쓴이가 같은 경우 글 수정, 삭제

 

멍SOS > SOS상담 글쓰기 페이지 추가

 

멍SOS 로그인 정보와 글쓴이가 같은 경우 글 수정, 삭제

 

- 2024.08.17 ~ 페이지 디자인하기

작성 : 2024.08.05 

 

기획의도

강아지를 키우는 사람들은 의료 정보와 애견 동반 가능한 장소에 대한 정보 접근이 어려운 경우가 많습니다. 이러한 문제를 해결하기 위해 강아지 병원 정보, 애견 동반 가능한 휴가 장소 추천, 그리고 내 강아지를 자랑할 수 있는 커뮤니티 기능을 제공하는 웹사이트를 기획하게 되었습니다.

 

의의

지금은 586만 마리의 강아지와 함께 하는 시대!

국민은행 경영연구소가 발표한 2023 한국 반려동물 보고서에 따르면,

현재 대한민국에는 582만 마리 이상의 강아지가 살고 있습니다.

가족처럼 소중한 반려동물과 건강하고 오래 살고자 하는 반려가구가 늘어나면서,

다양한 건강 관리 정보에 대한 필요성도 증가하고 있습니다.

이 웹사이트는 이러한 반려가구가 보다 성숙한 반려견 양육 문화를 형성하는 데 기여하고자 합니다.

반려견의 건강과 행복을 지키기 위한 정보를 제공하여,

반려인들이 반려견과 함께하는 시간을 더욱 소중하게 만들어 드리겠습니다.

 

서비스 소개

  • 강아지 병원 정보: 지역별 강아지 병원 정보 제공
  • 애견 동반 장소 추천: 휴가 및 외출 시 애견 동반 가능한 장소 소개
  • 커뮤니티 기능: 반려견 자랑 및 정보 공유를 위한 커뮤니티 제공

 

 

 

 

0801 ~ 0802

내가 우선 css, html 을 부트스트랩을 이용해 디자인을 한 후 팀원에게 넘겨줬다.

구체적인 디자인 작업을 하는 팀원 1, 

파일정의서, 화면정의서 등 작업을 하는 팀원 2(나),

컨트롤러 구현을 하는 팀원 3. 이렇게 역할을 분담해 작업을 시작했다. 

 

0802 ~ 0803

다른 팀원이 컨트롤러 구현에서 어려움이 많아 내가 다시 파일 구조를 만들고 처음부터 컨트롤러 구현을 해나갔다. 

컨트롤러 구현을 하며 나 뿐만 아니라 모든 팀원이 스프링에 대한 이해도가 낮을 것을 확인할 수 있었다. 

이 기회에 열심히 공부했고 다른 팀원에게도 도움이 될까 싶어 노션에 컨트롤러 구현 과정을 적어 공유했다. 

 

 

팀 노션에서 공유한 부분 발췌 ) 


스프링 공부 _ 컨트롤러 구현과정

 

절대 이 영역 수정하지 말 것 !   

-> 노션을 공유해서 사용하면 내가 쓴 글이 수정되는 일들이 종종 있어 이렇게 적어두었다.

 

공부를 위해 이 과정을 처음부터 따라가주셔도 좋을 것 같습니다.

구현한 공룡게임 코드는 조 단톡방에 0802(금)에 올려드렸습니다.

 

  • 페이지 이동 구조
  1. 로그인 후 아이디와 비밀번호가 일치하면 게임페이지로 이동
  2. 로그인 후 아이디, 비밀번호 둘 중 하나라도 일치하지 않으면 로그인 페이지로 이동
  3. 회원가입 버튼을 누르면 회원가입 페이지로 이동
  4. 회원가입 정보 기입 후 가입하기 버튼을 누르면 자동로그인, 게임페이지로 이동
  5. 회원가입 후 로그인 페이지에서는 다시 1, 2번 참조
  6. 랭킹 버튼을 누르면 랭킹 페이지로 이동

 

  • 컨트롤러 구현

패지지와 폴더 구조가 중요한게 아님

패키지명은 작업 관리의 유지보수성 극대화를 위해 임의로 정한 것.

어떤 패키지에 어떤 클래스가 들어가야하는지에 너무 고민할 필요가 없었다

 

RootController 에서 페이지 이동 처리

회원 가입 화면 요청

회원 가입 요청 (가입시켜줘!)

로그인 화면 요청

로그인 정보 확인 요청 (아이디, 비밀번호 맞는지 폼값을 넘겨 확인)

로그인 정보 불일치 시 다시 로그인 화면으로 이동

 

이걸 코드로 옮기면

 

∨ homecontroller 로 실험해본 코드

더보기
package com.dino.root;

import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/**
 * Handles requests for the application home page.
 */
@Controller
public class RootController {
	
	private static final Logger logger = LoggerFactory.getLogger(RootController.class);
	
	/**
	 * Simply selects the home view to render by returning its name.
	 */
	@RequestMapping(value = "/", method = RequestMethod.GET)
	public String home(Locale locale, Model model) {
		logger.info("Welcome home! The client locale is {}.", locale);
		
		Date date = new Date();
		DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
		
		String formattedDate = dateFormat.format(date);
		
		model.addAttribute("serverTime", formattedDate );
		
		return "home";
	}
	
	@RequestMapping(value = "signup", method = RequestMethod.GET)
	public String signup() {
		System.out.println("signup");
		return "signup";
	}
	
	@RequestMapping(value = "signup", method = RequestMethod.POST)
	public String signup2(HttpServletRequest req) {
		System.out.println("signup 회원가입 정보를 저장");
		System.out.println(req.getParameter("aaa"));
		
		return "home";
	}
	
}

 

homecontroller 에서 수정된 RootController.java

package com.dino.root;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class RootController {
    
    private static final Logger logger = LoggerFactory.getLogger(RootController.class);

    // 메인 페이지 이동
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String home() {
        logger.info("Welcome to the home page!");
        return "home";
    }
    
    // 로그인 페이지 이동
    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public String login() {
        return "login";
    }

    // 로그인 요청 처리
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public String loginPost(@RequestParam("userid") String userid,
                            @RequestParam("password") String password,
                            HttpServletRequest req) {
        // 아이디와 비밀번호 확인 (예제로 확인용)
        if ("user".equals(userid) && "password".equals(password)) {
        	return "redirect:/game";
        } else {
            return "login";
        }
    }

    // 회원가입 페이지 이동
    @RequestMapping(value = "/signup", method = RequestMethod.GET)
    public String signup() {
        return "signup";
    }

    // 회원가입 요청 처리
    @RequestMapping(value = "/signup", method = RequestMethod.POST)
    public String signupPost(HttpServletRequest req) {
        // 회원가입 처리 로직 (여기서는 예제로 간단하게 출력만 함)
        String userid = req.getParameter("userid");
        String password = req.getParameter("password");
        logger.info("회원가입한 회원 이름: {} 비밀번호: {}", userid, password);

        // 회원가입 후 바로 로그인 처리
        if ("user".equals(userid) && "password".equals(password)) {
            return "redirect:/game";
        } else {
            return "login";
        }
    }

    // 랭킹 페이지 이동
    @RequestMapping(value = "/ranking", method = RequestMethod.GET)
    public String ranking() {
        return "ranking";
    }

    // 게임 페이지 이동 (로그인 성공 후)
    @RequestMapping(value = "/game", method = RequestMethod.GET)
    public String game() {
        return "game";
    }
}

 

private static final Logger logger = LoggerFactory.getLogger(RootController.class);

logger.info → syso 는 단순 문자열출력으로 확인만 했다면 log 가 더 자세하게 오류 원인을 알려준다고 해서 사용해보았다. (프로젝트 만들면 기본으로 homecontroller에 샘플코드로 찍히는데 log 관련된 것 같길래 구글링해보니 이렇게 사용하면 된다고 해서 사용해본 것)

 

signup.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>dinogame</title>
</head>
<body>
<h2>회원가입</h2>
    <form action="${pageContext.request.contextPath}/signup" method="post">
        <div>
            <label for="userid">ID:</label>
            <input type="text" id="userid" name="userid" required>
        </div>
        <div>
            <label for="password">Password:</label>
            <input type="password" id="password" name="password" required>
        </div>
        <div>
            <button type="submit">Sign Up</button>
        </div>
    </form>
    <p>이미 회원이신가요? <a href="${pageContext.request.contextPath}/login">로그인</a></p>
</body>
</html>

required 속성 → html5 표준, 필드의 폼을 비워두고 제출하면 브라우저가 자동으로 해달 필드를 강조해 메세지를 표시한다 (유효성 검사와는 조금 다르고 빈 값이 없게 해주는 역할)

 

servlet-context

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:beans="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
		http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

	<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
	
	<!-- Enables the Spring MVC @Controller programming model -->
	<annotation-driven />

	<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
	<resources mapping="/resources/**" location="/resources/" />

	<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
	<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<beans:property name="prefix" value="/WEB-INF/views/" />
		<beans:property name="suffix" value=".jsp" />
	</beans:bean>
	
	<context:component-scan base-package="com.dino.root" />
	
	
	
</beans:beans>

두번째 수정)

전체 코드는 0803(토) 자정 쯤 조 단톡방에 보내드렸습니다.

 

  • 파일 구조

 

🛠 수정 사항

  • .do 로 매핑 → localhost:9999/login.do 이런 식으로 들어가야 한다.
  • home.jsp 파일의 이름을 명시성을 위해 game.jsp 파일로 이름 수정
  • 회원가입 기능 수행을 위해 MemberDAO, MemberVO, MemberService 클래스를 만들었다. (RootController에서 처리한 기능 분산)
  • MemberDAO에 DB 연결 코드 작성

 

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

	<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>/WEB-INF/spring/root-context.xml</param-value>
	</context-param>
	
	<!-- Creates the Spring Container shared by all Servlets and Filters -->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

	<!-- Processes application requests -->
	<servlet>
		<servlet-name>appServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
		
	<servlet-mapping>
		<servlet-name>appServlet</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>

</web-app>

 

☄️ 공룡게임 전체코드

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");

canvas.width = window.innerWidth - 100;
canvas.height = window.innerHeight - 100;

var dinoImg = new Image();
dinoImg.src = '../img/dino.png'; // 공룡 이미지 경로

var cactusImg = new Image();
cactusImg.src = '../img/cactus.png'; // 선인장 이미지 경로

let dino = {
    x: 10,
    y: 230,
    width: 60,
    height: 80,
    draw() {
        ctx.drawImage(dinoImg, this.x, this.y, this.width, this.height);
    }
};

class Cactus {
    constructor() {
        this.x = 500;
        this.y = 230;
        this.width = 20;
        this.height = 40;
    }
    draw() {
        ctx.drawImage(cactusImg, this.x, this.y, this.width, this.height);
    }
}

var timer = 0;
var cactusArr = [];
var jumpTimer = 0;
var animation;
var jumping = false;
var score = 0;

function frame() {
    animation = requestAnimationFrame(frame);
    timer++;

    ctx.clearRect(0, 0, canvas.width, canvas.height);

    if (Math.random() < 0.01) {
        var cactus = new Cactus();
        cactusArr.push(cactus);
    }

    cactusArr.forEach((a, i, o) => {
        a.x -= 1; // 선인장 이동 속도

        if (a.x < 0) {
            o.splice(i, 1);
            score++; // 선인장이 지나갈 때 점수 증가
        }

        collision(dino, a);
        a.draw();
    });

    if (jumping) {
        dino.y -= 4; // 점프 상승 속도
        jumpTimer++;
    }

    if (jumpTimer > 20) {
        jumping = false;
        jumpTimer = 0;
    }

    if (!jumping && dino.y < 230) {
        dino.y += 1; // 점프 하강 속도
    }

    dino.draw();
    drawScore(); // 점수판 그리기
}
frame();

function collision(dino, cactus) {
    var xSubtraction = cactus.x - (dino.x + dino.width);
    var ySubtraction = cactus.y - (dino.y + dino.height);
    if (xSubtraction < 0 && ySubtraction < 0) {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        cancelAnimationFrame(animation);
        showGameOver();
    }
}

var jumpSwitch = false;
let lastSpacePressTime = 0;

document.addEventListener('keydown', function(e) {
    if (e.code === 'Space') {
        const currentTime = Date.now();
        const timeSinceLastPress = currentTime - lastSpacePressTime;

        if (timeSinceLastPress > 500) {
            jumping = true;
            lastSpacePressTime = currentTime;
        }
    }
});

function drawScore() {
    ctx.font = "20px Arial";
    ctx.fillStyle = "black";
    ctx.fillText("Score: " + score, 10, 20);
}

function showGameOver() {
    ctx.font = "40px Arial";
    ctx.fillStyle = "black";
    ctx.fillText("Game Over", canvas.width / 2 - 100, canvas.height / 2);
    createRestartButton();
}

function createRestartButton() {
    var button = document.createElement("button");
    button.innerHTML = "Restart Game";
    button.style.position = "absolute";
    button.style.top = canvas.height / 2 + "px";
    button.style.left = canvas.width / 2 - 40 + "px";
    button.addEventListener("click", restartGame);
    document.body.appendChild(button);
}

function restartGame() {
    document.querySelector("button").remove();
    cactusArr = [];
    score = 0;
    dino.y = 230;
    frame();
}

 


0804 

이슈와 해결, 그리고 참고

  • 부트스트랩 라이브러리에 대한 이해 부족으로 생겼던 이슈

부트스트랩을 사용하면 클래스이름으로 부트스트랩 라이브러리에 값 인식을 하기 때문에 속성을 바꿀 때는 아이디값을 줘야하는데 임의로 클래스 이름을 바꿔 배열이 클어졌다. (왼)

클래스 이름을 원복하고 아이디 값을 줘 해결. (오른쪽)

 

그 밖에 팀원들과 참고한 블로그들)

 

스프링(Spring)에서 자바스크립트(JavaScript) 사용 방법

스프링에서 css, js, image 등의 자원은 파일이 존재하는 url 그 자체로 사용된다. 따라서 url 요청을 해야 하는데 이는 MVC의 DispatcherServlet에서 판단해 Controller에서 RequestMapping Annotation을 검색하게 된

minwoohi.tistory.com

 

 

 

[Spring] 컨트롤러와 프론트 사이에서 값 전달하는 방법의 종류

[1] 들어가며 Spring 프레임워크의 컨트롤러와 JSP사이에서 값을 주고 받는 것은 웹프로그래밍에서 가장 기본적인 작업입니다. 하지만 값을 전달하는 방법의 종류가 많고 프레임워크특성상 많은

admm.tistory.com


0805

우여곡절 끝에 커밋하고 깃에 올리고 발표까지 완료! 

                                              ☄️

                   🦖

         🦖                          🦖             

    🦖          🌋                     🦖                🌋      🦖


프로젝트 마감 후 회고

 

깃을 이용해보기위해 조를 짜 미니프로젝트를 진행해보았다.

미니프로젝트였지만 스프링을 다 이해하고 돌입하게 아니어서 파일구조부터 컨트롤러 구성까지 시행착오가 많았고, 시행착오가 많았던 만큼 스프링에 대해 공부도 많이 됐던 프로젝트다. 사실 여전히 깃은 잘 모르겠지만.. 모르는 만큼 본격적인 프로젝트에 들어가기 전 공부를 해야겠다고 다짐한다! ㅠ

또, 앞으로는 얼마 남지 않은 기간이지만 날마다 그날 작성한 코드들을 압축해 관리하는 습관을 들여야할것 같다. 

그렇게 해놓지 않으니 스프링 JDBC 방식이 뭐였는지 mybatis가 뭐였는지 구별이 안된다. 둘을 제대로 알고 넘어간게 아니라 하날 공부하는 와중에 다른 걸 또 배우니 머리 속에서 정리가 안되는 거다. 그래도 시험을 보며 잘 정리할 기회를 얻어서 다행.. 블로그에도 두 방식을 나눠 정리를 잘 해둬야겠다. 

 

이런저런 팀원들의 사정으로 내가 거의 다 해냈던 프로젝트인데 그래서인지 애정이 정말 크다. 

내가 만든 프로젝트라고 자신있게 말할 수 있을 것 같다. 아주 작은 규모라도 끝을 냈다는 것에 의의를 두고 자신감을 가져야겠다. 회고는 이쯤에서 끝내고 3~4일 가량이었지만 고생했던 프로젝트를 끝냄 기념으로 기록해보려 한다. 



 

프로젝트 주제 : 공룡게임을 할 수 있는 사이트

 

간단한 조작을 통해 누구나 공룡게임을 즐길 수 있고, 회원가입을 하면 본인의 랭킹을 확인할 수 있습니다.

 

기간 ) 0801 ~ 0804

팀원 ) 강유나, ____, ____

 

역할 )

강유나 : 컨트롤러 구현, 회원가입 DAO, VO, Service 기능 구현, jsp파일 css, html, javascript 공룡 게임 구현, 파일 정의서, 화면 정의서 작성

____ : jsp파일 css, html 디자인, 공룡 게임 수정, 팀원에게 깃 사용법 전파

____  : 랭킹 페이지 구현

 

 

☄️ 구현할 페이지 : 게임을 할 수 있는 메인화면, 로그인, 회원가입, 랭킹 확인

 

패키지/ 자바 파일 정의서

shoppingmall 폴더에서 작업 ) -> 초기에는 shoppingmall 이름으로 프로젝트를 모든 조가 일괄적으로 만들었기 때문에 이름이 이렇다.

 

src > main > wabapp 에는 화면을 띄울 jsp 파일이 들어갑니다.

index.jsp → 메인 화면으로 바로 공룡게임을 할 수 있는 화면이 보여집니다.

login.jsp → 로그인 화면입니다.

memberjoin.jsp → 회원가입 화면입니다.

ranking.jsp → 회원들의 게임 점수를 기반으로 랭킹이 매겨집니다.

 

 

자바 파일 및 JSP 파일 정의서 수정

각 기능은 동일하지만 보다 정리된 파일 구조입니다.

-> 컨트롤러를 이해하고 훨씬 더 간결해진 파일 구조다. 

 

 

sql deverloper 에서 작업 )

kit3 계정을 만들어 회원 정보를 담을 테이블과 회원의 점수를 담을 테이블 생성

reate table member(
    id varchar2(15) primary key,
    pass varchar2(20) not null,
    name varchar2(200) not null
    );

create table board(   
    id varchar2(200) primary key,
    score number not null,
    content varchar2(200),
    num number
    );

alter table board 
    add constraint board_mem_fk foreign key (id)
    references member (id);
    
create sequence seq_board_num2
    increment by 1
    start with 1
    minvalue 1;
    
select id,score,content
from (select * from board order by score desc)
where rownum <=20 ;

 

 

화면정의서

 

메인 화면 ( index.jsp )

 

로그인 화면 ( login.jsp )

 

회원가입 화면 ( memberJoin.jsp )

 

랭킹 화면 ( ranking.jsp )

 

 

 

☄️ 실제 구현 화면

 

함께 공유해요 

-> 프로젝트를 하며 새롭게 알게됐던 부분, 함께 나누고 싶은 부분을 '함께 공유해요'라는 이름으로 발표해보았다.

 

  • 스프링에서 정적자원 삽입하기

스프링에서 css, js, image 등의 자원은 파일이 존재하는 url 그 자체로 사용된다. 따라서 url 요청을 해야 하는데 이는 MVC의 DispatcherServlet에서 판단해 Controller에서 RequestMapping Annotation을 검색하게 된다. 이 때 404에러가 발생하게 된다.

따라서 CSS, JavaScript, Image 같은 정적 자원들에 대해 URL을 따로 주어야 하는데 이를 지원해주는 녀석이 mvc:resources이다. 이 태그를 DispatcherServlet에 등록해줘야 사용할 수 있다.

 

어떻게 game jsp에 자바스크립트를 넣었는지에 대한 자세한 설명 참조

 

스프링(Spring)에서 자바스크립트(JavaScript) 사용 방법

스프링에서 css, js, image 등의 자원은 파일이 존재하는 url 그 자체로 사용된다. 따라서 url 요청을 해야 하는데 이는 MVC의 DispatcherServlet에서 판단해 Controller에서 RequestMapping Annotation을 검색하게 된

minwoohi.tistory.com

 

 

  • 공룡게임 참고 - 코딩애플 유튜브영상

 

 

  • 공룡게임 수정

 

로그인을 실행하게 될 경우, 바로 게임 화면으로 이동하면서 게임이 시작되는 부분이 있었다. 이것은 유저의 순발력을 요구하는 플레이가 될 수 있지만, 실제로 게임을 즐기는 유저 입장에서는 굉장히 불쾌할 수 있는 요소중 하나이다. 적어도 게임에 입장하게 되면, 바로 조작할 수 있게 진행해주었어야했었다고 생각했다.

 

참고 문서 :

 

tabindex=1, tabindex=0, tabindex=-1

HTML, CSS(flex/grid), UI/UX, Accessibility, 정찬명

naradesign.github.io

 

 

HTML의 tabindex 속성과 키보드 포커스

Engineering Blog by Dale Seo

www.daleseo.com

 

 

• 이 속성은 문서의 탭 순서 안에서 현재 요소의 순번을 결정한다. 값은 0부터 32767 사이의 숫자여야 한다. 브라우저는 값 앞에 0이 붙어있으면 무시해야 한다.

canvas.tabIndex = 1;
canvas.style.outline = "none"; // 포커스 시 테두리 없애기

 

canvas 에 tabIndex = 1; 을 설정함으로서 로그인에 성공 후, 인게임에 진입하게 되면 가장 먼저 선택을 받을 수 있다.

하지만 이렇게 된다 해도 바로 게임에 진입할 수 있는 상태가 아니기 때문에 focus를 설정해 페이지 진입시, 클릭이 되어있는 상태로 만들어줘야한다. 

// 문서가 준비된 후 캔버스에 포커스 추가
window.onload = () => {
	canvas.focus();
};

window.onload 로 dom이 다 불러와진 경우 자동으로 canvas에 focus를 실행하도록 설정했다.

 

 

+ Recent posts