代码笔:https://codepen.io/anon/pen/LjxNGj
Javascript:
$(document).ready(function() {
var regions = '../js/json/eveRegions.json';
var systems = '../js/json/eveSystems.json';
var constellations = [];
var displayedSystems = [];
var arrayX = [];
var arrayY = [];
function getRegions() {
$.getJSON(regions, function(data) {
data.forEach(function(regionData) {
$('#regionSelect').append("<option id="+regionData.region_id+">"+regionData.name+"</option>")
});
});
}
$('#regionSelect').change(function() {
var selectedRegion = $(this).val();
constellations = [];
displayedSystems = [];
arrayX = [];
arrayY = [];
$('#container').empty();
$.getJSON(regions, function(data) {
data.forEach(function(regionData) {
if (selectedRegion == regionData.name) {
console.log(regionData);
regionData.constellations.forEach(function(constellation) {
constellations.push(constellation);
});
console.log(constellations);
getSystems();
}
});
});
});
function getSystems() {
$.getJSON(systems, function(data) {
var systemCount = data.length;
var index = 0;
data.forEach(function(systemData) {
index++;
if(constellations.indexOf(systemData.constellation_id) > -1) {
var x = systemData.position.x / 100000000000000;
var y = systemData.position.y / 100000000000000;
arrayX.push(x);
arrayY.push(y);
displayedSystems.push(systemData);
}
if (index === systemCount) {
generateSystems();
}
});
});
}
function generateSystems() {
var lowestX = Math.min.apply(Math, arrayX);
var lowestY = Math.min.apply(Math, arrayY);
var offsetX = Math.abs(lowestX);
var offsetY = Math.abs(lowestY);
displayedSystems.forEach(function(data) {
var x = data.position.x / 100000000000000;
var y = data.position.y / 100000000000000;
var coordX = x + offsetX;
var coordY = y + offsetY;
var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
svg.setAttribute('id', data.name);
svg.setAttribute('title', data.name);
svg.setAttribute('class', 'system');
svg.setAttribute('constellation-id', data.constellation_id);
svg.setAttribute('style', 'margin-top:'+coordY+'px;margin-left:'+coordX+'px');
svg.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink");
document.getElementById('container').appendChild(svg);
});
}
getRegions();
$('#container').panzoom();
});
HTML:
<body>
<select id="regionSelect"></select>
<div id="container"></div>
</body>
CSS:
select {
position: absolute;
}
#container {
.system {
width: 4px;
height: 4px;
background: grey;
border-radius: 12px;
position: absolute;
&:hover {
background: red;
}
}
.label {
position: absolute;
font-size: 10px;
}
}
此脚本在一个 div 中动态创建多个 SVG 元素。这些元素中的每一个都有使用 x 和 y 坐标的不同像素偏移,例如 map 上的位置。
每次通过下拉菜单选择一个新选项时,都会加载一组新的位置。
你可以在这里看到我将原始坐标除以 10 万亿,以使它们在像素方面更易于管理:
var x = systemData.position.x / 100000000000000;
var y = systemData.position.y / 100000000000000;
这很好用,但问题是即使仍然在某些选择中,偏移量太大以至于生成的 SVG 元素被推到视口(viewport)之外。我通过采用最负坐标并将这些值添加到偏移量(在大多数情况下)使元素从左上角开始对齐来解决这个问题,如下所示:
var lowestX = Math.min.apply(Math, arrayX);
var lowestY = Math.min.apply(Math, arrayY);
var offsetX = Math.abs(lowestX);
var offsetY = Math.abs(lowestY);
displayedSystems.forEach(function(data) {
var x = data.position.x / 100000000000000;
var y = data.position.y / 100000000000000;
var coordX = x + offsetX;
var coordY = y + offsetY;
我正在寻找的是一种不同的方式来绘制这些位置/元素,以便它们始终位于主视口(viewport)内。简单来说,现在有些元素的顶部边距为 1000 像素或更多,我正在寻找一种奇特的方法来解决这个问题。
最佳答案
首先,我建议您只获取一次您的区域和系统数据......这会让您的用户更开心。
但是,为了回答您的查询,如果您将最小的 X 和 Y 值乘以 -1(以有效地使它们成为 0,0 原点),那么您将确保为一个区域显示的每个系统都从最小位置开始。 x 在 0px 和最小的 position.y 在 0px。
希望这对您有所帮助!
$(document).ready(function() {
var regions = '../js/json/eveRegions.json';
var systems = '../js/json/eveSystems.json';
var regionData = [];
var systemData = [];
var constellations = [];
var displayedSystems = [];
var arrayX = [];
var arrayY = [];
$('#regionSelect').change(function() {
var selectedRegion = $(this).val();
constellations = [];
displayedSystems = [];
arrayX = [];
arrayY = [];
$('#container').empty();
var filteredRegions = regionData.filter((r) => selectedRegion == r.name);
filteredRegions.forEach((r) => {
console.log(r);
r.constellations.forEach((c) => constellations.push(c));
console.log(constellations);
getRegionSystems();
});
});
function getRegionSystems() {
// Clear out the previously displayed systems so we don't keep building the list
displayedSystems = systemData.filter((s) => constellations.indexOf(s.constellation_id) > -1);
displayedSystems.forEach((s) => {
var x = s.position.x / 100000000000000;
var y = s.position.y / 100000000000000;
arrayX.push(x);
arrayY.push(y);
});
generateSystems();
}
function generateSystems() {
var lowestX = Math.min.apply(Math, arrayX);
var lowestY = Math.min.apply(Math, arrayY);
var offsetX = -1 * lowestX;
var offsetY = -1 * lowestY;
displayedSystems.forEach(function(data) {
var x = data.position.x / 100000000000000;
var y = data.position.y / 100000000000000;
var coordX = x + offsetX;
var coordY = y + offsetY;
var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
svg.setAttribute('id', data.name);
svg.setAttribute('title', data.name);
svg.setAttribute('class', 'system');
svg.setAttribute('constellation-id', data.constellation_id);
svg.setAttribute('style', 'margin-top:'+coordY+'px;margin-left:'+coordX+'px');
svg.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink");
document.getElementById('container').appendChild(svg);
});
}
function getRegions() {
$.getJSON(regions, function(data) {
data.forEach(function(regionData) {
$('#regionSelect').append("<option id="+regionData.region_id+">"+regionData.name+"</option>")
});
regionData = data;
});
}
function getSystems() {
$.getJSON(systems, function(data) {
systemData = data;
});
}
getRegions();
getSystems();
// $('#container').panzoom();
});
关于javascript - 将元素动态移动到视口(viewport)内部,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45526611/