|
<!DOCTYPE html> |
|
<html> |
|
<head> |
|
<meta charset='utf-8'> |
|
<meta http-equiv='X-UA-Compatible' content='IE=edge'> |
|
<style> |
|
html, body { |
|
background: #ffffff; |
|
font-family: Helvetica, Arial, Tahoma, sans-serif; |
|
margin: 0; |
|
padding: 0; |
|
} |
|
|
|
path { |
|
fill: none; |
|
stroke: #343434; |
|
} |
|
.result { |
|
fill: none; |
|
stroke: #343434; |
|
stroke-width: 4px; |
|
} |
|
|
|
h1,h2,h3 { |
|
padding-left: 140px; |
|
padding-top: 0px; |
|
} |
|
</style> |
|
</head> |
|
<body> |
|
<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink= 'http://www.w3.org/1999/xlink' height=1500 width=1050> |
|
<defs> |
|
<filter id="filter-map" x="-0.15000001" y="-0.15000001" width="1.3" height="1.3" color-interpolation-filters="sRGB" > |
|
<feGaussianBlur stdDeviation="8" in="SourceGraphic" result="result1" id="feGaussianBlur4202" /> |
|
<feTurbulence type="fractalNoise" baseFrequency="0.1" numOctaves="3" result="result0" id="feTurbulence4204" /> |
|
<feDisplacementMap in2="result0" scale="20" xChannelSelector="R" yChannelSelector="G" in="result1" result="result2" id="feDisplacementMap4206" /> |
|
<feGaussianBlur stdDeviation="1" in="SourceGraphic" result="result4" id="feGaussianBlur4208" /> |
|
<feComposite in2="result2" operator="arithmetic" k1="0.2" k2="-0.15" k3="0.8" k4="0" in="result4" result="result5" id="feComposite4210" /> |
|
</filter> |
|
</defs> |
|
</svg> |
|
|
|
<h3>Fog of War - Click to remove fog</h3> |
|
<em>Note: this is not designed to be performant; this is just an example of how filters and masks can be used</em> |
|
|
|
<script src='http://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js'></script> |
|
|
|
<script> |
|
|
|
(function setupMap(){ |
|
// 0. setup groups |
|
// ---------------------------------- |
|
var svg = d3.select('svg'); |
|
var wrapper = svg.append('g').attr({ 'class': 'map-wrapper'}); |
|
var background = wrapper.append('g').attr({ 'class': 'background'}); |
|
var characters = wrapper.append('g').attr({ 'class': 'characters'}); |
|
|
|
// 1. Setup the mask |
|
// ---------------------------------- |
|
var maskGroup = svg.select('defs').append('mask') |
|
.attr({ id: 'map-mask' }); |
|
|
|
// 2. Add map images |
|
// ---------------------------------- |
|
// fog version - grayscaled and dark |
|
var fogMap = background.append("image") |
|
.attr({ |
|
// TODO: use difference background image |
|
'xlink:href': 'http://vasir-assets.s3.amazonaws.com/fog-of-war/map-dark.jpg', |
|
'preserveAspectRatio': 'none', |
|
'class': 'fog', x: 0, y: 0, |
|
height: '100%', width: '100%' |
|
}); |
|
|
|
// full version |
|
var visibleMap = background.append("image") |
|
.attr({ |
|
// TODO: use difference background image |
|
'xlink:href': 'http://vasir-assets.s3.amazonaws.com/fog-of-war/map.jpg', |
|
'preserveAspectRatio': 'none', |
|
'class': 'visibleArea', x: 0, y: 0, |
|
height: '100%', width: '100%' |
|
}) |
|
.style({ |
|
// fill with full version of map |
|
fill: '#336699', mask: 'url(#map-mask)' |
|
}); |
|
|
|
// 3. Add a starting circle to break the fog |
|
// ---------------------------------- |
|
// create a masked path to show visible nodes |
|
var vertices = []; |
|
|
|
function updateFog(){ |
|
var masks = maskGroup.selectAll('.breakFog') |
|
.data(vertices); |
|
|
|
var newMasks = masks.enter() |
|
.append('circle') |
|
.style({ |
|
fill: '#000000', |
|
opacity: 1 |
|
}); |
|
|
|
// update existing masks |
|
masks |
|
.attr({ |
|
'class': 'breakFog', |
|
cx: function(d){ |
|
|
|
console.log(d); |
|
return d.x; }, |
|
cy: function(d){ return d.y; }, |
|
filter: 'url(#filter-map)', |
|
r: function(d){ |
|
var r = 220; |
|
return r; |
|
} |
|
}).style({ fill: '#ffffff', opacity: 1 }); |
|
|
|
masks.exit().remove(); |
|
|
|
|
|
// add sprites |
|
// ------------------------------ |
|
/* |
|
var sprites = characters.selectAll('.character') |
|
.data(vertices); |
|
|
|
var races = ['darkelf.gif', 'human.gif', 'elf.gif', 'mimirian.gif']; |
|
|
|
sprites.enter() |
|
.append("image") |
|
.attr({ |
|
'class': 'character', |
|
'xlink:href': 'http://vasir-assets.s3.amazonaws.com/fog-of-war/' + |
|
races[vertices.length % races.length], |
|
'preserveAspectRatio': 'none', |
|
x: function(d){ return d.x - 53/2; }, |
|
y: function(d){ return d.y - 53/2; }, |
|
height: 53, width: 53 |
|
}); |
|
sprites.exit().remove(); |
|
*/ |
|
}; |
|
|
|
// Call it immediately |
|
updateFog(); |
|
|
|
// then, call whenever a point is added |
|
wrapper.on('click', function(){ |
|
vertices.push({ |
|
x: d3.event.clientX, |
|
y: d3.event.clientY |
|
}); |
|
updateFog(); |
|
}); |
|
|
|
wrapper.append('rect').attr({ x:0, y: 0, width: 20, height: 20 }).style({ }).on('click', function(){ |
|
setTimeout(function(){ |
|
vertices.pop(); vertices.pop(); |
|
updateFog() |
|
}, 200); |
|
}) |
|
|
|
let clickedI = 0; |
|
let coords = [ |
|
[100, 200], |
|
[400, 20], |
|
[500, 400], |
|
[100, 400], |
|
[670, 600], |
|
[800, 400], |
|
[1000, 200], |
|
[700, 50], |
|
[500, 100] |
|
] |
|
setTimeout(function () { |
|
coords.forEach(function (d, i) { |
|
setTimeout(function () { |
|
console.log('clicked', i); |
|
vertices.push({ |
|
x: coords[i][0], |
|
y: coords[i][1] |
|
}); |
|
updateFog() |
|
}, i * 400); |
|
clickedI++; |
|
}) |
|
}, 500) |
|
|
|
|
|
|
|
})(); |
|
</script> |
|
|
|
</body> |
|
</html> |