require.js and three.js: Uncaught ReferenceError: THREE is not defined - three.js
I'm trying to include a threejs visual in a documentation page generated via Julia's Documenter.jl package. Unfortunately, the way Documenter currently handles javascript components is via require.js and it appears to break three.js (or its modules) with the error
Uncaught ReferenceError: THREE is not defined
My self-contained example is like this
var container = document.getElementById("three_container");
scene = new THREE.Scene();
scene.background = new THREE.Color( 0xeeeeee );
camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.x = 0;
camera.position.y = 0;
camera.position.z = 200;
camera.lookAt(scene.position);
renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0x000, 1.0);
renderer.setSize(window.innerWidth, window.innerHeight);
const frontSpot = new THREE.SpotLight(0xeeeece);
frontSpot.position.set(1000, 1000, 1000);
scene.add(frontSpot);
const frontSpot2 = new THREE.SpotLight(0xddddce);
frontSpot2.position.set(-500, -500, -500);
scene.add(frontSpot2);
scene.add(new THREE.AmbientLight(0xffffff, 1));
function createSphere(radius, segments) {
const material = new THREE.MeshStandardMaterial({
color: 0xfcc742,
emissive: 0x111111,
specular: 0xffffff,
metalness: 0.8,
roughness: 0.6,
});
return new THREE.Mesh(
new THREE.SphereGeometry(radius, segments, segments),
material
);
}
// sphere params
var radius = 1,
segments = 36,
rotation = 6;
// spheres
var sphere1 = createSphere(radius, segments);
sphere1.position.x = 35.35533905932738;
sphere1.position.y = 35.35533905932737;
sphere1.position.z = 99.99999999999999;
sphere1.scale.set(10,10,20);
sphere1.rotation.z = 3.9269908169872414;
sphere1.rotation.x = 2.137707831735906;
sphere1.rotation.y = 0.0;
sphere1.rotation.order = 'ZXY';
scene.add(sphere1);
var sphere2 = createSphere(radius, segments);
sphere2.position.x = 3.061616997868383e-15;
sphere2.position.y = 50.0;
sphere2.position.z = 74.99999999999999;
sphere2.scale.set(10,10,20);
sphere2.rotation.z = 4.71238898038469;
sphere2.rotation.x = 2.137707831735906;
sphere2.rotation.y = 0.0;
sphere2.rotation.order = 'ZXY';
scene.add(sphere2);
var sphere3 = createSphere(radius, segments);
sphere3.position.x = -35.35533905932737;
sphere3.position.y = 35.35533905932738;
sphere3.position.z = 49.999999999999986;
sphere3.scale.set(10,10,20);
sphere3.rotation.z = -0.7853981633974483;
sphere3.rotation.x = 2.137707831735906;
sphere3.rotation.y = 0.0;
sphere3.rotation.order = 'ZXY';
scene.add(sphere3);
var sphere4 = createSphere(radius, segments);
sphere4.position.x = -50.0;
sphere4.position.y = 6.123233995736766e-15;
sphere4.position.z = 24.999999999999986;
sphere4.scale.set(10,10,20);
sphere4.rotation.z = -2.220446049250313e-16;
sphere4.rotation.x = 2.137707831735906;
sphere4.rotation.y = 0.0;
sphere4.rotation.order = 'ZXY';
scene.add(sphere4);
var sphere5 = createSphere(radius, segments);
sphere5.position.x = -35.355339059327385;
sphere5.position.y = -35.35533905932737;
sphere5.position.z = 0.0;
sphere5.scale.set(10,10,20);
sphere5.rotation.z = 0.7853981633974481;
sphere5.rotation.x = 2.137707831735906;
sphere5.rotation.y = 0.0;
sphere5.rotation.order = 'ZXY';
scene.add(sphere5);
var sphere6 = createSphere(radius, segments);
sphere6.position.x = -9.184850993605149e-15;
sphere6.position.y = -50.0;
sphere6.position.z = -25.000000000000014;
sphere6.scale.set(10,10,20);
sphere6.rotation.z = 1.5707963267948963;
sphere6.rotation.x = 2.137707831735906;
sphere6.rotation.y = 0.0;
sphere6.rotation.order = 'ZXY';
scene.add(sphere6);
var sphere7 = createSphere(radius, segments);
sphere7.position.x = 35.35533905932737;
sphere7.position.y = -35.355339059327385;
sphere7.position.z = -49.999999999999986;
sphere7.scale.set(10,10,20);
sphere7.rotation.z = 2.356194490192345;
sphere7.rotation.x = 2.137707831735906;
sphere7.rotation.y = 0.0;
sphere7.rotation.order = 'ZXY';
scene.add(sphere7);
var sphere8 = createSphere(radius, segments);
sphere8.position.x = 50.0;
sphere8.position.y = -1.2246467991473532e-14;
sphere8.position.z = -75.00000000000001;
sphere8.scale.set(10,10,20);
sphere8.rotation.z = 3.141592653589793;
sphere8.rotation.x = 2.137707831735906;
sphere8.rotation.y = 0.0;
sphere8.rotation.order = 'ZXY';
scene.add(sphere8);
var sphere9 = createSphere(radius, segments);
sphere9.position.x = 35.355339059327385;
sphere9.position.y = 35.35533905932737;
sphere9.position.z = -100.00000000000001;
sphere9.scale.set(10,10,20);
sphere9.rotation.z = 3.9269908169872414;
sphere9.rotation.x = 2.137707831735906;
sphere9.rotation.y = 0.0;
sphere9.rotation.order = 'ZXY';
scene.add(sphere9);
var sphere10 = createSphere(radius, segments);
sphere10.position.x = 1.5308084989341916e-14;
sphere10.position.y = 50.0;
sphere10.position.z = -124.99999999999999;
sphere10.scale.set(10,10,20);
sphere10.rotation.z = 4.71238898038469;
sphere10.rotation.x = 2.137707831735906;
sphere10.rotation.y = 0.0;
sphere10.rotation.order = 'ZXY';
scene.add(sphere10);
// end spheres
document.body.appendChild(renderer.domElement);
//renderer.render(scene, camera);
var controls = new THREE.TrackballControls(camera);
function render() {
controls.update();
requestAnimationFrame(render);
renderer.render(scene, camera);
}
render();
I've read and tried various suggestions to make the THREE namespace available or something, but haven't had any luck. If I manually insert
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script src="https://unpkg.com/three#0.85.0/examples/js/controls/TrackballControls.js"></script>
<script src="https://unpkg.com/three#0.85.0/examples/js/Detector.js"></script>
at the top of the page <head>, everything works fine, but I cannot change the order when it's generated by Documenter. Any thoughts on how to work around this?
Edit: The requirejs configuration generated by Documenter looks like this:
// Generated by Documenter.jl
requirejs.config({
paths: {
'highlight-julia': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/languages/julia.min',
'headroom': 'https://cdnjs.cloudflare.com/ajax/libs/headroom/0.10.3/headroom.min',
'jqueryui': 'https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min',
'katex-auto-render': 'https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.11.1/contrib/auto-render.min',
'jquery': 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min',
'headroom-jquery': 'https://cdnjs.cloudflare.com/ajax/libs/headroom/0.10.3/jQuery.headroom.min',
'katex': 'https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.11.1/katex.min',
'highlight': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/highlight.min',
'highlight-julia-repl': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/languages/julia-repl.min',
},
shim: {
"highlight-julia": {
"deps": [
"highlight"
]
},
"katex-auto-render": {
"deps": [
"katex"
]
},
"headroom-jquery": {
"deps": [
"jquery",
"headroom"
]
},
"highlight-julia-repl": {
"deps": [
"highlight"
]
}
}
});
////////////////////////////////////////////////////////////////////////////////
require(['jquery', 'katex', 'katex-auto-render'], function($, katex, renderMathInElement) {
$(document).ready(function() {
renderMathInElement(
document.body,
{
"delimiters": [
{
"left": "$",
"right": "$",
"display": false
},
{
"left": "$$",
"right": "$$",
"display": true
},
{
"left": "\\[",
"right": "\\]",
"display": true
}
]
}
);
})
})
////////////////////////////////////////////////////////////////////////////////
require(['jquery', 'highlight', 'highlight-julia', 'highlight-julia-repl'], function($, hljs) {
$(document).ready(function() {
hljs.initHighlighting();
})
})
////////////////////////////////////////////////////////////////////////////////
require(['jquery', 'headroom', 'headroom-jquery'], function($, Headroom) {
// Manages the top navigation bar (hides it when the user starts scrolling down on the
// mobile).
window.Headroom = Headroom; // work around buggy module loading?
$(document).ready(function() {
$('#documenter .docs-navbar').headroom({
"tolerance": {"up": 10, "down": 10},
});
})
})
////////////////////////////////////////////////////////////////////////////////
require(['jquery'], function($) {
// Modal settings dialog
$(document).ready(function() {
var settings = $('#documenter-settings');
$('#documenter-settings-button').click(function(){
settings.toggleClass('is-active');
});
// Close the dialog if X is clicked
$('#documenter-settings button.delete').click(function(){
settings.removeClass('is-active');
});
// Close dialog if ESC is pressed
$(document).keyup(function(e) {
if (e.keyCode == 27) settings.removeClass('is-active');
});
});
})
////////////////////////////////////////////////////////////////////////////////
require(['jquery'], function($) {
// Manages the showing and hiding of the sidebar.
$(document).ready(function() {
var sidebar = $("#documenter > .docs-sidebar");
var sidebar_button = $("#documenter-sidebar-button")
sidebar_button.click(function(ev) {
ev.preventDefault();
sidebar.toggleClass('visible');
if (sidebar.hasClass('visible')) {
// Makes sure that the current menu item is visible in the sidebar.
$("#documenter .docs-menu a.is-active").focus();
}
});
$("#documenter > .docs-main").bind('click', function(ev) {
if ($(ev.target).is(sidebar_button)) {
return;
}
if (sidebar.hasClass('visible')) {
sidebar.removeClass('visible');
}
});
})
// Resizes the package name / sitename in the sidebar if it is too wide.
// Inspired by: https://github.com/davatron5000/FitText.js
$(document).ready(function() {
e = $("#documenter .docs-autofit");
function resize() {
var L = parseInt(e.css('max-width'), 10);
var L0 = e.width();
if(L0 > L) {
var h0 = parseInt(e.css('font-size'), 10);
e.css('font-size', L * h0 / L0);
// TODO: make sure it survives resizes?
}
}
// call once and then register events
resize();
$(window).resize(resize);
$(window).on('orientationchange', resize);
});
// Scroll the navigation bar to the currently selected menu item
$(document).ready(function() {
var sidebar = $("#documenter .docs-menu").get(0);
var active = $("#documenter .docs-menu .is-active").get(0);
if(typeof active !== 'undefined') {
sidebar.scrollTop = active.offsetTop - sidebar.offsetTop - 15;
}
})
})
////////////////////////////////////////////////////////////////////////////////
require(['jquery'], function($) {
function set_theme(theme) {
var active = null;
var disabled = [];
for (var i = 0; i < document.styleSheets.length; i++) {
var ss = document.styleSheets[i];
var themename = ss.ownerNode.getAttribute("data-theme-name");
if(themename === null) continue; // ignore non-theme stylesheets
// Find the active theme
if(themename === theme) active = ss;
else disabled.push(ss);
}
if(active !== null) {
active.disabled = false;
if(active.ownerNode.getAttribute("data-theme-primary") === null) {
document.getElementsByTagName('html')[0].className = "theme--" + theme;
} else {
document.getElementsByTagName('html')[0].className = "";
}
disabled.forEach(function(ss){
ss.disabled = true;
});
}
// Store the theme in localStorage
if(typeof(window.localStorage) !== "undefined") {
window.localStorage.setItem("documenter-theme", theme);
} else {
console.error("Browser does not support window.localStorage");
}
}
// Theme picker setup
$(document).ready(function() {
// onchange callback
$('#documenter-themepicker').change(function themepick_callback(ev){
var themename = $('#documenter-themepicker option:selected').attr('value');
set_theme(themename);
});
// Make sure that the themepicker displays the correct theme when the theme is retrieved
// from localStorage
if(typeof(window.localStorage) !== "undefined") {
var theme = window.localStorage.getItem("documenter-theme");
if(theme !== null) {
$('#documenter-themepicker option').each(function(i,e) {
e.selected = (e.value === theme);
})
} else {
$('#documenter-themepicker option').each(function(i,e) {
e.selected = $("html").hasClass(`theme--${e.value}`);
})
}
}
})
})
////////////////////////////////////////////////////////////////////////////////
require(['jquery'], function($) {
// update the version selector with info from the siteinfo.js and ../versions.js files
$(document).ready(function() {
var version_selector = $("#documenter .docs-version-selector");
var version_selector_select = $("#documenter .docs-version-selector select");
version_selector_select.change(function(x) {
target_href = version_selector_select.children("option:selected").get(0).value;
window.location.href = target_href;
});
// add the current version to the selector based on siteinfo.js, but only if the selector is empty
if (typeof DOCUMENTER_CURRENT_VERSION !== 'undefined' && $('#version-selector > option').length == 0) {
var option = $("<option value='#' selected='selected'>" + DOCUMENTER_CURRENT_VERSION + "</option>");
version_selector_select.append(option);
}
if (typeof DOC_VERSIONS !== 'undefined') {
var existing_versions = version_selector_select.children("option");
var existing_versions_texts = existing_versions.map(function(i,x){return x.text});
DOC_VERSIONS.forEach(function(each) {
var version_url = documenterBaseURL + "/../" + each;
var existing_id = $.inArray(each, existing_versions_texts);
// if not already in the version selector, add it as a new option,
// otherwise update the old option with the URL and enable it
if (existing_id == -1) {
var option = $("<option value='" + version_url + "'>" + each + "</option>");
version_selector_select.append(option);
} else {
var option = existing_versions[existing_id];
option.value = version_url;
option.disabled = false;
}
});
}
// only show the version selector if the selector has been populated
if (version_selector_select.children("option").length > 0) {
version_selector.toggleClass("visible");
}
})
})
Related
Loading multiple textures from different url's fails
I am trying to render textures on planes loaded from different URL's. For some reason after 2nd or 3rd image I can see in browser that loading image is stuck and it is not being rendered. Adding the code used: function init() { loadPicturesFromDirectUrl(); } function loadPicturesFromDirectUrl(currentPictureIndex) { if (currentPictureIndex === undefined) { currentPictureIndex = 0; } var picture = data.pictures[currentPictureIndex]; var loader = new THREE.TextureLoader(); loader.load(picture.url, function (texture) { renderPicture(picture, texture); currentPictureIndex++; if (currentPictureIndex > data.pictures.length - 1) { return; } loadPicturesFromDirectUrl(currentPictureIndex); }, null, function (e) { console.log(e); }); } function renderPicture(picture, texture) { var planeGeometry = new THREE.PlaneGeometry(picture.size.width, picture.size.height); var planeMaterial = new THREE.MeshBasicMaterial({ map: texture }); var planeMesh = new THREE.Mesh(planeGeometry, planeMaterial); planeMesh.position.x = picture.location.x; planeMesh.position.y = picture.location.y; planeMesh.rotateY(myzeum.toRadians(180)); scene.add(planeMesh); }
You may want to try to preload all the pictures in one function and store them in an array and render them only after all of them have been loaded. Like so: var all_textures = []; function init() { loadPicturesFromDirectUrl(); for int (i = 0; i < all_picture.length; i++) { renderPicture(data.pictures[i], all_textures[i]) } } function loadPicturesFromDirectUrl(currentPictureIndex) { if (currentPictureIndex === undefined) { currentPictureIndex = 0; } var picture = data.pictures[currentPictureIndex]; var loader = new THREE.TextureLoader(); loader.load(picture.url, function (texture) { all_textures[currentPictureIndex] = texture currentPictureIndex++; if (currentPictureIndex > data.pictures.length - 1) { return; } loadPicturesFromDirectUrl(currentPictureIndex); }, null, function (e) { console.log(e); }); } function renderPicture(picture, texture) { var planeGeometry = new THREE.PlaneGeometry(picture.size.width, picture.size.height); var planeMaterial = new THREE.MeshBasicMaterial({ map: texture }); var planeMesh = new THREE.Mesh(planeGeometry, planeMaterial); planeMesh.position.x = picture.location.x; planeMesh.position.y = picture.location.y; planeMesh.rotateY(myzeum.toRadians(180)); scene.add(planeMesh); }
Google Maps: add listener to dynamically created marker outside initialize function
I have been trying for days to add an event listener for an infoWindow to markers that are created on Ajax success. The mouseover event is never fired, so there must be something I'm doing wrong in adding the listener. The listener that does NOT work is for the marker restMarker. The dragend listener for addressMarker in the initialize() function works fine. I have tried adding the listener in multiple ways: google.maps.event.addListener(markerObject,'mouseover',function(){}) and markerObject.addListener('mouseover',function(){}). I have tried giving the restMarker global scope. I have read the following: Dynamically Adding Listeners To Google Maps Markers create event listener to dynamically created google-map marker ...and more. I have infoWindows working fine with dynamically created markers in other projects. The only difference I'm aware of in the working projects is that the markers are created in the map initialize() function instead of in an ajax success function. Am I doing anything obviously wrong? <script type='text/javascript'> var zoneMap; var currentRestMarkers = []; var markerInfoWindow; var distances = [{"fee":2,"distance":5,"available":1},{"fee":3,"distance":7,"available":1},{"available":1,"distance":9,"fee":7},{"fee":9,"available":0,"distance":10}]; var ajaxResponse = {"success":[{"duration":"11.5","name":"Backyard Bistro","lng":-78.7253,"lat":35.7989,"distance":6.64,"restId":"179"},{"lat":35.7796,"lng":-78.6758,"restId":"180","distance":7.5,"name":"Baja Burrito","duration":"13.3"},{"name":"Mi Rancho","duration":"15.6","lng":-78.6482,"lat":35.7491,"restId":"183","distance":6.32},{"lat":35.7757,"lng":-78.6363,"distance":4.67,"restId":"188","name":"El Rodeo Downtown","duration":"13.7"},{"duration":"9.2","name":"El Rodeo North","lng":-78.6262,"lat":35.8137,"distance":3.35,"restId":"189"},{"name":"Fallon's Flowers","duration":"9.1","restId":"192","distance":2.92,"lat":35.789,"lng":-78.6507},{"lng":-78.6397,"lat":35.7742,"restId":"193","distance":4.62,"name":"Fire Wok","duration":"14.1"},{"lng":-78.6131,"lat":35.8051,"restId":"194","distance":6.21,"name":"Gateway","duration":"9.8"},{"restId":"195","distance":27.99,"lng":-79.0564,"lat":35.9152,"name":"Gift Cards ","duration":"35.6"},{"name":"Jumbo China","duration":"8.5","lng":-78.6262,"lat":35.819,"distance":2.87,"restId":"197"},{"lng":-78.6456,"lat":35.8817,"restId":"198","distance":4.93,"name":"La Rancherita","duration":"12.0"},{"duration":"8.9","name":"Mami Nora's","restId":"205","distance":3.35,"lat":35.8137,"lng":-78.6271},{"distance":2.94,"restId":"209","lat":35.7883,"lng":-78.6474,"duration":"8.0","name":"Mellow Mushroom"},{"distance":7.88,"restId":"212","lng":-78.7387,"lat":35.7878,"duration":"12.3","name":"Ole Time BBQ"},{"lng":-78.6388,"lat":35.8374,"restId":"214","distance":2.23,"duration":"7.0","name":"Piola"},{"name":"The Remedy Diner 2.0 - Brunch","duration":"11.9","lng":-78.656,"lat":35.7824,"distance":4.24,"restId":"216"},{"lng":-78.656,"lat":35.7824,"restId":"217","distance":4.24,"duration":"11.9","name":"The Remedy Diner 2.0"},{"distance":7.66,"restId":"218","lng":-78.6773,"lat":35.7777,"name":"Sammy's Tap & Grill","duration":"13.4"},{"lng":-78.621,"lat":35.8238,"distance":4.39,"restId":"219","duration":"8.4","name":"Shaba Shabu"},{"name":"Spring Rolls","duration":"5.9","distance":1.88,"restId":"220","lng":-78.6409,"lat":35.8399},{"duration":"9.6","name":"Thaiphoon","restId":"222","distance":3.2,"lat":35.7845,"lng":-78.6477},{"lat":35.7776,"lng":-78.6398,"restId":"223","distance":4.3,"duration":"11.6","name":"The Big Easy"},{"lng":-78.6433,"lat":35.8364,"restId":"225","distance":1.68,"duration":"5.5","name":"The Q Shack"},{"duration":"14.4","name":"Vic's Italian","lng":-78.6356,"lat":35.7759,"restId":"226","distance":4.72},{"restId":"227","distance":1.68,"lng":-78.6433,"lat":35.8364,"name":"Which Wich North Hills","duration":"5.5"},{"lat":35.7912,"lng":-78.6799,"restId":"245","distance":5.89,"duration":"10.5","name":"The Wild Cook's Indian Grill"},{"lng":-78.6237,"lat":35.873,"restId":"301","distance":4.68,"name":"Taj Mahal North","duration":"12.9"},{"restId":"820","distance":6.29,"lng":-78.6825,"lat":35.8986,"duration":"14.5","name":"El Dorado "},{"name":"Taza Grill","duration":"12.8","restId":"821","distance":4.84,"lat":35.8693,"lng":-78.6211},{"duration":"14.9","name":"Sassool","restId":"824","distance":6.83,"lat":35.9043,"lng":-78.6567},{"lng":-78.5797,"lat":35.8477,"distance":8.45,"restId":"830","name":"Alpaca Peruvian Charcoal Chicken","duration":"13.9"},{"distance":6.21,"restId":"831","lat":35.899,"lng":-78.653,"name":"Shish Kabob Six Forks","duration":"14.1"},{"distance":2.87,"restId":"923","lng":-78.6262,"lat":35.819,"name":"Tropical Picken Chicken","duration":"8.5"},{"duration":"10.3","name":"Wicked Taco","lat":35.7852,"lng":-78.6923,"restId":"931","distance":6.48},{"duration":"14.8","name":"Despina's Cafe","restId":"1142","distance":6.31,"lng":-78.6824,"lat":35.9015},{"duration":"4.7","name":"WhichWich Crabtree","lat":35.8391,"lng":-78.6752,"distance":1.7,"restId":"1242"},{"duration":"6.3","name":"Pharaoh's Grill at North Hills","distance":1.86,"restId":"1296","lng":-78.6434,"lat":35.8403},{"name":"Pharaoh's at the Museum","duration":"12.2","restId":"1297","distance":4.43,"lat":35.7818,"lng":-78.6386},{"restId":"1298","distance":2.54,"lng":-78.6298,"lat":35.8215,"name":"Gorilla Grill","duration":"6.5"},{"name":"My Way Tavern","duration":"9.8","lng":-78.6506,"lat":35.7872,"restId":"1307","distance":3.04}]}; function initialize() { var myLatlng = new google.maps.LatLng(35.8013,-78.6409); var geocoder = new google.maps.Geocoder(); var mapOptions = { zoom: 13, center: myLatlng, panControl: false, zoomControl: true, mapTypeControl: false, scaleControl: true, streetViewControl: false, overviewMapControl: false, mapTypeId: google.maps.MapTypeId.ROADMAP }; zoneMap = new google.maps.Map(document.getElementById('map_canvas'), mapOptions); var addressMarker = new google.maps.Marker({ position: zoneMap.center, map: zoneMap, clickable: true, draggable: true, flat: true, icon: 'https://maps.google.com/mapfiles/ms/icons/blue-dot.png' }); google.maps.event.addListener(addressMarker, 'dragend', function(event) { var markerNewLatLng=event.latLng; geocoder.geocode({'latLng': markerNewLatLng}, function(results, status) { if (status == google.maps.GeocoderStatus.OK) { showAvailableRests(markerNewLatLng.lat(),markerNewLatLng.lng()); } else { console.log('Geocoder failed due to: ' + status); } }); }); } function loadScript() { var acScript = document.createElement('script'); acScript.type = 'text/javascript'; acScript.src = 'https://maps.googleapis.com/maps/api/js?libraries=places&callback=initialize'; document.body.appendChild(acScript); } function showAvailableRests(whichLat,whichLng) { var rest_list = jQuery('#rest_list'); jQuery(rest_list).empty(); jQuery('#restCount').html(''); if (currentRestMarkers.length > 0) { for (var i in currentRestMarkers) { currentRestMarkers[i].setMap(null); } currentRestMarkers = []; } var restCount = 0; for (var i=0; i < ajaxResponse.success.length; i++ ) { var iconColor = 'green.png'; var available = 1; var tierClass = 'tier1'; for (var j=0; j < distances.length; j++ ) { if (ajaxResponse.success[i].distance >= distances[j].distance) { if (distances[j].available == 0) { available = 0; } if (j === 0) { iconColor = 'yellow.png'; tierClass = 'tier2'; } else if (j === 1) { iconColor = 'orange.png'; tierClass = 'tier3'; } else if (j > 1) { iconColor = 'purple.png'; tierClass = 'tier4'; } } else { break; // if it is not greater than the shorter distance, it is not greater than longer ones either } } if (available === 0) { // if this restaurant is not available at this distance //continue; // skip the rest for unavailable iconColor = 'red.png'; tierClass = 'unavailable'; } else { restCount++; } var restDiv = jQuery(document.createElement('div')); var distanceTier = jQuery(document.createElement('span')).html(' ').addClass('distance-tier ' + tierClass).appendTo(restDiv); var restDist = jQuery(document.createElement('span')).html(ajaxResponse.success[i].distance + ' mi.').addClass('rest-distance').appendTo(restDiv); var restName = jQuery(document.createElement('span')).html(ajaxResponse.success[i].name).addClass('rest-name').appendTo(restDiv); jQuery(restDiv).appendTo(rest_list); var restMarkerPosition = new google.maps.LatLng(ajaxResponse.success[i].lat,ajaxResponse.success[i].lng); var restMarker = new google.maps.Marker({ position: restMarkerPosition, map: zoneMap, clickable: false, draggable: false, flat: true, icon: 'https://maps.google.com/mapfiles/ms/icons/' + iconColor }); currentRestMarkers.push(restMarker); google.maps.event.addListener(restMarker, 'mouseover', function(e) { console.log('mouseover event fired'); // the mouseover event is never fired!!! showRestWindow(e, ajaxResponse.success[i].name, ajaxResponse.success[i].distance); }); /*restMarker.addListener('mouseover', function() { new google.maps.InfoWindow({ content: "<div><strong>" + ajaxResponse.success[i].name + "<\/strong><br>" + ajaxResponse.success[i].distance + " miles<\/div>", disableAutoPan: true, }); markerInfoWindow.open(zoneMap, this); });*/ jQuery('#restCount').html(restCount); } } function showRestWindow(event, name, distance) { markerInfoWindow = new google.maps.InfoWindow({ content: "<div><strong>" + name + "<\/strong><br>" + distance + " miles<\/div>", disableAutoPan: true, position: event.latLng, }); markerInfoWindow.open(zoneMap); }; jQuery(document).ready(function () { loadScript(); return false; }); </script> <div id='map_container'> <div id='map_canvas'></div> </div> <div id='column_right'> <p><b>Available Restaurants: <span id='restCount'></span></b></p> <div id='rest_list'></div> </div>
OpenLayers3 : Draggable OverviewMapControl
In OpenLayers 2, in the OverviewMapControl, you can drag the "box" to move the map. You can not do this in OpenLayers 3. I've tried to implement a custom control based on https://github.com/openlayers/ol3/blob/master/src/ol/control/overviewmapcontrol.js, but you can not use goog.xxx or other fancy stuff like ol.extent.scaleFromCenter when you are not in debug ! How should I proceed ? basically, implementing drag'n drop is fairly "simple" : var dragging = null; var getMap = this.getMap.bind(this); //during ctor of a control, we have no access to the map ! $(document.body).on("mousemove", function (e) { if (dragging) { dragging.el.offset({ top: e.pageY, left: e.pageX }); } }); $(box).on("mousedown", function (e) { dragging = { el: $(e.target) }; }); $(document.body).on("mouseup", function (e) { if (dragging) { debugger; var coords = ovmap.getEventCoordinate(e.originalEvent); //TODO: taking event coordinates is not good, we must use center of the box coordinates //the problem is that ovmap.getCoordinateFromPixel(dragging.el.offset()) is not working at all because we need to adjust ovmap viewport getMap().getView().setCenter(coords); dragging = null; } });
For those interested (which does not seem to be the case at the moment :)), here is the way I solved /** * Mostly a big copy/paste from https://raw.githubusercontent.com/openlayers/ol3/master/src/ol/control/overviewmapcontrol.js * without rotation and zoom/dezoom plus some adapations from http://ol3.qtibia.ro/build/examples/overviewmap-custom-drag.html * to add the possibility to drag the box on the minimap to move the main map */ ol.control.CustomOverviewMap = function (opt_options) { var options = typeof opt_options !== 'undefined' ? opt_options : {}; this.collapsed_ = typeof options.collapsed !== 'undefined' ? options.collapsed : true; this.onCollapseOrExpand = options.onCollapseOrExpand || function () { }; this.needFirstRenderUpdate_ = this.collapsed_; //prepare the hack to render the map when uncollapsed the first time var tipLabel = typeof options.tipLabel !== 'undefined' ? options.tipLabel : 'Overview map'; this.collapseLabel_ = $('<span>\u00BB</span>').get(0); this.label_ = $('<span>\u00AB</span>').get(0); var activeLabel = (!this.collapsed_) ? this.collapseLabel_ : this.label_; var button = $('<button type="button" title="{0}"></button>'.replace('{0}', tipLabel)).append(activeLabel); button.on('click', this.handleClick_.bind(this)); //ol.control.Control.bindMouseOutFocusOutBlur(button); button.on('mouseout', function () { this.blur(); }); button.on('focusout', function () { this.blur(); }); var ovmapDiv = $('<div class="ol-overviewmap-map"></div>').get(0); this.ovmap_ = new ol.Map({ controls: new ol.Collection(), interactions: new ol.Collection(), layers: [options.tileLayer], target: ovmapDiv, view: new ol.View(opt_options.view) }); var box = $('<div class="ol-overviewmap-box"></div>'); this.boxOverlay_ = new ol.Overlay({ position: [0, 0], positioning: 'bottom-left', element: box.get(0) }); this.ovmap_.addOverlay(this.boxOverlay_); var cssClasses = 'ol-overviewmap ol-unselectable ol-control' + (this.collapsed_ ? ' ol-collapsed' : ''); var element = $('<div class="{0}"></div>'.replace('{0}', cssClasses)).append(ovmapDiv).append(button).get(0); ol.control.Control.call(this, { element: element, render: ol.control.CustomOverviewMap.render }); // deal with dragable minimap this.dragging = null; box.on("mousedown", this.onStartDrag.bind(this)); $(document.body).on("mousemove", this.onDrag.bind(this)); $(document.body).on("mouseup", this.onEndDrag.bind(this)); }; ol.inherits(ol.control.CustomOverviewMap, ol.control.Control); ol.control.CustomOverviewMap.prototype.onStartDrag = function (e) { // remember some data to use during onDrag or onDragEnd var box = $(e.target); this.dragging = { el: box, evPos: { top: e.pageY, left: e.pageX }, elPos: box.offset() }; } ol.control.CustomOverviewMap.prototype.onDrag = function (e) { if (this.dragging) { //set the position of the box to be oldPos+translation(ev) var curOffset = this.dragging.el.offset(); var newOffset = { top: curOffset.top + (e.pageY - this.dragging.evPos.top), left: curOffset.left + (e.pageX - this.dragging.evPos.left) }; this.dragging.evPos = { top: e.pageY, left: e.pageX }; this.dragging.el.offset(newOffset); } } ol.control.CustomOverviewMap.prototype.onEndDrag = function (e) { if (this.dragging) { //see ol3.qtibia.ro href at the top of the class to understand this var map = this.getMap(); var offset = this.dragging.el.position(); var divSize = [this.dragging.el.width(), this.dragging.el.height()]; var mapSize = map.getSize(); var c = map.getView().getResolution(); var xMove = offset.left * (Math.abs(mapSize[0] / divSize[0])); var yMove = offset.top * (Math.abs(mapSize[1] / divSize[1])); var bottomLeft = [0 + xMove, mapSize[1] + yMove]; var topRight = [mapSize[0] + xMove, 0 + yMove]; var left = map.getCoordinateFromPixel(bottomLeft); var top = map.getCoordinateFromPixel(topRight); var extent = [left[0], left[1], top[0], top[1]]; map.getView().fitExtent(extent, map.getSize()); map.getView().setResolution(c); //reset the element at the original position so that when the main map will trigger //the moveend event, this event will be replayed on the box of the minimap this.dragging.el.offset(this.dragging.elPos); this.dragging = null; } } ol.control.CustomOverviewMap.render = function (mapEvent) { //see original OverviewMap href at the top of the class to understand this var map = this.getMap(); var ovmap = this.ovmap_; var mapSize = map.getSize(); var view = map.getView(); var ovview = ovmap.getView(); var overlay = this.boxOverlay_; var box = this.boxOverlay_.getElement(); var extent = view.calculateExtent(mapSize); var ovresolution = ovview.getResolution(); var bottomLeft = ol.extent.getBottomLeft(extent); var topRight = ol.extent.getTopRight(extent); overlay.setPosition(bottomLeft); // set box size calculated from map extent size and overview map resolution if (box) { var boxWidth = Math.abs((bottomLeft[0] - topRight[0]) / ovresolution); var boxHeight = Math.abs((topRight[1] - bottomLeft[1]) / ovresolution); $(box).width(boxWidth).height(boxHeight); } }; ol.control.CustomOverviewMap.prototype.handleClick_ = function (event) { event.preventDefault(); this.collapsed_ = !this.collapsed_; $(this.element).toggleClass('ol-collapsed'); // change label if (this.collapsed_) { this.collapseLabel_.parentNode.replaceChild(this.label_, this.collapseLabel_); } else { this.label_.parentNode.replaceChild(this.collapseLabel_, this.label_); } // manage overview map if it had not been rendered before and control is expanded if (!this.collapsed_ && this.needFirstRenderUpdate_) { this.needFirstRenderUpdate_ = false; this.ovmap_.updateSize(); this.ovmap_.once("postrender", function () { this.render(); }.bind(this)); } //trigger event this.onCollapseOrExpand(this.collapsed_); };
I am facing difficulty to load multiple marker in google map in my code, in my code only one marker will be loaded in gmap, please give me solution
<script type="text/javascript"> var map; var mc; //marker clusterer var mcOptions = { gridSize: 10, maxZoom: 8 }; var infowindow = new google.maps.InfoWindow(); //global infowindow var geocoder = new google.maps.Geocoder(); //geocoder var address = new Array("15.8700, 74.5000", "15.871463, 74.500777", "15.871505, 74.500884", "32.7714,-97.2915");`enter code here` var content = new Array("Unit`enter code here`No1", "UnitNo42", "UnitNo43", "UnitNo44"); //min and max limits for multiplier, for random numbers //keep the range pretty small, so markers are kept close by var min = .999999; var max = 1.000001; function createMarker(latlng, text) { var marker = new google.maps.Marker({ position: latlng, map: map }); ///get array of markers currently in cluster var allMarkers = mc.getMarkers(); //check to see if any of the existing markers match the latlng of the new marker if (allMarkers.length != 0) { for (i = 0; i < allMarkers.length; i++) { var existingMarker = allMarkers[i]; var pos = existingMarker.getPosition(); if (latlng.equals(pos)) { text = text + " & " + content[i]; } } } // WHERE TO ADD: mc.addMarker(marker); //?? google.maps.event.addListener(marker, 'click', function () { infowindow.close(); infowindow.setContent(text); infowindow.open(map, marker); }); return marker; } function initialize() { var options = { zoom: 2, center: new google.maps.LatLng(21.7679, 78.8718), mapTypeId: google.maps.MapTypeId.ROADMAP }; map = new google.maps.Map(document.getElementById('map'), options); var gmarkers = []; for (i = 0; i < address.length; i++) { var ptStr = address[i]; var coords = ptStr.split(","); var latlng = new google.maps.LatLng(parseFloat(coords[0]), parseFloat(coords[1])) gmarkers.push(createMarker(latlng, content[i])); } //marker cluster mc = new MarkerClusterer(map, gmarkers, mcOptions); for (i = 0; i < address.length; i++) { geocodeAddress(address[i], i); } } </script>
var mapOptions = { center: new google.maps.LatLng(20, 77), zoom: 3, mapTypeId: google.maps.MapTypeId.SATELLITE }; var map = new google.maps.Map(document.getElementById("map_Google"), mapOptions); var allmarkers = new Array(); ; var bounds = new google.maps.LatLngBounds(); var infowindow = new google.maps.InfoWindow(); var marker, i; for (i = 0; i < markers.length; i++) { if (allmarkers.length >= i + 1) { } else { var image = { url: markers[i][3] }; marker = new google.maps.Marker({ position: new google.maps.LatLng(markers[i][1], markers[i][2]), map: map, icon: image, animation: google.maps.Animation.DROP, cursor: "default" }); marker.mycategory = "Halla"; allmarkers.push(marker); bounds.extend(marker.getPosition()); google.maps.event.addListener(allmarkers[i], 'click', (function (allmarkers, i) { return function () { //map.setZoom(21); //map.setCenter(marker.getPosition()); infowindow.setContent(markers[i][0]); infowindow.open(map, allmarkers[i]); } }) (allmarkers, i)); } map.fitBounds(bounds); });
WordPress remove manual Ajax trigger and use infinite scroll
I have a problem with my script. I want to remove the load more button and instead do an infinite scroll when I get to bottom of the page. I'm using a WordPress template and without support I'm stuck on this nonsense. What should I change to do to this script? jQuery(document).ready(function($){ var $container = $('#hentry-wrapper'); // Isotope // modified Isotope methods for gutters in masonry $.Isotope.prototype._getMasonryGutterColumns = function() { var gutter = this.options.masonry && this.options.masonry.gutterWidth || 0; containerWidth = this.element.width(); this.masonry.columnWidth = this.options.masonry && this.options.masonry.columnWidth || // or use the size of the first item this.$filteredAtoms.outerWidth(true) || // if there's no items, use size of container containerWidth; this.masonry.columnWidth += gutter; this.masonry.cols = Math.floor( ( containerWidth + gutter ) / this.masonry.columnWidth ); this.masonry.cols = Math.max( this.masonry.cols, 1 ); }; $.Isotope.prototype._masonryReset = function() { // layout-specific props this.masonry = {}; // FIXME shouldn't have to call this again this._getMasonryGutterColumns(); var i = this.masonry.cols; this.masonry.colYs = []; while (i--) { this.masonry.colYs.push( 0 ); } }; $.Isotope.prototype._masonryResizeChanged = function() { var prevSegments = this.masonry.cols; // update cols/rows this._getMasonryGutterColumns(); // return if updated cols/rows is not equal to previous return ( this.masonry.cols !== prevSegments ); }; var loadMore = $('#load-more'); var posts_per_page = parseInt(loadMore.attr('data-perpage')); var offset = posts_per_page; var totalPosts = parseInt(loadMore.attr('data-total-posts')); var author = parseInt(loadMore.attr('data-author')); var category = parseInt(loadMore.attr('data-category')); var tag = loadMore.attr('data-tag'); var datemonth = loadMore.attr('data-month'); var dateyear = loadMore.attr('data-year'); var search = loadMore.attr('data-search'); var loader = $('#posts-count').attr('data-loader'); if (!author) author = 0; if (!category) category = 0; if (!tag) tag = ''; if (!datemonth) datemonth = 0; if (!dateyear) dateyear = 0; if (!search) search = ''; // cache jQuery window var $window = $(window); // start up isotope with default settings $(window).load(function(){ reLayout(); $window.smartresize( reLayout ); if (offset < totalPosts) { $('#nav-pagination-load-more').fadeIn(200); mega_initLoadMore(); } }); function reLayout() { var mediaQueryId = getComputedStyle( document.body, ':after' ).getPropertyValue('content'); // fix for firefox, remove double quotes " //mediaQueryId = mediaQueryId.replace( /"/g, '' ); //console.log( mediaQueryId ); var windowSize = $window.width(); var masonryOpts; // update sizing options switch ( mediaQueryId ) { case 'large' : masonryOpts = { gutterWidth: 0 }; break; case 'big' : masonryOpts = { //columnWidth: 297, gutterWidth: 0 }; break; case 'medium' : masonryOpts = { //columnWidth: 269, gutterWidth: 0 }; break; case 'small' : masonryOpts = { //columnWidth: $container.width() / 4, gutterWidth: 0 }; break; case 'tiny' : masonryOpts = { //columnWidth: $container.width() / 1, gutterWidth: 0 }; break; } $container.isotope({ resizable: false, // disable resizing by default, we'll trigger it manually itemSelector : '.type-post', transformsEnabled: false, // Firefox Vimeo issue masonry: masonryOpts }).isotope( 'reLayout' ); } function mega_initLoadMore(){ loadMore.click(function(e) { $(this).unbind("click").addClass('active'); $('#posts-count').html('<img src="'+ loader +'"/>'); e.preventDefault(); mega_loadMorePosts(); }); } function mega_reLayout(){ $container.isotope( 'reLayout' ); } function mega_loadMorePosts(){ jQuery.ajax({ url: megaAjax.ajaxurl, type: 'POST', data: { action : 'mega_ajax_blog', nonce : megaAjax.nonce, category: category, author: author, tag: tag, datemonth: datemonth, dateyear: dateyear, search: search, offset: offset }, success: function( data ) { var $newElems = $(data); // ensure that images load before adding to masonry layout $newElems.imagesLoaded( function(){ // FitVids $('.fluid-video, .entry-content', $newElems).fitVids(); $container.append($newElems).isotope( 'appended', $newElems ); // Flex Slider $('.flexslider', $newElems).flexslider({ animation: "fade", slideshow: false, keyboard: false, directionNav: true, touch: true, prevText: "", nextText: "" }); setTimeout(function(){ mega_reLayout(); }, 1000); offset = offset + posts_per_page; loadMore.removeClass('active'); if (offset < totalPosts){ $('#posts-count').text(''); loadMore.bind("click", mega_initLoadMore()); } else { setTimeout(function(){ loadMore.parent().remove(); }, 1000 ); } }); } }); return false; } });
I think this script is taken from "HEAT WORDPRESS THEME" directly which is located in js folder of the theme. Its simple to modify,you just need to remove Ajax post loading function and keep Isotop initializing function only. For help see this link http://www.shambix.com/en/isotope-twitter-bootstrap-infinite-scroll-fluid-responsive-layout/