Skip to content

Commit

Permalink
Add settings for radius of clear fog in meters
Browse files Browse the repository at this point in the history
  • Loading branch information
Freika committed Jun 25, 2024
1 parent 61431ac commit 81d13f5
Show file tree
Hide file tree
Showing 9 changed files with 72 additions and 133 deletions.
2 changes: 1 addition & 1 deletion app/assets/builds/tailwind.css

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions app/assets/stylesheets/fog-of-war.css
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
pointer-events: none;
mix-blend-mode: multiply;
z-index: 1000;
filter: blur(5px); /* Apply a blur effect */
}

.unfogged-circle {
Expand All @@ -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 */
}
4 changes: 3 additions & 1 deletion app/controllers/settings_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ def generate_api_key
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
32 changes: 26 additions & 6 deletions app/javascript/controllers/maps_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -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()],
Expand All @@ -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,
Expand All @@ -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);
}
});

Expand All @@ -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]);
Expand All @@ -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);
}

Expand Down
3 changes: 2 additions & 1 deletion app/views/map/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
24 changes: 24 additions & 0 deletions app/views/settings/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
14 changes: 14 additions & 0 deletions db/data/20240625201842_add_fog_of_war_meters_to_settings.rb
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion db/data_schema.rb
Original file line number Diff line number Diff line change
@@ -1 +1 @@
DataMigrate::Data.define(version: 20240610170930)
DataMigrate::Data.define(version: 20240625201842)
121 changes: 0 additions & 121 deletions test.html

This file was deleted.

0 comments on commit 81d13f5

Please sign in to comment.