Skip to content

Instantly share code, notes, and snippets.

@tafsiri
Last active April 18, 2017 16:08
Show Gist options
  • Save tafsiri/e9550432d05ab2c7b9e8ba612e969b33 to your computer and use it in GitHub Desktop.
Save tafsiri/e9550432d05ab2c7b9e8ba612e969b33 to your computer and use it in GitHub Desktop.
Tangram Firefly Map

Tangram Shader Firefly Map

Visual effects with fragment shaders

<!DOCTYPE html>
<head>
<meta charset="utf-8">
<!-- leaflet -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.0-rc.1/leaflet.js"></script>
<!-- Main tangram library -->
<script src="https://mapzen.com/tangram/tangram.min.js"></script>
<script src="https://cdn.jsdelivr.net/quicksettings/latest/quicksettings.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.0-rc.1/leaflet.css" />
<style>
body {
margin:0;
position:fixed;
top:0;
right:0;
bottom:0;
left:0;
}
#map {
height: 100%;
width: 100%;
position: absolute;
z-index: 0;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
var mapContainer = document.querySelector('#map');
var map = L.map('map');
map.setView([36.2453813,-100.7281112], 5);
var layer = Tangram.leafletLayer({
scene: 'scene.yaml',
attribution: '<a href="https://mapzen.com/tangram" target="_blank">Tangram</a> | &copy; OSM contributors | <a href="https://mapzen.com/" target="_blank">Mapzen</a>'
});
layer.addTo(map);
var scene = layer.scene;
var requestRedraw = function() {
window.requestAnimationFrame(function() {
scene.requestRedraw();
});
}
// Interaction callbacks
layer.setSelectionEvents({
hover: function(selection) {
if (selection.pixel && selection.leaflet_event.target) {
var node = selection.leaflet_event.target._container;
var x = selection.pixel.x;
var y = selection.pixel.y;
scene.styles.citydot.shaders.uniforms.u_mouse_x = x;
scene.styles.citydot.shaders.uniforms.u_mouse_y = y;
requestRedraw();
}
}
});
// Scene warnings & errors.
scene.subscribe({
error: function (e) {
console.log('scene error:', e);
},
warning: function (e) {
console.log('scene warning:', e);
},
load: function () {
console.log('scene load complete');
}
});
</script>
</body>
cameras:
camera1:
type: perspective
lights:
global_light:
visible: true
type: ambient
ambient: 1.0
diffuse: 1.0
specular: 1.0
sources:
stamen-terrain:
type: Raster
url: http://a.tile.stamen.com/terrain-background/{z}/{x}/{y}.jpg
osm:
type: TopoJSON
url: https://vector.mapzen.com/osm/all/{z}/{x}/{y}.topojson?api_key=vector-tiles-jvpqPNW
countryPolygons:
type: GeoJSON
url: world.json
import:
- https://tangrams.github.io/blocks/color/tools-full.yaml
styles:
citydot:
base: points
blend: inlay
shaders:
uniforms:
u_mouse_x: 0
u_mouse_y: 0
blocks:
color: |
// We are going to use texture coordinates to color our dots.
// What does texcoord look like?
//
// (0,1)----(1,1)
// |--------|
// |--------|
// |--------|
// (0,0)----(1,0)
//
// v_texcoord is varying set by tangram.
// see https://github.com/tangrams/tangram/blob/master/src/styles/points/points_fragment.glsl
// Some coordinate checking debug code.
// vec2 uv = v_texcoord;
// if(uv.x > 0.9 && uv.y > 0.9) {
// color.r = 1.0;
// color.g = 1.0;
// color.b = 1.0;
// }
// Check if the mouse if near this fragment
//
// We need to convert mouse position from css pixels to device pixels
// for the calculations to work on 'retina' screens as gl_FragCoord is in
// device pixels.
vec2 mousePos = vec2(u_mouse_x, u_mouse_y) / u_resolution * u_device_pixel_ratio;
mousePos.y = 1. - mousePos.y;
vec2 fragmentPos = gl_FragCoord.xy / u_resolution;
float mouseDistance = abs(distance(mousePos, fragmentPos));
float pulse = 0.0;
if (mouseDistance < 0.045) {
color.rgb = vec3(1.00,0.39,0.28); // orange
pulse = sin(u_time * 1.45) * 0.5 + 0.5;
pulse = clamp(pulse, 0., 0.3);
}
// Distance to center of point.
vec2 uvd = v_texcoord * 2. - 1.;
float point_dist = length(uvd);
float centerRingRadius = 0.15;
// Set color and alpha
if (point_dist < centerRingRadius - (pulse * .1)) {
color.rgba = vec4(1., 1., 1., 1.);
} else {
color.a = (1. - point_dist - pulse);
}
terrain:
animated: true
base: raster
shaders:
blocks:
color: |
// Desaturate
float luma = dot(color.rgb, vec3(0.299, 0.587, 0.114));
color.rgb = mix(color.rgb, vec3(luma), vec3(0.97));
// Adjust brightness and contrast.
float contrast = 1.8;
//float brightness = -0.4 * luma;
float brightness = -0.8 * luma;
color.rgb = contrast * (color.rgb - .5) + .5 + brightness;
polygonOverlay:
base: polygons
blend: inlay
global:
remap: |
function(value, inLow, inHigh, outLow, outHigh) {
var newVal = ((value - inLow) * ((outHigh - outLow) / (inHigh - inLow))) + outLow;
if (newVal < outLow) {
newVal = outLow;
} else if (newVal > outHigh) {
newVal = outHigh;
}
return Math.floor(newVal);
}
layers:
# Terrain base map
terrain:
data: { source: stamen-terrain }
draw:
terrain:
order: 0 # draw on bottom
# Country polygons
FeatureCollection:
visible: true
data:
source: countryPolygons
draw:
polygonOverlay:
order: 10
color: |
function() {
if (feature.iso_a3 === 'USA') {
return undefined
} else {
return [.0, .0, .0, .7];
}
}
# Water layer
water:
data: { source: stamen-terrain }
draw:
polygons:
order: function() { return feature.sort_key; }
color: '#030418'
# Populated places
places:
data: {source : osm}
cities:
filter: |
function () {
return feature.kind === 'Populated place' && feature.population > 1000;
}
draw:
citydot:
size: |
function() {
// scale roughly by population
var size = global.remap(feature.population, 1000, 10000000, 25, 55);
return size;
}
color: '#0E8CC1'
order: 3
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment