Google Maps API - Marker Clusterer - google-maps-markers

i just want to set some markers based on a xml file and additionally create three different marker clusterer with own icons!
the problems are:
no markers are displayed
how i have to implement three marker groups (marker clusterer) with my own icons
index.html
<html>
<head>
<title>Google Maps Integration</title>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" src="js/jquery-1.4.1.min.js"></script>
<script type="text/javascript" src="js/data.json"></script>
<script type="text/javascript" src="js/markerclusterer.js"></script>
<script type="text/javascript" src="js/markers.js"></script>
</head>
<body>
<div id="map"></div>
</body>
</html>
marker.js
$(document).ready(function() {
$("#map").css({
height: 675,
width: 659
});
var myLatLng = new google.maps.LatLng(51.918, 4.47663);
MYMAP.init('#map', myLatLng, 7);
MYMAP.placeMarkers("markers.xml"); // xml data
});
var MYMAP = {
map: null,
}
MYMAP.init = function(selector, latLng, zoom) {
var myOptions = {
zoom:zoom,
center: latLng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
this.map = new google.maps.Map($(selector)[0], myOptions);
}
// set markers
MYMAP.placeMarkers = function(filename) {
var markers = []; // create new array for marker points
$.get(filename, function(xml){
$(xml).find("marker").each(function(){
var name = $(this).find('name').text();
var address = $(this).find('address').text();
// create a new LatLng point for the marker
var lat = $(this).find('lat').text();
var lng = $(this).find('lng').text();
var point = new google.maps.LatLng(parseFloat(lat),parseFloat(lng));
// set marker new
var marker = new google.maps.Marker({position: point});
markers.push(marker);
// set marker info
var infoWindow = new google.maps.InfoWindow();
var html='<b>'+name+'</b><br>'+address;
google.maps.event.addListener(marker, 'click', function() {
infoWindow.setContent(html);
infoWindow.open(MYMAP.map, marker);
});
});
var markerCluster = new MarkerClusterer(map, markers);
});
}
google.maps.event.addDomListener(window, 'load', initialize);
marker.xml
<?xml version="1.0"?>
<markers>
<marker>
<name>Heineken Amsterdam</name>
<address>Joop Geesinkweg 5</address>
<city>Amsterdam</city>
<postcode>1096 AT</postcode>
<lat>52.3354</lat>
<lng>4.92938</lng>
</marker>
</markers>

Check out the newest version of markerclusterPlus here:
http://google-maps-utility-library-v3.googlecode.com/svn/tags/markerclustererplus/2.0.6/
There is a good doc and some examples too.

Related

Online CDN, and background color control, for this three.js examle?

This could be a continuation of What is the URL for three.js to include it online? , I guess...
I had found this example online:
https://github.com/josdirksen/learning-threejs/blob/master/chapter-08/16-load-vrml.html
To have it run from a single file (included below), so it downloads all its JS libs online, I've had to change this part:
<script type="text/javascript" src="../libs/three.js"></script>
<script type="text/javascript" src="../libs/VRMLLoader.js"></script>
<script type="text/javascript" src="../libs/stats.js"></script>
<script type="text/javascript" src="../libs/dat.gui.js"></script>
<script type="text/javascript" src="../libs/OrbitControls.js"></script>
Into this:
<script type="text/javascript" src="https://threejs.org/build/three.js"></script>
<script type="text/javascript" src="https://threejs.org/examples/js/loaders/VRMLLoader.js"></script>
<script type="text/javascript" src="https://threejs.org/examples/js/libs/stats.min.js"></script>
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.5/dat.gui.min.js"></script>
<script type="text/javascript" src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
Question 1: Is there a more appropriate CDN for VRMLLoader.js and similar libraries, so this example runs from a single .html file? I'd rather not hit three.js - then again, if I enter a fake link like https://threejs.org/examples/js/libs/dat.gui.js I get a 404 with "Read the full documentation for more information about using GitHub Pages.", so maybe it's OK now?
Anyways, when I run the file in Firefox 57.0.4 on Ubuntu 14.04, I get this:
As you can see, the background is fluorescent green, likely RGB of 0x00FF00; however, the code says:
webGLRenderer.setClearColor(new THREE.Color(0x000, 1.0));
... so I should get a black background here, instead? And if I set 0xFFF instead of 0x000 in .setClearColor, then I get a yellow background ?!
Question 2: How can I specify a background color, and have it render correctly, in this three.js example?
Here is the file threejs-16-load-vrml.html - just save it locally and open in a browser:
<!DOCTYPE html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<!-- https://raw.githubusercontent.com/josdirksen/learning-threejs/master/chapter-08/16-load-vrml.html
-->
<html>
<head>
<title>Example 08.16 - Load vrml model </title>
<!-- <script type="text/javascript" src="../libs/three.js"></script>
<script type="text/javascript" src="../libs/VRMLLoader.js"></script>
<script type="text/javascript" src="../libs/stats.js"></script>
<script type="text/javascript" src="../libs/dat.gui.js"></script>
<script type="text/javascript" src="../libs/OrbitControls.js"></script>
-->
<!-- <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/three.js/89/three.js"></script>
-->
<script type="text/javascript" src="https://threejs.org/build/three.js"></script>
<script type="text/javascript" src="https://threejs.org/examples/js/loaders/VRMLLoader.js"></script>
<script type="text/javascript" src="https://threejs.org/examples/js/libs/stats.min.js"></script>
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.5/dat.gui.min.js"></script>
<script type="text/javascript" src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<style>
body {
/* set margin to 0 and overflow to hidden, to go fullscreen */
margin: 0;
overflow: hidden;
}
</style>
</head>
<body>
<div id="Stats-output">
</div>
<!-- Div which will hold the Output -->
<div id="WebGL-output">
</div>
<!-- Javascript code that runs our Three.js examples -->
<script type="text/javascript">
// once everything is loaded, we run our Three.js stuff.
function init() {
var stats = initStats();
// create a scene, that will hold all our elements such as objects, cameras and lights.
var scene = new THREE.Scene();
// create a camera, which defines where we're looking at.
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
// create a render and set the size
var webGLRenderer = new THREE.WebGLRenderer();
webGLRenderer.setClearColor(new THREE.Color(0xFFF, 1.0));
webGLRenderer.setSize(window.innerWidth, window.innerHeight);
webGLRenderer.shadowMapEnabled = true;
// position and point the camera to the center of the scene
camera.position.x = 30;
camera.position.y = 30;
camera.position.z = 30;
camera.lookAt(new THREE.Vector3(0, 0, 0));
var orbit = new THREE.OrbitControls(camera);
var dir1 = new THREE.DirectionalLight(0.4);
dir1.position.set(-30, 30, -30);
scene.add(dir1);
var dir2 = new THREE.DirectionalLight(0.4);
dir2.position.set(-30, 30, 30);
scene.add(dir2);
var dir3 = new THREE.DirectionalLight(0.4);
dir3.position.set(30, 30, -30);
scene.add(dir3);
// add spotlight for the shadows
var spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(30, 30, 30);
scene.add(spotLight);
// add the output of the renderer to the html element
document.getElementById("WebGL-output").appendChild(webGLRenderer.domElement);
// call the render function
var step = 0;
// setup the control gui
var controls = new function () {
// we need the first child, since it's a multimaterial
};
var group;
var gui = new dat.GUI();
var loader = new THREE.VRMLLoader();
var group = new THREE.Object3D();
//~ loader.load("../assets/models/vrml/tree.wrl", function (model) {
loader.load("https://raw.githubusercontent.com/josdirksen/learning-threejs/master/assets/models/vrml/tree.wrl", function (model) {
console.log(model);
model.traverse(function (child) {
if (child instanceof THREE.Mesh) {
// child.material = new THREE.MeshLambertMaterial({color:0xaaaaaa});
console.log(child.geometry);
}
});
model.scale.set(10, 10, 10);
scene.add(model);
});
render();
function render() {
stats.update();
orbit.update();
if (group) {
group.rotation.y += 0.006;
// group.rotation.x+=0.006;
}
// render using requestAnimationFrame
requestAnimationFrame(render);
webGLRenderer.render(scene, camera);
}
function initStats() {
var stats = new Stats();
stats.setMode(0); // 0: fps, 1: ms
// Align top-left
stats.domElement.style.position = 'absolute';
stats.domElement.style.left = '0px';
stats.domElement.style.top = '0px';
document.getElementById("Stats-output").appendChild(stats.domElement);
return stats;
}
}
window.onload = init;
</script>
</body>
</html>
dat.gui.js -> dat.gui.min.js
Read attentively about THREE.Color() here.
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(0, 0, 10);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor('#fff');
document.body.appendChild(renderer.domElement);
var sphere = new THREE.Mesh(new THREE.SphereGeometry(), new THREE.MeshBasicMaterial({color: "blue", wireframe: true}));
scene.add(sphere);
var gui = new dat.GUI();
gui.add(sphere.scale, "x", .5, 2);
render();
function render(){
requestAnimationFrame(render);
renderer.render(scene, camera);
}
body{
overflow: hidden;
margin: 0;
}
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/libs/dat.gui.min.js"></script>

Dimple overlaid the new plot after selecting from a dropdown menu: Solution?

I would like to update an interactive scatter plot in dimple using a dropdown menu, however I am having some issues with this task. An example of my code is below:
<select name="xAX" id="xAX">
<option value ="Distance">Distance</option>
<option value ="Redshift">Redshift</option>
</select>
<div id ="chartContainer">
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://dimplejs.org/dist/dimple.v2.1.2.min.js"></script>
<script type="text/javascript">
var dropdown = d3.select("#xAX")
var xAX2 = dropdown.node().options[dropdown.node().selectedIndex].value;
d3.csv("tabula.csv", function(data) {
dataset = data.map(function(data) { return [
data["Object"],
+data["Redshift"],
+data["Distance"],
+data["Scale"],
data["Type"],
+data["IRAS12um"] ]; });
},
var svg = dimple.newSvg("#chartContainer", 900, 900);
var myChart = new dimple.chart(svg, data);
myChart.setBounds(100, 180, 730, 550)
myChart.showGridlines = true;
var x = myChart.addMeasureAxis("x", ["Redshift","Distance"]);
x.addOrderRule(["Redshift","Distance"]);
myChart.addMeasureAxis("y", "Redshift");
myChart.addMeasureAxis("z", "IRAS12um");
myChart.addSeries("Type", dimple.plot.bubble);
myChart.addLegend(70, 10, 610, 80, "right");
myChart.draw();
d3.select("#xAX").on("change", change)
function change() {
this.options[this.selectedIndex].value
}
myChart.draw(1000);
});
The "tabula.csv" table has X headers with Y elements per header. I would like that the x- and/or y-axis would have any possible option of the X header.
I have tried this example but it did not really make what I would like. Any help on the code or other example would be very helpful.
----- UPDATE ----
I updated the code and I can change the plot from a dropdown menu. However, the new graph is plotted on top of the old one. How the old plot can be removed?
<h2>X-Axis</h>
<select id="xAX" name="xAX">
<option value ="Distance" selected>Distance</option>
<option value ="Redshift">Redshift</option>
</select>
<div id="chartContainer">
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://dimplejs.org/dist/dimple.v2.1.2.min.js"></script>
<script type="text/javascript">
var svg = dimple.newSvg("#chartContainer", 900, 900);
var dropdown = d3.select("#xAX")
var change = function() {
var source = dropdown.node().options[dropdown.node().selectedIndex].value;
d3.csv("tabula.csv", function(data) {
var myChart = new dimple.chart(svg, data);
myChart.setBounds(100, 180, 730, 550)
var x = myChart.addMeasureAxis("x", source);
myChart.addMeasureAxis("y", "Redshift");
myChart.addMeasureAxis("z", "IRAS12um");
myChart.addSeries("Type", dimple.plot.bubble);
myChart.addLegend(70, 10, 610, 80, "right");
myChart.draw();
});
}
dropdown.on("change", change);
change();
</script>
try something like this:
<h2>X-Axis</h>
<select id="xAX" name="xAX">
<option value ="Distance" selected>Distance</option>
<option value ="Redshift">Redshift</option>
</select>
<div id="chartContainer">
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://dimplejs.org/dist/dimple.v2.1.2.min.js"></script>
<script type="text/javascript">
var svg = dimple.newSvg("#chartContainer", 900, 900);
var dropdown = d3.select("#xAX")
var xAxis;
var myChart;
var draw = function() {
var source = dropdown.node().options[dropdown.node().selectedIndex].value;
d3.csv("tabula.csv", function(data) {
myChart = new dimple.chart(svg, data);
myChart.setBounds(100, 180, 730, 550)
xAxis = myChart.addMeasureAxis("x", source);
myChart.addMeasureAxis("y", "Redshift");
myChart.addMeasureAxis("z", "IRAS12um");
myChart.addSeries("Type", dimple.plot.bubble);
myChart.addLegend(70, 10, 610, 80, "right");
myChart.draw();
});
}
var change = function() {
var source = dropdown.node().options[dropdown.node().selectedIndex].value;
xAxis.categoryFields = source;
myChart.draw();
};
dropdown.on("change", change);
draw();
</script>
This will make it so you don't have to remove the original svg objects, if you add a delay in myChart.draw(800, false); in the change function, it will animate the change.

Three.js Updating DataTextures with a renderTarget's image data

I am working on a motion detection program in Three.js which uses the difference between the current and previous frame. For now, before the subtraction, the current and the previous frame are both blurred using a Three.EffectComposer each.
The main problem is: Instead of having to blur the previous frame again, I want to use the previously blurred "current" frame as the texture in the subtraction process.
The closest I have managed to do is by using the function below to update the image.data of the Three.DataTexture. It was used in the render()-function after the Blurring composer is rendered, but before the subtraction is rendered.
Both of them were rendered to the screen with Three.CopyShader.
function getData(image) {
var canvas = document.createElement('canvas');
canvas.width = image.width;
canvas.height = image.height;
var context = canvas.getContext('2d');
context.drawImage(image, 0, 0);
return new Uint8Array(context.getImageData(0, 0, image.width, image.height).data);
}
Where the “image” is the renderer.domElement. This method feels quite inefficient and I needed to render the Blur-pass to the screen, which caused the result to flicker.
Edit 1 The current code is shown below, it blurs the current and previous images and then calculates the difference. The animate()-function is the point of interest.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Three.js Webcam Test</title>
<meta charset="utf-8">
<!-- <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
-->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
<script src="lib/three.min.js"></script>
<!-- Effect composer scripts -->
<script src = "postprocessing/EffectComposer.js"></script>
<script src = "postprocessing/MaskPass.js"></script>
<script src = "postprocessing/RenderPass.js"></script>
<script src = "postprocessing/TexturePass.js"></script>
<script src = "postprocessing/ShaderPass.js"></script>
<script src = "postprocessing/SavePass.js"></script>
<script src = "shaders/CopyShader.js"></script>
<script src = "shaders/ColorifyShader.js"></script>
<script src = "shaders/DilationShader.js"></script>
<script src = "shaders/ErosionShader.js"></script>
<script src = "shaders/HorizontalBlurShader.js"></script>
<script src = "shaders/VerticalBlurShader.js"></script>
<script src = "shaders/BlendShader.js"></script>
<script src = "shaders/passThroughShader.js"></script>
<script src = "shaders/framediffShader.js"></script>
<script src = "shaders/PawaskarPostShader.js"></script>
<!-- ----------------------- -->
<script src="lib/Projector.js"></script>
<script src="lib/CanvasRenderer.js"></script>
<script src="lib/webcam.js"></script>
<script src="lib/perspective.js"></script>
<script src="lib/stats.min.js"></script>
<script src="lib/rStats.js"></script>
<script src="lib/rStats.extras.js"></script>
<script type="text/javascript" src="lib/dat.gui.min.js"></script>
<link href="css/style.css" rel="stylesheet" type="text/css">
<link rel="stylesheet" href="http://bootswatch.com/lumen/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap-theme.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"></script>
</head>
<body>
<h1>Motion Detection (in progress)</h1>
<p>Press P to print the current frame</p>
<div id="WebGL-output">
</div>
<div id="camera" class="camera">
<div class="label"></div>
<video id="theVideo" autoplay width="640" height="480" class="webcam"></video>
<canvas id="theCanvas" width="640" height="480" class="hidden"></canvas>
</div>
<script>
var SCREEN_HEIGHT = 480;
var SCREEN_WIDTH = 640;
var values = {
detectmotion: true,
softness: 0.17,
threshold: 0.11,
color: "#ffae23",
usecolor: false,
postprocess: false,
postprocessmethod: 0,
preprocess: true,
detectedges: false,
framedifference: false,
binarydifference: false,
bufferlength: 1
};
var stats, container, video, renderer, currTexture, uniforms, camera, scene, prevTexture, prevTexture2, prevTexture3, prevTextureBuffer = [], bufferLenght,
videoContext,
prevTime;
var rS, glS, tS;
var postProcessFilters = [];
var prepScene, prepRenderTarget, prepComposer, prepPrevComposer, hBlur, vBlur, temporalShader, prevTemporalShader, prevBlur;
var modelScene, modelRenderTarget, modelComposer, passShader;
var subtractScene, subtractRenderTarget,subtractComposer, subtractShader;
//GUI variables
var gui, cPostProcessMethod, doPostProcess = false;
var frameNumber;
/** TEST **/
var BlurSave;
function init(){
frameNumber = 0;
/* INIT */
scene = new THREE.Scene();
camera = new THREE.Camera();
scene.add(camera);
webcam.updateSources(function(s){
webcam.start('theVideo',s[0]);
});
var size = SCREEN_WIDTH * SCREEN_HEIGHT;
video = document.getElementById( 'theVideo' );
videoContext = document.getElementById('theCanvas').getContext('2d');
//The textures
currTexture = new THREE.DataTexture([],SCREEN_WIDTH,SCREEN_HEIGHT);
prevTexture = new THREE.DataTexture([],SCREEN_WIDTH,SCREEN_HEIGHT);
prevBlur = new THREE.DataTexture([], SCREEN_WIDTH, SCREEN_HEIGHT);
currTexture.minFilter = prevTexture.minFilter = prevBlur.minFilter= THREE.LinearFilter;
prevTime = -1;
renderer = new THREE.WebGLRenderer();
renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
renderer.domElement.width = SCREEN_WIDTH;
renderer.domElement.height = SCREEN_HEIGHT;
renderer.autoClear = false;
document.body.insertBefore(renderer.domElement, document.body.childNodes[0]);
uniforms = {
currentTexture: { type: "t", value: currTexture },
mirrorImage: { type: "i", value: 0}
}
var geometry = new THREE.PlaneBufferGeometry(1, 1);
var material = new THREE.ShaderMaterial( {
uniforms: uniforms,
vertexShader: THREE.passThroughShader.vertexShader,
fragmentShader: THREE.passThroughShader.fragmentShader
} );
// A plane with the current video context as texture
var mesh = new THREE.Mesh(geometry,material);
mesh.material.depthTest = false;
mesh.material.depthWrite = false;
scene.add(mesh);
// COPY SHADER, used to render the current context to the screen
var effectCopy = new THREE.ShaderPass(THREE.CopyShader);
effectCopy.renderToScreen = true;
/** Preprocess stage **/
prepScene = new THREE.Scene();
prepScene.add( new THREE.AmbientLight( 0xffffff ) );
prepScene.add(mesh) // add the current quad
var renderTargetParameters = {minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBuffer: false};
//blur shaders
hBlur = new THREE.ShaderPass(THREE.HorizontalBlurShader);
hBlur.uniforms["h"].value = 1 / SCREEN_WIDTH;
hBlur.enabled = values['preprocess'];
vBlur = new THREE.ShaderPass(THREE.VerticalBlurShader);
vBlur.uniforms["v"].value = 1 / SCREEN_HEIGHT;
vBlur.enabled = values['preprocess'];
BlurSave = new THREE.SavePass(new THREE.WebGLRenderTarget(SCREEN_WIDTH, SCREEN_HEIGHT, renderTargetParameters));
//preprocess scene render pass
var renderModelPrep = new THREE.RenderPass(prepScene, camera);
var prevPassShader1 = new THREE.ShaderPass(THREE.passThroughShader);
prevPassShader1.uniforms["mirrorImage"].value = 1;
//Preprocess of the current image
//It is this prepComposer's rendertarget value I want to use in the next loop
prepComposer = new THREE.EffectComposer(renderer, new THREE.WebGLRenderTarget(SCREEN_WIDTH, SCREEN_HEIGHT, renderTargetParameters));
prepComposer.addPass(renderModelPrep);
prepComposer.addPass(prevPassShader1);
prepComposer.addPass(hBlur);
prepComposer.addPass(vBlur);
prepComposer.addPass(BlurSave);
//
// subtractComposer.addPass(effectCopy);
//Preprocess of the previous image
//Want to skip this stage
var prevPassShader = new THREE.ShaderPass(THREE.passThroughShader, prevTexture);
prevPassShader.uniforms["currentTexture"].value = prevTexture;
prevPassShader.uniforms["mirrorImage"].value = 1;
var prevBlurSave = new THREE.SavePass(new THREE.WebGLRenderTarget(SCREEN_WIDTH, SCREEN_HEIGHT, renderTargetParameters));
prepPrevComposer = new THREE.EffectComposer(renderer, new THREE.WebGLRenderTarget(SCREEN_WIDTH, SCREEN_HEIGHT, renderTargetParameters));
prepPrevComposer.addPass(renderModelPrep);
prepPrevComposer.addPass(prevPassShader);
prepPrevComposer.addPass(hBlur);
prepPrevComposer.addPass(vBlur);
prepPrevComposer.addPass(prevBlurSave);
/**------------------**/
/**---------------------------**/
/** Background Subtraction stage **/
subtractScene = new THREE.Scene();
subtractScene.add( new THREE.AmbientLight( 0xffffff ) );
var renderTargetParameters3 = {minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat, stencilBuffer: false};
//Background Subtraction shaders
subtractShader = new THREE.ShaderPass(THREE.framediffShader);
subtractShader.uniforms['currentTexture'].value = BlurSave.renderTarget; // from the preprocess
subtractShader.uniforms['previousTexture'].value = prevBlurSave.renderTarget; //modelled background
//Background subtraction scene render pass
var renderSubtract = new THREE.RenderPass(subtractScene, camera);
//Background subtraction Composer
subtractComposer = new THREE.EffectComposer(renderer, new THREE.WebGLRenderTarget(SCREEN_WIDTH, SCREEN_HEIGHT, renderTargetParameters3));
subtractComposer.addPass(renderSubtract);
subtractComposer.addPass(subtractShader);
//subtractComposer.addPass(effectCopy2);
/**------------------------------**/
/** Postprocessing stage **/
//Dilation
var dilationFilter = new THREE.ShaderPass(THREE.DilationShader);
dilationFilter.enabled = values['postprocess'];
postProcessFilters.push(dilationFilter);
//Erosion
var erosionFilter = new THREE.ShaderPass(THREE.ErosionShader);
erosionFilter.enabled = values['postprocess'];
postProcessFilters.push(erosionFilter);
//Pawaskar's postprocess filter
var pawaskarFilter = new THREE.ShaderPass(THREE.PawaskarPostShader);
pawaskarFilter.uniforms['threshold'].value = values['threshold'];
pawaskarFilter.enabled = values['postprocess'];
postProcessFilters.push(pawaskarFilter);
subtractComposer.addPass(pawaskarFilter);
//Opening
subtractComposer.addPass(erosionFilter);
subtractComposer.addPass(dilationFilter);
//Closing
subtractComposer.addPass(dilationFilter);
subtractComposer.addPass(erosionFilter);
//The final result rendered to the screen
subtractComposer.addPass(effectCopy);
/**----------------------**/
animate();
}
function animate()
{
if(video.readyState === video.HAVE_ENOUGH_DATA ){
var time = video.currentTime;
if(time !== prevTime){
//Because a firefox bug when drawImage is used, need to catch NS_ERROR_NOT_AVAILABLE
try {
videoContext.drawImage(video, 0, 0,SCREEN_WIDTH,SCREEN_HEIGHT); //update the video
if(currTexture.image.data.length){
//var imgData = getData(renderer.domElement);
//var imgData = renderer.domElement.toDataURL();
// var gl = renderer.getContext();
//gl.readPixels( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, gl.RGBA, gl.UNSIGNED_BYTE, prevBlur.image.data );
//prevBlur.image.data = imgData;
// prevBlur.needsUpdate = true;
/** I want to update the prevBlur texture with the BlurSave.renderTarget! **/
prevTexture.image.data = currTexture.image.data;
prevTexture.needsUpdate = true; //updates the previous texture in the shader
}
currTexture.image.data = new Uint8Array(videoContext.getImageData(0,0,SCREEN_WIDTH, SCREEN_HEIGHT).data);
currTexture.needsUpdate = true; //updates the current texture in the shader
prevTime = time;
}catch (e) {
if (e.name == "NS_ERROR_NOT_AVAILABLE") {
console.error(e);
} else {
throw e;
}
}
}
}
prepComposer.render(0.05);
prepPrevComposer.render(0.05);
subtractComposer.render(0.05);
frameNumber++;
requestAnimationFrame(animate);
}
function getData(image) {
var canvas = document.createElement('canvas');
canvas.width = image.width;
canvas.height = image.height;
var context = canvas.getContext('2d');
context.drawImage(image, 0, 0);
return new Uint8Array(context.getImageData(0, 0, image.width, image.height).data);
}
function copyCanvas(e) {
var imgData, imgNode;
if (e.which !== 80) {
return;
} else {
imgData = renderer.domElement.toDataURL();
}
// create a new image and add to the document
imgNode = document.createElement("img");
imgNode.src = imgData;
document.body.appendChild(imgNode);
}
window.onload = init;
window.addEventListener("keyup", copyCanvas);
</script>
</body>
</html>
How can I update the prevBlur.image.data with the current image data of the BlurSave.rendertarget?
Are there any other way to update a shader's Sampler2D uniform with the value from a WebGLRenderTarget’s image data from a previous time-step?
If you want to post-process your scene with a subtraction shader that uses the difference between the current and previous frames, you can do something like the following:
First create two render targets rt1 and rt2. Set currentRT = rt1 and prevRT = rt2.
Then in your render loop, (1) render to currentRT, then (2) pass currentRT and prevRT as uniforms to your subtraction shader and render to the screen, then (3) swap the render targets.
three.js r.70

addEventListener: undefined is not a function

On my chrome browser, I've got an error:
undefined is not a function
at the line: dom.addEventListener( 'mouseup', onMouseUp, false);
I'm learning webGL and here is my actual code:
<html>
<head>
<?php include "header.php"?>
<title>Learning WebGL</title>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<script type="text/javascript" src="/glmatrix/glMatrix.min.js"></script>
<script type="text/javascript" src="../three.min.js"></script>
<script type="text/javascript" src="../requestAnimationFrame.js"> </script>
<script>
var renderer = null,
scene = null,
camera = null,
cube = null,
animating = false;
function onload()
{
var container = document.getElementById("container");
renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(container.offsetWidth, container.offsetHeight);
container.appendChild(renderer.domElement);
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(45, container.offsetWidth/container.offsetHeight, 1, 4000);
camera.position.set(0,0,3);
var light = new THREE.DirectionalLight(0xffffff, 1.5);
light.position.set(0,0,1);
scene.add(light);
var mapUrl = "/test.jpg";
var map = THREE.ImageUtils.loadTexture(mapUrl);
var material = new THREE.MeshPhongMaterial({map: map});
var geometry = new THREE.CubeGeometry(1,1,1);
cube = new THREE.Mesh(geometry, material);
cube.rotation.x = Math.PI / 5;
cube.rotation.y = Math.PI / 5;
scene.add(cube);
addMouseHandler();
run();
}
function run()
{
renderer.render(scene,camera);
if(animating){
cube.rotation.y -= 0.01;
}
requestAnimationFrame(run);
}
function addMouseHandler()
{
var mydom = renderer.domElement;
mydom.addEventlistener('mouseup', onMouseUp, false);
}
function onMouseUp(event){
event.preventDefault();
animating = !animating;
}
</script>
</head>
<body onload="onload();">
<?php include "navigation.php"?>
<div id="container" style="width:95%; height:95%; position:absolute;">
</div>
<div id="prompt" style="width:95%; height:6%; bottom:0; position:absolute;">
Click to animate the cube
</div>
</body>
</html>
I've tried changing the variable name from "dom" to "mydom" but that doesn't help.
Many thanks!

google maps api v3 draw polyline between draggable markers

I have multiple markers on google map v3. When map gets loaded it draws all marker and polyline. Initial path of the polyline would be same LatLng of each marker. When you drag marker it should draw the line between original LatLng to new position of the marker. You can move all and/or any markers on the map and each marker should have separate line showing marker's original LatLng to new position. I have done similar thing in below code but the problem is when I move marker it looses previous line of the marker. It always shows only one line of the dragged marker. How to solve this problem. Thanks in advance... Ash
<!DOCTYPE html>
<html>
<head>
<title>Marker with line example two</title>
<style type="text/css">
html {
height: 100%;
}
body {
height: 100%;
margin: 0;
padding: 0;
}
#map_canvas {
height: 100%;
}
</style>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" src="Scripts/jquery-1.10.2.min.js"></script>
<script>
var line;
var myLatlng = new google.maps.LatLng(41.7833, 5.2167);
var marker;
var lines = [];
function initialize() {
var domain = [new google.maps.LatLng(11.2583, 75.1374)];
var markers = [];
var mapOptions = {
zoom: 2,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP,
opacity: 0.2,
disableDefaultUI: true,
draggable: false
};
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
var lineCoordinates = [
new google.maps.LatLng(53.215556, 56.949219),
new google.maps.LatLng(75.797201, 125.003906),
new google.maps.LatLng(37.7833, 144.9667),
new google.maps.LatLng(-24.797201, 26.003906),
new google.maps.LatLng(27.797201, -101.003906)
];
for (i = 0; i < lineCoordinates.length; i++) {
var latLng = lineCoordinates[i],
marker = new google.maps.Marker({
position: latLng,
draggable: true,
title: i.toString(),
map: map,
});
markers.push({
key: i.toString(),
latLng: latLng
});
line = new google.maps.Polyline({
path: [latLng, latLng],
strokeOpacity: 0.8,
strokeWeight: 2,
strokeColor: '#f00',
geodesic: true
});
line.setMap(map);
lines.push(line);
google.maps.event.addListener(marker, 'drag', function (event) {
var title = this.title,
result = $.grep(markers, function (e) { return e.key === title }),
oldLatLng = result[0].latLng,
newLatLng = new google.maps.LatLng(this.getPosition().lat(), this.getPosition().lng());
line.setPath([oldLatLng, newLatLng]);
});
} //end of for loop
} //end of initialize function
</script>
</head>
<body onload="initialize()">
<div id="map_canvas" style="width: 1000px; height: 675px; margin-left: 400px; margin-top: 38px;"></div>
</body>
</html>
You were almost there. You have to make closure for variable line for event listener:
(function(line) {
google.maps.event.addListener(marker, 'drag', function (event) {
var title = this.title,
result = $.grep(markers, function (e) { return e.key === title }),
oldLatLng = result[0].latLng,
newLatLng = new google.maps.LatLng(this.getPosition().lat(), this.getPosition().lng());
line.setPath([oldLatLng, newLatLng]);
});
})(line);

Resources