mirror of
https://github.com/Freika/dawarich.git
synced 2026-01-10 01:01:39 -05:00
Add settings for radius of clear fog in meters
This commit is contained in:
parent
61431ac64f
commit
81d13f548e
9 changed files with 72 additions and 133 deletions
File diff suppressed because one or more lines are too long
|
|
@ -9,7 +9,6 @@
|
|||
pointer-events: none;
|
||||
mix-blend-mode: multiply;
|
||||
z-index: 1000;
|
||||
filter: blur(5px); /* Apply a blur effect */
|
||||
}
|
||||
|
||||
.unfogged-circle {
|
||||
|
|
@ -18,5 +17,5 @@
|
|||
border-radius: 50%;
|
||||
background: white;
|
||||
mix-blend-mode: destination-out;
|
||||
filter: blur(0px); /* Apply no blur to the circles */
|
||||
filter: blur(3px); /* Apply no blur to the circles */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@ class SettingsController < ApplicationController
|
|||
private
|
||||
|
||||
def settings_params
|
||||
params.require(:settings).permit(:meters_between_routes, :minutes_between_routes)
|
||||
params.require(:settings).permit(
|
||||
:meters_between_routes, :minutes_between_routes, :fog_of_war_meters
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ export default class extends Controller {
|
|||
let center = markers[markers.length - 1] || JSON.parse(this.element.dataset.center);
|
||||
center = center === undefined ? [52.514568, 13.350111] : center;
|
||||
const timezone = this.element.dataset.timezone;
|
||||
const clearFogRadius = this.element.dataset.fog_of_war_meters;
|
||||
|
||||
const map = L.map(this.containerTarget, {
|
||||
layers: [this.osmMapLayer(), this.osmHotMapLayer()],
|
||||
|
|
@ -23,7 +24,7 @@ export default class extends Controller {
|
|||
|
||||
const polylinesLayer = this.createPolylinesLayer(markers, map, timezone);
|
||||
const heatmapLayer = L.heatLayer(heatmapMarkers, { radius: 20 }).addTo(map);
|
||||
const fogOverlay = L.layerGroup();
|
||||
const fogOverlay = L.layerGroup(); // Initialize fog layer
|
||||
const controlsLayer = {
|
||||
Points: markersLayer,
|
||||
Polylines: polylinesLayer,
|
||||
|
|
@ -40,16 +41,19 @@ export default class extends Controller {
|
|||
})
|
||||
.addTo(map);
|
||||
|
||||
L.control.layers(this.baseMaps(), controlsLayer).addTo(map);
|
||||
const layerControl = L.control.layers(this.baseMaps(), controlsLayer).addTo(map);
|
||||
|
||||
let fogEnabled = false;
|
||||
|
||||
// Hide fog by default
|
||||
document.getElementById('fog').style.display = 'none';
|
||||
|
||||
// Toggle fog layer visibility
|
||||
map.on('overlayadd', function(e) {
|
||||
if (e.name === 'Fog of War') {
|
||||
fogEnabled = true;
|
||||
document.getElementById('fog').style.display = 'block';
|
||||
updateFog(markers);
|
||||
updateFog(markers, clearFogRadius);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -63,20 +67,35 @@ export default class extends Controller {
|
|||
// Update fog circles on zoom and move
|
||||
map.on('zoomend moveend', function() {
|
||||
if (fogEnabled) {
|
||||
updateFog(markers);
|
||||
updateFog(markers, clearFogRadius);
|
||||
}
|
||||
});
|
||||
|
||||
function updateFog(markers) {
|
||||
function updateFog(markers, clearFogRadius) {
|
||||
if (fogEnabled) {
|
||||
var fog = document.getElementById('fog');
|
||||
fog.innerHTML = ''; // Clear previous circles
|
||||
markers.forEach(function(point) {
|
||||
clearFog(point[0], point[1], 100); // Adjust the radius as needed
|
||||
const radiusInPixels = metersToPixels(map, clearFogRadius);
|
||||
clearFog(point[0], point[1], radiusInPixels);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function metersToPixels(map, meters) {
|
||||
const zoom = map.getZoom();
|
||||
const latLng = map.getCenter(); // Get map center for correct projection
|
||||
const metersPerPixel = getMetersPerPixel(latLng.lat, zoom);
|
||||
return meters / metersPerPixel;
|
||||
}
|
||||
|
||||
function getMetersPerPixel(latitude, zoom) {
|
||||
// Might be a total bullshit, generated by ChatGPT, but works
|
||||
const earthCircumference = 40075016.686; // Earth's circumference in meters
|
||||
const metersPerPixel = earthCircumference * Math.cos(latitude * Math.PI / 180) / Math.pow(2, zoom + 8);
|
||||
return metersPerPixel;
|
||||
}
|
||||
|
||||
function clearFog(lat, lng, radius) {
|
||||
var fog = document.getElementById('fog');
|
||||
var point = map.latLngToContainerPoint([lat, lng]);
|
||||
|
|
@ -87,6 +106,7 @@ export default class extends Controller {
|
|||
circle.style.height = size + 'px';
|
||||
circle.style.left = (point.x - radius) + 'px';
|
||||
circle.style.top = (point.y - radius) + 'px';
|
||||
circle.style.backdropFilter = 'blur(0px)'; // Remove blur for the circles
|
||||
fog.appendChild(circle);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,8 @@
|
|||
data-center="<%= MAP_CENTER %>"
|
||||
data-timezone="<%= Rails.configuration.time_zone %>"
|
||||
data-meters_between_routes="<%= current_user.settings['meters_between_routes'] %>"
|
||||
data-minutes_between_routes="<%= current_user.settings['minutes_between_routes'] %>">
|
||||
data-minutes_between_routes="<%= current_user.settings['minutes_between_routes'] %>"
|
||||
data-fog_of_war_meters="<%= current_user.settings['fog_of_war_meters'] %>">
|
||||
<div data-maps-target="container" class="h-[25rem] w-auto min-h-screen">
|
||||
<div id="fog" class="fog"></div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -56,6 +56,30 @@
|
|||
<% end %>
|
||||
<%= f.number_field :minutes_between_routes, value: current_user.settings['minutes_between_routes'], class: "input input-bordered" %>
|
||||
</div>
|
||||
<div class="form-control my-2">
|
||||
<%= f.label :fog_of_war_meters do %>
|
||||
Fog of War meters
|
||||
|
||||
<!-- The button to open modal -->
|
||||
<label for="fog_of_war_meters_info" class="btn">?</label>
|
||||
|
||||
<!-- Put this part before </body> tag -->
|
||||
<input type="checkbox" id="fog_of_war_meters_info" class="modal-toggle" />
|
||||
<div class="modal" role="dialog">
|
||||
<div class="modal-box">
|
||||
<h3 class="text-lg font-bold">Fog of War meters</h3>
|
||||
<p class="py-4">
|
||||
Value in meters.
|
||||
</p>
|
||||
<p class="py-4">
|
||||
Here you can set the radius of the "cleared" area around a point when Fog of War mode is enabled. The area around the point will be cleared, and the rest of the map will be covered with fog. The cleared area will be a circle with the point as the center and the radius as the value you set here.
|
||||
</p>
|
||||
</div>
|
||||
<label class="modal-backdrop" for="fog_of_war_meters_info">Close</label>
|
||||
</div>
|
||||
<% end %>
|
||||
<%= f.number_field :fog_of_war_meters, value: current_user.settings['fog_of_war_meters'], class: "input input-bordered" %>
|
||||
</div>
|
||||
<div class="form-control my-2">
|
||||
<%= f.submit "Update", class: "btn btn-primary" %>
|
||||
</div>
|
||||
|
|
|
|||
14
db/data/20240625201842_add_fog_of_war_meters_to_settings.rb
Normal file
14
db/data/20240625201842_add_fog_of_war_meters_to_settings.rb
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddFogOfWarMetersToSettings < ActiveRecord::Migration[7.1]
|
||||
def up
|
||||
User.find_each do |user|
|
||||
user.settings = user.settings.merge(fog_of_war_meters: 100)
|
||||
user.save!
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
raise ActiveRecord::IrreversibleMigration
|
||||
end
|
||||
end
|
||||
|
|
@ -1 +1 @@
|
|||
DataMigrate::Data.define(version: 20240610170930)
|
||||
DataMigrate::Data.define(version: 20240625201842)
|
||||
|
|
|
|||
121
test.html
121
test.html
|
|
@ -1,121 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Leaflet Map with Fog of War</title>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" />
|
||||
<style>
|
||||
#map { height: 100vh; }
|
||||
|
||||
.fog {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.7); /* Adjust the opacity here */
|
||||
pointer-events: none;
|
||||
mix-blend-mode: multiply;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.unfogged-circle {
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
border-radius: 50%;
|
||||
background: white;
|
||||
mix-blend-mode: destination-out;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="map"></div>
|
||||
<div id="fog" class="fog"></div>
|
||||
<script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script>
|
||||
<script>
|
||||
// Initialize the map
|
||||
var map = L.map('map').setView([52.516667, 13.383333], 14);
|
||||
|
||||
// Add OpenStreetMap tile layer
|
||||
var osmLayer = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
maxZoom: 19,
|
||||
}).addTo(map);
|
||||
|
||||
// Create fog of war overlay
|
||||
var fogOverlay = L.layerGroup();
|
||||
|
||||
// Function to clear fog around a given position
|
||||
function clearFog(lat, lng, radius) {
|
||||
var fog = document.getElementById('fog');
|
||||
var point = map.latLngToContainerPoint([lat, lng]);
|
||||
var size = radius * 2;
|
||||
var circle = document.createElement('div');
|
||||
circle.className = 'unfogged-circle';
|
||||
circle.style.width = size + 'px';
|
||||
circle.style.height = size + 'px';
|
||||
circle.style.left = (point.x - radius) + 'px';
|
||||
circle.style.top = (point.y - radius) + 'px';
|
||||
fog.appendChild(circle);
|
||||
}
|
||||
|
||||
// Example points to unfog
|
||||
var points = [
|
||||
[52.516667, 13.383333],
|
||||
[52.520007, 13.404954],
|
||||
[52.522222, 13.412222]
|
||||
];
|
||||
|
||||
// Clear fog around each point
|
||||
function updateFog() {
|
||||
if (fogEnabled) {
|
||||
var fog = document.getElementById('fog');
|
||||
fog.innerHTML = ''; // Clear previous circles
|
||||
points.forEach(function(point) {
|
||||
clearFog(point[0], point[1], 100); // Adjust the radius as needed
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Initial fog clearing
|
||||
var fogEnabled = true;
|
||||
updateFog();
|
||||
|
||||
// Update fog clearing when the map moves or zooms
|
||||
map.on('moveend', updateFog);
|
||||
map.on('zoomend', updateFog);
|
||||
|
||||
// Layers for the controls
|
||||
var markersLayer = L.layerGroup(); // Replace with your actual markers layer
|
||||
var polylinesLayer = L.layerGroup(); // Replace with your actual polylines layer
|
||||
var heatmapLayer = L.layerGroup(); // Replace with your actual heatmap layer
|
||||
|
||||
// Layers control
|
||||
var controlsLayer = {
|
||||
"Points": markersLayer,
|
||||
"Polylines": polylinesLayer,
|
||||
"Heatmap": heatmapLayer,
|
||||
"Fog of War": fogOverlay
|
||||
};
|
||||
|
||||
L.control.layers({ "OpenStreetMap": osmLayer }, controlsLayer).addTo(map);
|
||||
|
||||
// Toggle fog layer visibility
|
||||
map.on('overlayadd', function(e) {
|
||||
if (e.name === 'Fog of War') {
|
||||
fogEnabled = true;
|
||||
document.getElementById('fog').style.display = 'block';
|
||||
updateFog();
|
||||
}
|
||||
});
|
||||
|
||||
map.on('overlayremove', function(e) {
|
||||
if (e.name === 'Fog of War') {
|
||||
fogEnabled = false;
|
||||
document.getElementById('fog').style.display = 'none';
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Reference in a new issue