是否可以在使用JavaScript编程创建的Map上创建可单击区域?

jxct1oxe  于 2022-12-28  发布在  Java
关注(0)|答案(1)|浏览(217)

我使用原始Map数据和JavaScript重新创建了1985年游戏“Balance of Power”(WikipediaInternet Archive)中的Map。
我想知道的是,是否可以只使用JavaScript、CSS和HTML来使每个国家成为可点击的区域。我想发生的是,如果我点击一个国家边界内的任何地方,整个国家将被突出显示,即填充黑色表示它已被选中。
注意:如果可能的话,我想把自己限制在JavaScript、CSS和HTML上,以使这个过程尽可能简单。
以下是根据原始数据创建Map后的外观。x1c 0d1x
下面是选择单个国家/地区后的Map外观(一次只能选择一个国家/地区)。

jq6vz3qz

jq6vz3qz1#

在阅读了评论并做了一些研究之后,我决定使用原始数据创建一个自定义SVGMap。

原始Map是使用JavaScript在HTML画布上创建的,位于左侧和右侧两个SVG图像的下方。
SVG版本只包含三个北美国家,并使用一些CSS来填充单个国家,当您越过其边界并将鼠标悬停在其上时。代码还没有优化,每个国家都有自己的数据结构,当你跨越一些国家的边界时,仍然会有一些小故障(我想让它在你点击它时高亮显示,而不是仅仅跨越它的边界,但我还没有想出如何做到这一点)。
下面是创建上述SVGMap图像的JS/CSS/HTML代码:

const svgns = "http://www.w3.org/2000/svg"; // variable for the namespace
const svg = document.querySelector("svg"); // targeting the svg itself

const usa_main = document.querySelector("g#usa_main"); // targeting the united states div
const usa_alaska = document.querySelector("g#usa_alaska"); 
const canada_main = document.querySelector("g#canada_main");
const canada_victoria = document.querySelector("g#canada_victoria");
const mexico_main = document.querySelector("g#mexico_main"); 

const stroke_default = "black";
const fill_default = "none";

var outline_united_states = "";
var outline_alaska = "";
var outline_canada = "";
var outline_victoria_island = "";
var outline_mexico = "";

// United States
outline_united_states=createOutline(60, 84, "3ES6ES6ES6ES6ES6ES6ES6ES3ESWSWS3EN2ESESESEES5WSSWSSWWSWSW3SESEENENE3NENENN4ESSWSWSE3SWSSEEN3ENENN6E3N9EENENEN3E3SWSSWSWWSWWSWSEES4WS3WSWWSSWSWS3WNNW5SW3NWSSWSSESSWSWS3WSSWWSSWWSWSWWSWSSW4SE7SWS3WNWNNENNWNNE4N2WN3WN6WSESSWNWWNWWS3WSWWS3WSWWSWSW4S2WNWNW4NW3N5W3NWNN5WN2WN2WN2WN6W4NWNW9NNE3NE2NENE2NE2NENE2NENE2NENENE2NE2NENE2N");
let united_states = document.createElementNS(svgns, "polygon");
united_states.setAttribute("points", outline_united_states);
united_states.setAttribute("stroke", stroke_default);
united_states.setAttribute("fill", fill_default);
//svg.appendChild(united_states); // append the new polygon to the svg
usa_main.appendChild(united_states); 

// Alaska
outline_alaska = createOutline(30, 56, "3EN3ENEN2ESE2NW3NEN6ES2ENEN2EN3WS2W2NE2N2EN5E2SENENENW3N2ES4EN3EN6ES2ENEN2ESES2ESES6E2SWSWS2WSWS2WSWS2WSWSWS2WSWSWS2WSWS2W5SE9S2W5NW2NW2NWN2WNWN2WN3WS2WS3WNEN2ENEN2WS2WS2WS9W2WS5W3N");
let alaska = document.createElementNS(svgns, "polygon");
alaska.setAttribute("points", outline_alaska);
alaska.setAttribute("stroke", "black");
alaska.setAttribute("fill", "none");
usa_alaska.appendChild(alaska);

// Canada
outline_canada = createOutline(86, 41, "2ESES2ENENEN2ES2EN3ENE2S2ES4ESES3ESE2S7EN3ESE2SES2ES2EN3EN2ENENESESE4N2ENENEN2ENEN3EN2ESESWSWSWSW2SWSW2SE2SWSES2ENENENENESE2SWS2W2S3WS2WNWS3WS2WNW2S2E2S3WN3WS2WS2WS2W2SWS2WS2WS3W7S3ESES2ESES3ESW2SW2SE2SES2E3NENE2NEN2EN2ENENE5NENEN2ENE3N3ES3ENESESES2E2SW2SW2SES2EN2E2NE2NE6SW3SE3S3ESES2E4SW2S5WS9W6WS2WS2WSWSWSENEN3EN3ES2E2SWSWS2W2SES2ESES3WSWS4WNEN2EN2WS2WSW2NE3N3WSWSWS9WWS5W2SWS5WNENENENEN2ENWNEN5W2NE3NWNWN4WS2WSWN3WN6WN6WN6WN6WN6WN6WN6WN4W6NE2NE2NENE2NEN2E9NW5N2ENEN2ENENEN2ENENEN2ENEN2ENEN2ENENEN");
let canada = document.createElementNS(svgns, "polygon");
canada.setAttribute("points", outline_canada);
canada.setAttribute("stroke", "black");
canada.setAttribute("fill", "none");
canada_main.appendChild(canada);

// Victoria Island
outline_victoria_island = createOutline(114, 43, "2ES3EN2W2NEN3ESES2ENEN2ESES2E2SES3ESWS4WN2W2SES2WNWNWNWN6WS3W3N");
let victoria_island = document.createElementNS(svgns, "polygon");
victoria_island.setAttribute("points", outline_victoria_island);
victoria_island.setAttribute("stroke", "black");
victoria_island.setAttribute("fill", "none");
canada_victoria.appendChild(victoria_island);

// Mexico
outline_mexico = createOutline(47, 124, "6ES2ES2ES2ES5E2SE3S5E3SE4SESESE4SW2SW3SE2SW2SES2ESESEN2ES2ENENE3NEN3ESEN3ESWSW3SW2SWS4W3S4WSWS2WN6WS2WNWNWN2WNWN2WNWNWNWNWNW3NENE3N2W6NW3NW5NW3NW5NWNW9S3SE3SE8S2W2NW4NW2NW2NWNW2N2E2NW3NE6N");
let mexico = document.createElementNS(svgns, "polygon");
mexico.setAttribute("points", outline_mexico);
mexico.setAttribute("stroke", "black");
mexico.setAttribute("fill", "none");
mexico_main.appendChild(mexico);

function createOutline(origin_x, origin_y, direction_string) {
    var points = "";
    var current_x = parseInt(origin_x);
    var current_y = parseInt(origin_y);
    
    for (let i = 0; i <= direction_string.length; i++) {
        points = points + current_x.toString() + "," + current_y.toString() + " ";
        

        k = direction_string.substr(i, 1).charCodeAt(0) - 49;
        l = i + 1;

        if (k < 0 || k > 8) {
            k = 1;
            l = i;
        }

        direction = direction_string[l];

        switch (direction) {
            case "N":
                current_y = current_y - k;
                break;
            case "S":
                current_y = current_y + k;
                break;
            case "E":
                current_x = current_x + k;
                break;
            case "W":
                current_x = current_x - k;
                break;
        }
    }
    //console.log(points);
    //console.log(points.length);  
    
    return points;
}
svg {
    background-color: antiquewhite;
}

g polygon:hover {
    fill: #000000;
}
<svg id="map" class="map" xmlns="http://www.w3.org/2000/svg" width="512" height="342" viewBox="0 0 512 342">
    <g id="usa_main" class="north_america" xmlns="http://www.w3.org/2000/svg" />
    <g id="usa_alaska" class="north_america" xmlns="http://www.w3.org/2000/svg" />
    <g id="canada_main" class="north_america" xmlns="http://www.w3.org/2000/svg" />
    <g id="canada_victoria" class="north_america" xmlns="http://www.w3.org/2000/svg" /> 
    <g id="mexico_main" class="north_america" xmlns="http://www.w3.org/2000/svg" />
</svg>

相关问题