myPhotoAtlas allows users to search and save photos and locations around the world. It is an application that is geared toward photography enthusiasts and adventurous travelers explore a new location. Our final product allows the user to search any location and returns a gallery of photos taken within a specific radius of that location. Additional features include the ability to get directions from Google Maps and save/delete locations and images to the my ‘myPlaces’ page. In the future we would like to incorporate a backend server and database, which will allow the user to login to their own profile. We would also like to import another API which will give the user information on their chosen locations (i.e. wikipedia etc.).
Sarah Abbey: https://github.com/sabbey37
Contributions: JavaScript and jQuery for myPlaces and Search pages. Implemented our streach goal of allowing a user to save places in local storage and displaying those locations on the myPlaces page. Developed jQuery and JavaScript functions to efficently obtain information from Flickr API and Google Maps API, including geocoding and reverse geocoding.
Katie Lane: https://github.com/MaeDae11
Contributions: Main focus was HTML, CSS, JavaScript and jQuery for myPlaces and Search pages. Focused our Flickr API search after running into roadblocks. Deployed responsive design while collaborating with team as well as consistent design throughout all pages, navigation, and footers.
Stephanie Asmar: https://github.com/stephanieasmar
Contributions: HTML, CSS & JavaScript for home and about pages, concepting/prototyping of product idea. Guided overall design and usability. Tested responsive design and implemented changes with team as needed. Ensured consistent design throughout website.
- HTML5
- CSS
- JavaScript
- JSON
- jQuery
- Bootstrap
- Google (GeoCode, Maps)
- Flickr
- Favicon
- AJAX
- Photo search gallery to feature photography across the United States
- Home page with wonderful images implemented with a carousel
- Google map
- Responsive design
- Using AJAX / localstorage to save myPlaces
- Map with functionality: info window pop up, locating where picture was taken, marking location on map, displaying multiple markers at a time, adjusting map depending where user was searching
- Implementing Google Autocomplete
- Hiding and showing of map
- Creating PostgreSQL database requiring user login to enable myPlaces to be available from different devices
Challenge: Finding quality APIs that returned necessary data. Used 3-4 before we settled on the final ones.
Solution: Learned much more about APIs. What to look for, how to search, how to retrieve the data we wanted.
Challenge: Understanding Google Maps API, using their language.
Solution: Read user documentation.
Challenge: Photo tags, getting good photos from Flickr API
Solution: Trial and error, reading up on user documentation, tutorials.
Showcases how we worked with Flickr's API and the specificity they require when working with their database.
// Searches Flickr API for images based on latitude and longitude from Google Search, sends pictues to createPicture function
function photoSearch(latLon) {
// gets radius, units and tags
var radius = getRadius();
var units = getUnits();
var tags = chooseTags();
//Creates error function w/message to be returned if no pictures found
var errorPics = errorMessage('No pictures were found for this location, radius, and tags, please try your search again.');
// Adds in tags. Tags are essential in the search process,as well as radius units. These aspects will be changed later to get respnoses from the user
var resp = $.get("https://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=" + FLICKR_API_KEY + "&lat=" + latLon["lat"] + "&lon=" + latLon["lng"]+ "&tags=" + tags + "&tag_mode=any&radius=" + radius + "&radius_units=" + units + "&format=json&nojsoncallback=1");
resp
.catch(errorPics)
.then(checkForPics)
};
//Carousel control; rotates through jumbotron images
function carouselControl() {
$(document).ready(function(){
$('.carousel').slick({
autoplay: true,
mobileFirst: true,
autoplaySpeed: 5000,
arrows: false,
pauseOnFocus: false,
pauseOnHover: false,
swipeToSlide: true,
});
});
};
This bit of code displays the use of jQuery's ease of animations to add hide and show features for our map and hamburger menu.
// ******************************
// *******REACTIVE MENUS*********
// ******************************
function clickShowMap() {
$SHOW_MAP.click(function () {
$('[data-images-role="hide-map"]').show();
printIt($(this));
$(this).hide();
$(".click-to-close").hide();
$(".click-to-open").show();
$(".map-banner-container").slideDown(1000);
});
};
function clickHideMap() {
$HIDE_MAP.click(function () {
$('[data-images-role="show-map"]').show();
$(this).hide();
$(".click-to-close").show();
$(".click-to-open").hide();
$(".map-banner-container").slideUp(1000);
});
};
// when hamburger menu icon is clicked, the hamburger icon hids, the exit icon shows and the menu-container shows slowly
function clickMenuShow() {
$HAMBURGER.click(function () {
$EXIT_ICON.show();
$(this).hide();
$(".myAtlas-logo").hide("slow");
$MENU_CONTAINER.show("slow");
});
};
// when exit icon is clicked, the exit icon hids, the hamburger menu shows, and the menu-container hids slowly
function clickExitButton() {
$EXIT_ICON.click(function () {
$HAMBURGER.show();
$(this).hide();
$(".myAtlas-logo").show("slow");
$MENU_CONTAINER.hide("slow");
});
};
Code snippit displays how listerners can be added to text inside a Google Maps marker. The code also detects whether or not the event has already been saved to myPlaces. The listener is not added if the event has been saved.
google.maps.event.addListener(infoWindow, 'domready', function() {
if (document.querySelector('[data-role="save"]')) {
document.querySelector('[data-role="save"]').addEventListener("click", function handler(e) {
e.preventDefault();
this.textContent = '\u2713Saved to myPlaces';
this.setAttribute('data-role', 'saved');
this.setAttribute('class', 'saved');
addPlace(formatted_address, picInfo, latLon);
e.currentTarget.removeEventListener('click', handler);
});
}
});
// Takes myPlaces from local storage and prints information to screen
function displayMyPlaces(myPlaces) {
var $myPlacesContainer = $('<div></div>', {
'class': 'places-container',
'data-role': 'places-container'
});
for (var key in myPlaces) {
var id = stringMaker(key);
var $place = $('<div></div>', {
'class': 'place',
'data-role': 'place',
'name': key,
'id': id
});
appendImages(myPlaces[key]["images"], $place);
var $address = $('<span></span>', {
'text': key
});
$place.append($address);
var URI = encodeURI(key);
var link = "https://maps.google.com?q=" + URI;
var $directions = $('<a></a>', {
'target': "_blank",
'rel': "noopener noreferrer",
'href': link,
'text': 'Directions'
});
$place.append($directions);
var $delete = $('<a></a>', {
'href': "#",
'text': "Delete",
'class': 'delete',
'data-role': 'delete'
});
$place.append($delete);
$myPlacesContainer.append($place);
}
$myPlacesDisplay.append($myPlacesContainer);
};
https://www.youtube.com/watch?v=LRKIs7j-9Ew