mirror of
https://github.com/godotengine/godot-website.git
synced 2025-12-31 09:48:43 +03:00
* Add note to user groups page with info on where to open a PR to add a group * Add target/rel to link
209 lines
6.9 KiB
HTML
209 lines
6.9 KiB
HTML
---
|
|
permalink: /community/user-groups/index.html
|
|
title: "User Groups"
|
|
description: "Find local Godot user groups run by community members."
|
|
layout: default
|
|
---
|
|
|
|
{% include header.html %}
|
|
|
|
<main>
|
|
<div class="head">
|
|
<div class="container flex eqsize">
|
|
<div class="main">
|
|
<h1 class="intro-title">User Groups</h1>
|
|
<p class="small">
|
|
Some community members manage local Godot user groups.
|
|
Anyone is welcome to join or create a local community!
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="container">
|
|
|
|
<link rel="stylesheet" href="/assets/leaflet/leaflet.css">
|
|
<script defer src="/assets/leaflet/leaflet.js"></script>
|
|
<script>
|
|
const points = {{ site.data.communities | jsonify }};
|
|
const countryCoordinates = {
|
|
// Full country name: [latitude, longitude]
|
|
// Use <https://latitude.to/> to find GPS coordinates.
|
|
'Algeria': [28.00003, 2.99998],
|
|
'Argentina': [-38.4192641, -63.5989206],
|
|
'Brazil': [-14.240073, -53.180502],
|
|
'Bulgaria': [42.60740, 25.48566],
|
|
'Canada': [56.130366, -106.346771],
|
|
'China': [35.486703, 101.901875],
|
|
'Croatia': [45.815399, 15.966568],
|
|
'Czech Republic and Slovakia': [50.073658, 14.418540],
|
|
'Ecuador': [-1.160171, -78.432915],
|
|
'Finland': [62.777754, 26.199539],
|
|
'France or French-speaking': [47.824905, 2.618787],
|
|
'Germany': [51.133481, 10.018343],
|
|
'India': [22.199166, 78.476681],
|
|
'Indonesia': [-2.548926, 118.0148634],
|
|
'Italy': [42.504154, 12.646361],
|
|
'Iran': [32.4207423, 53.6830157],
|
|
'Iraq': [33.223191, 43.679291],
|
|
'Israel': [31.53131, 34.86677],
|
|
'Japan': [36.57484, 139.23942],
|
|
'Latvia': [56.959065, 24.862593],
|
|
'Pakistan': [30.3894, 69.353220],
|
|
'Philippines': [14.583333, 120.966667],
|
|
'Poland': [51.9189046, 19.1343786],
|
|
'Portugal': [40.03326, -7.88963],
|
|
'Russia': [55.751400, 37.620900],
|
|
'Saudi Arabia': [25.62426, 42.35283],
|
|
'South Korea': [36.638392, 127.6961188],
|
|
'Spain': [40.2085, -3.713],
|
|
'Sweden': [64.964875, 17.675409],
|
|
'Taiwan': [23.44265, 120.50237],
|
|
'Turkey': [39.908606, 32.784806],
|
|
'United States': [39.78373, -100.44588],
|
|
}
|
|
|
|
function escapeXml(unsafe) {
|
|
return unsafe.replace(/[<>&'"]/g, function (character) {
|
|
switch (character) {
|
|
case '<': return '<';
|
|
case '>': return '>';
|
|
case '&': return '&';
|
|
case "'": return ''';
|
|
case '"': return '"';
|
|
}
|
|
});
|
|
}
|
|
|
|
window.addEventListener('DOMContentLoaded', () => {
|
|
const bounds = L.latLngBounds(L.latLng(90, -180), L.latLng(-90, 180));
|
|
const myMap = L.map('community-map', {
|
|
// Show the whole world (centered around Europe) when loading.
|
|
center: [40, 0],
|
|
zoom: 3,
|
|
maxBounds: bounds,
|
|
maxBoundsViscosity: 1,
|
|
});
|
|
|
|
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
|
attribution: '© <a href="https://openstreetmap.org/copyright">OpenStreetMap contributors</a>',
|
|
// Use more reasonable zoom level limits where tiles are still displayed.
|
|
minZoom: 2,
|
|
maxZoom: 18,
|
|
noWrap: true,
|
|
bounds,
|
|
}).addTo(myMap);
|
|
|
|
// The icon to use for physical venues.
|
|
const physicalIcon = L.icon({
|
|
iconUrl: '/assets/leaflet/images/physical-marker-icon.webp',
|
|
iconRetinaUrl: '/assets/leaflet/images/physical-marker-icon-2x.webp',
|
|
iconSize: [25, 41],
|
|
iconAnchor: [12, 41],
|
|
shadowUrl: '/assets/leaflet/images/marker-shadow.png',
|
|
shadowSize: [41, 41],
|
|
shadowAnchor: [13, 41],
|
|
popupAnchor: [1, -34],
|
|
tooltipAnchor: [16, -28],
|
|
});
|
|
|
|
// Object with country names as key, array of points as value.
|
|
const onlinePoints = {};
|
|
|
|
// Flatten the object while looping over it.
|
|
Object.keys(points).forEach((country, index) => {
|
|
points[country].forEach((point, index2) => {
|
|
// Store the country so we can get the coordinates for online communities.
|
|
point.country = country;
|
|
if (point.coordinates) {
|
|
// Physical community.
|
|
const marker = L.marker(point.coordinates, {
|
|
title: point.name,
|
|
icon: physicalIcon,
|
|
});
|
|
marker.bindPopup(`
|
|
<strong>${escapeXml(point.name)}</strong><br>
|
|
${point.links.map((link) => ` <a href="${escapeXml(link.url)}">${escapeXml(link.title)}</a>`)}
|
|
`).openPopup();
|
|
marker.addTo(myMap);
|
|
} else {
|
|
// Online community.
|
|
// We only want one marker per country (with a merged tooltip, see below).
|
|
// Therefore, we don't add the marker here directly.
|
|
if (!onlinePoints[point.country]) {
|
|
onlinePoints[point.country] = []
|
|
}
|
|
|
|
onlinePoints[point.country].push(point);
|
|
}
|
|
});
|
|
});
|
|
|
|
// Add markers for online communities with merged tooltips.
|
|
Object.keys(onlinePoints).forEach((country, index) => {
|
|
if (countryCoordinates[country] == null) {
|
|
console.warn(`Coordinates of "${country}" are missing, skipping.`);
|
|
return;
|
|
}
|
|
|
|
let markerPopup = '';
|
|
onlinePoints[country].forEach((point, index2) => {
|
|
// Add a line separation between online communities.
|
|
markerPopup += `
|
|
${index2 >= 1 ? '<hr>' : ''}
|
|
<strong>${escapeXml(point.name)}</strong><br>
|
|
${point.links.map((link) => ` <a href="${escapeXml(link.url)}">${escapeXml(link.title)}</a>`)}
|
|
`;
|
|
});
|
|
|
|
const marker = L.marker(countryCoordinates[country], {
|
|
title: country,
|
|
});
|
|
marker.bindPopup(markerPopup).openPopup();
|
|
marker.addTo(myMap);
|
|
});
|
|
});
|
|
</script>
|
|
|
|
<h2 class="title">Community map</h2>
|
|
<p>
|
|
This map lists all physical venues and online community hosted by community members.
|
|
Scroll down to view a list of online communities.
|
|
</p>
|
|
<div id="community-map" style="height: 35rem"></div>
|
|
<p>
|
|
<!-- Color legend. -->
|
|
<span
|
|
style="display: inline-block; width: 0.75rem; height: 0.75rem; border-radius: 50%; background-color: #b7422c; margin-right: 0.4rem"></span>
|
|
Physical community
|
|
<span
|
|
style="display: inline-block; width: 0.75rem; height: 0.75rem; border-radius: 50%; background-color: #257eca; margin-right: 0.4rem; margin-left: 1.5rem"></span>
|
|
Online community
|
|
</p>
|
|
|
|
|
|
{% for country in site.data.communities %}
|
|
<h3 class="title">{{ country[0] }}</h3>
|
|
<ul>
|
|
{% for community in country[1] %}
|
|
<li>
|
|
{{community.name }}
|
|
({% for link in community.links %}<a href="{{ link.url }}" target="_blank">{{ link.title }}</a>{% unless
|
|
forloop.last %}, {% endunless %}{% endfor %})
|
|
</li>
|
|
{% endfor%}
|
|
</ul>
|
|
{% endfor %}
|
|
|
|
|
|
<p style="margin-top: 4rem">
|
|
If you run a local community and would like to have it listed here,
|
|
please send an email to <em>webmaster at godotengine · org</em>
|
|
or open a pull request on GitHub modifying the
|
|
<a href="https://github.com/godotengine/godot-website/blob/master/_data/communities.yml" target="_blank" rel="noopener">
|
|
<code>_data/communities.yml</code> file
|
|
</a>.
|
|
</p>
|
|
</div>
|
|
</main>
|
|
{% include footer.html %}
|