21. 5. 4.

Javascript 사다리 게임( ladder Game)

그냥 만들어봤던 SVG로 만든 js 사다리 게임
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>사다리게임</title>
<style>
html,body{padding:0; margin:0; }
ul,li{ padding:0; margin:0; list-style:none;}
#div1{ display:inline-block; position:relative;}
#div1 > ul{ display:inline-block; position:relative; width:100%;}
#div1 > ul > li{ display:inline-block; float:left; text-align:center;}
#div1 > ul > li > input{ width:90%; text-align:center; }
#ladderboder{ position:relative; float:left;}
#ladderbody{ position:relative; display:inline-block;}
#ladderresult{ position:absolute; left:0; top:0;}
input{ border:1px solid;}
</style>
<script>
    // 인원제한
    var maxuser = 20;
    var linewidth = 80;
    var svgHeight = 500;
    var gridline = [];
    var resultline = [];
    var resultobj = { "user": 0, "list": [], "line": [] };
    var linecolor = [];
    window.onload = function () {
        var btn1 = document.getElementById("btn1");
        btn1.addEventListener("click", function () {
            linecolor = [];
            gridline = [];
            resultline = [];
            resultobj = { "user": 0, "list": [], "line": [] };
            var num = document.getElementById("num").value;
            if (num == undefined || num == "" || !Number(num)) {
                num = 0;
            }
            if (num <= 1) {
                alert("참여인원을 입력하세요.(최소 2명입니다.)");
                document.getElementById("num").value = "";
                document.getElementById("num").focus();
                return;
            }
            if (num > maxuser) {
                alert("참여인원은 최대 " + maxuser + "명입니다");
                document.getElementById("num").value = "";
                document.getElementById("num").focus();
                return;
            }
            resultobj.user = num;
            var html = [];
            for (var i = 0; i < num; i++) {
                // 랜덤컬러
                var rndcolor = "#" + Math.round(Math.random() * 0xffffff).toString(16);
                linecolor.push(rndcolor);
                html.push("<li><input type=\"text\" style=\"border:1px solid " + rndcolor + "\" name=\"lname\" placeholder=\"이름" + (i + 1) + "\" onmouseover=\"LineResult(" + i + ")\" onmouseout=\"LineResultView()\"/></li>");
            }
            document.getElementById("ladderheader").innerHTML = html.join('');

            var html = [];
            for (var i = 0; i < num; i++) {
                html.push("<li><input type=\"text\" name=\"litem\" placeholder=\"상품" + (i + 1) + "\"/></li>");
            }
            document.getElementById("ladderfooter").innerHTML = html.join('');
            document.getElementById("resultuser").innerHTML = "";

            var svgw = (num * linewidth);

            document.getElementById("ladderboder").style.width = (num * linewidth) + "px";
            document.getElementById("ladderboder").style.height = svgHeight + "px";
            document.getElementById("ladderresult").style.width = (num * linewidth) + "px";
            document.getElementById("ladderresult").style.height = svgHeight + "px";
            document.getElementById("ladderresult").style.display = "none";

            var svg = [];
            svg.push("<svg onclick=\"XYSetting(event);\" id=\"laddersvg\" width=\"" + svgw + "\" height=\"" + svgHeight + "\">");
            for (var i = 0; i < num; i++) {
                var x = ((linewidth / 2) + (i * linewidth));
                svg.push("<line x1=\"" + x + "\" y1=\"0\" x2=\"" + x + "\" y2=\"" + svgHeight + "\" stroke=\"#000\" stroke-width=\"1\"/>");
            }
            svg.push("</svg>");
            var lb = document.getElementById("ladderboder");
            lb.innerHTML = svg.join('');
            var l = document.querySelectorAll("#div1 > ul > li");
            l.forEach(function (el) {
                el.style.width = linewidth + "px";
            })
        });

        var btn2 = document.getElementById("btn2");

        btn2.addEventListener("click", function () {
            var ladderresult = document.getElementById("ladderresult");
            ladderresult.style.display = "inline-block";
            var rline = [];


            for (var i = 0; i < gridline.length; i++) {
                var ix = (gridline[i].x - 40) / linewidth;
                rline.push({ "x1": gridline[i].x, "x2": gridline[i].x + linewidth, "y": gridline[i].y });
                rline.push({ "x1": gridline[i].x + linewidth, "x2": gridline[i].x, "y": gridline[i].y });
            }

            for (var i = 0; i < resultobj.user; i++) {
                var x = ((linewidth / 2) + (i * linewidth));
                //                    rline.push({ "x1": x, "x2": x, "y": 0 });
                rline.push({ "x1": x, "x2": x, "y": svgHeight });
            }

            rline.sort(function (a, b) {
                return a["y"] - b["y"];
            });

            var svg = [];
            svg.push("<svg id=\"ladderresultsvg\" width=\"100%\" height=\"100%\">");

            for (var i = 0; i < resultobj.user; i++) {
                var lcolor = linecolor[i % linecolor.length];
                var resultusr = document.getElementsByName("lname")[i].value;
                if (resultusr == "") {
                    resultusr = document.getElementsByName("lname")[i].getAttribute("placeholder");
                }
                console.log(lcolor);
                var linelist = [];
                var bx = (i * linewidth) + (linewidth / 2);
                var by = 0;
                linelist.push({ "x": bx, "y": by });
                for (var j = 0; j < rline.length; j++) {
                    if (rline[j].x1 == bx && by > rline[j].y - 1) {
                        linelist.push({ "x": bx, "y": by });
                        linelist.push({ "x": rline[j].x2, "y": rline[j].y });
                        svg.push("<line x1=\"" + bx + "\" y1=\"" + rline[j].y + "\" x2=\"" + rline[j].x2 + "\" y2=\"" + rline[j].y + "\" stroke=\"" + lcolor + "\" stroke-width=\"1\" data-line=\"" + i + "\"/>");
                        bx = rline[j].x2;
                    } else if (rline[j].x2 == bx && by > rline[j].y - 1) {
                        linelist.push({ "x": bx, "y": by });
                        linelist.push({ "x": rline[j].x1, "y": rline[j].y });
                        svg.push("<line x1=\"" + rline[j].x1 + "\" y1=\"" + rline[j].y + "\" x2=\"" + bx + "\" y2=\"" + rline[j].y + "\" stroke=\"" + lcolor + "\" stroke-width=\"1\" data-line=\"" + i + "\"/>");
                        bx = rline[j].x1;
                    }
                    by = rline[j].y;
                }
                linelist.push({ "x": bx, "y": svgHeight });

                var ix = (bx - 40) / linewidth;
                document.getElementsByName("litem")[ix].style.borderColor = linecolor[i];
                document.getElementsByName("litem")[ix].setAttribute("onmouseover", "LineResult(" + i + ");");
                document.getElementsByName("litem")[ix].setAttribute("onmouseout", "LineResultView();");

                var itemresult = document.getElementsByName("litem")[ix].value;
                if (itemresult == "") {
                    itemresult = document.getElementsByName("litem")[ix].getAttribute("placeholder");
                }

                var html = [];
                html.push("<p style=\"color:" + linecolor[i] + "\">" + resultusr + " → " + itemresult + "</p>");
                resultuser.innerHTML += html.join('');

                var bx = 0;
                var by = 0;
                for (var j = 0; j < linelist.length; j++) {
                    if (j % 2 == 0) {
                        svg.push("<line x1=\"" + linelist[j].x + "\" y1=\"" + linelist[j].y + "\" ");
                        bx = linelist[j].x;
                        by = linelist[j].y;
                    } else {
                        svg.push(" x2=\"" + linelist[j].x + "\" y2=\"" + linelist[j].y + "\" stroke=\"" + lcolor + "\" stroke-width=\"1\" data-line=\"" + i + "\"/>");
                    }

                }
            }
            svg.push("</svg>");
            ladderresult.innerHTML = svg.join('');
        });
    }

    function XYSetting(e) {
        var lb = document.getElementById("ladderboder");
        var svgtop = lb.getBoundingClientRect().top;
        var x = Math.floor((e.pageX + (linewidth / 2)) / linewidth) * linewidth - (linewidth / 2);
        var y = e.pageY - svgtop;
        if (x > 0 && x < document.getElementById("laddersvg").clientWidth - (linewidth / 2)) {
            var check = false;
            var cli = 0;
            for (var i = 0; i < gridline.length; i++) {
                if (Number(gridline[i].x) == Number(x) && Number(gridline[i].y) == Number(y)) {
                    check = true;
                    cli = i;
                }
            }
            if (check) {
                gridline.splice(cli, 1);
            } else {
                var chk = false;
                for (var i = 0; i < gridline.length; i++) {

                    if (gridline[i].y == y) {
                        chk = true;
                    }
                }
                if (!chk) {
                    gridline.push({ "x": x, "y": y });
                }
            }

            var addsvg = [];
            addsvg.push("<svg onclick=\"XYSetting(event);\" id=\"laddersvg\" width=\"" + lb.clientWidth + "\" height=\"" + svgHeight + "\">");
            var num = (lb.clientWidth / linewidth);
            // 기본라인
            for (var i = 0; i < num; i++) {
                var x = ((linewidth / 2) + (i * linewidth));
                addsvg.push("<line x1=\"" + x + "\" y1=\"0\" x2=\"" + x + "\" y2=\"" + svgHeight + "\" stroke=\"#000\" stroke-width=\"1\"/>")
            }
            for (var i = 0; i < gridline.length; i++) {
                var sx = (gridline[i].x);
                var sy = gridline[i].y;
                addsvg.push("<line x1=\"" + sx + "\" y1=\"" + sy + "\" x2=\"" + (sx + linewidth) + "\" y2=\"" + sy + "\" stroke=\"#000\" stroke-width=\"1\"/>")
            }
            addsvg.push("</svg>");
            var lbs = document.getElementById("ladderboder");
            lbs.innerHTML = addsvg.join('');
        }
    }

    function LineResult(no) {
        if (document.getElementById("ladderresultsvg") != undefined)
            document.getElementById("ladderboder").style.opacity = 0;
        var elm = document.querySelectorAll("#ladderresultsvg line");
        for (var i = 0; i < elm.length; i++) {
            if (elm[i].getAttribute("data-line") == no) {
                elm[i].style.opacity = 1;
            } else {
                elm[i].style.opacity = 0;
            }
        }
    }

    function LineResultView() {
        if (document.getElementById("ladderresultsvg") != undefined)
            document.getElementById("ladderboder").style.opacity = 1;
        var elm = document.querySelectorAll("#ladderresultsvg line");
        for (var i = 0; i < elm.length; i++) {
            elm[i].style.opacity = 1;
        }
    }
</script>
</head>
<body>
    <form>
        <input type="number" id="num" placeholder="참여인원" />
        <a id="btn1">참여인원</a>
        <a id="btn2">결과확인</a>
    </form>

    <div id="div1">
        <ul id="ladderheader"></ul>
        <div id="ladderbody">
            <div id="ladderboder"></div>
            <div id="ladderresult"></div>
        </div>
        <ul id="ladderfooter"></ul>
        <div id="resultuser"></div>
    </div>
</body>
</html>