Visual effects with fragment shaders
Last active
April 18, 2017 16:08
-
-
Save tafsiri/e9550432d05ab2c7b9e8ba612e969b33 to your computer and use it in GitHub Desktop.
Tangram Firefly Map
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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> | © 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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment