├── layout.pdf ├── images ├── image1.jpg ├── image2.jpg ├── image3.jpg ├── image4.jpg ├── image5.jpg ├── image6.jpg ├── image7.jpg └── image8.jpg ├── README.md ├── assignment-2.md ├── assignment-3.md ├── assignment-4.md ├── PhotoGalleryLib.md ├── assignment-1.md └── PhotoGalleryLib.js /layout.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juliengs/vsp2018webapp-assignments/HEAD/layout.pdf -------------------------------------------------------------------------------- /images/image1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juliengs/vsp2018webapp-assignments/HEAD/images/image1.jpg -------------------------------------------------------------------------------- /images/image2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juliengs/vsp2018webapp-assignments/HEAD/images/image2.jpg -------------------------------------------------------------------------------- /images/image3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juliengs/vsp2018webapp-assignments/HEAD/images/image3.jpg -------------------------------------------------------------------------------- /images/image4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juliengs/vsp2018webapp-assignments/HEAD/images/image4.jpg -------------------------------------------------------------------------------- /images/image5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juliengs/vsp2018webapp-assignments/HEAD/images/image5.jpg -------------------------------------------------------------------------------- /images/image6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juliengs/vsp2018webapp-assignments/HEAD/images/image6.jpg -------------------------------------------------------------------------------- /images/image7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juliengs/vsp2018webapp-assignments/HEAD/images/image7.jpg -------------------------------------------------------------------------------- /images/image8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juliengs/vsp2018webapp-assignments/HEAD/images/image8.jpg -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # VSP Web Apps 2 | 3 | ## Assignments 4 | 5 | - [Assignment 1](assignment-1.md) 6 | - [Assignment 2](assignment-2.md) 7 | - [Assignment 3](assignment-3.md) 8 | - [Assignment 4](assignment-4.md) 9 | 10 | ## Resources 11 | 12 | - All 8 images which you will use in the assignments can be found [here](images). 13 | - A basic UI wireframe is [here](layout.pdf) 14 | - The PhotoGalleryLib library is [here](PhotoGalleryLib.js) 15 | - The documentation for that library can be found [here](PhotoGalleryLib.md) 16 | 17 | ## Server 18 | 19 | The HTTP server you will use in the later assignments is hosted here: 20 | (TBD) 21 | http://165.227.3.253:3000/images 22 | -------------------------------------------------------------------------------- /assignment-2.md: -------------------------------------------------------------------------------- 1 | # Assignment 2 2 | 3 | ## Introduction 4 | 5 | This assignment is a continuation of Assignment 1. If you have successfully completed the previous assignment, you may use your own code, or you can use the sample solution for Assignment 1, posted [here](http://ece.ubc.ca/~kumseok/src/vsp2018/solutions/assignment-1.zip), to complete this assignment. 6 | 7 | In this assignment, you will make the web app responsive. That is, the app will be optimized for viewing across multiple devices and screen sizes. For this assignment, and some future ones, you will use the [PhotoGalleryLib](PhotoGalleryLib.js) library provided by us, which includes a lot of helpful functions. The documentation and some examples of how to use this library can be found [here](PhotoGalleryLib.md). 8 | 9 | ## Tasks 10 | 11 | 1. All you need to do for this task is print *to the javascript browser console* the size of the screen ("small", "medium", or "large") whenever it changes. (Hint: Look at PhotoGalleryLib.onSizeClassChange) 12 | 2. Remove the hardcoded table of images in your HTML file. We will dynamically generate it using JavaScript in this task, and add it to the DOM. Whenever the screen size changes (ex, from large to medium), the following should happen: 13 | - Delete the table of images from the DOM 14 | - Generate a new table of images for the current screen size (Hint: Look at PhotoGalleryLib.generateGrid) 15 | - Insert this new table into the DOM 16 | 17 | ## Submission Instructions 18 | 19 | - Update either your own code from Assignment 1, or the sample solution code to accommodate the required changes for this assignment. 20 | - Create a branch, and name it appropriately (eg. assignment-2) 21 | - Make sure to push your changes to that branch before midnight (11:59 PM) on the date of the assignment deadline. 22 | -------------------------------------------------------------------------------- /assignment-3.md: -------------------------------------------------------------------------------- 1 | # Assignment 3 2 | 3 | ## Introduction 4 | 5 | This assignment is a continuation of Assignment 2. If you have successfully completed the previous assignment, you may use your own code, or you can use the sample solution for Assignment 2, posted [here](http://ece.ubc.ca/~kumseok/src/vsp2018/solutions/assignment-2.zip), to complete this assignment. 6 | 7 | In this assignment, you'll implement a presentation mode. The presentation mode should be opened when you click on an image, effectively making images enlargeable. You will implement the next and previous buttons in the presentation mode to switch through various images. Finally, you'll implement an automatic slideshow, which will switch through images in the presentation mode after a set period of time. 8 | 9 | The presentation mode will be implemented using a modal window. You will use [PhotoGalleryLib](PhotoGalleryLib.js) again for this assignment. The documentation and some examples of how to use this library can be found [here](PhotoGalleryLib.md). 10 | 11 | ## Tasks 12 | 13 | 1. The presentation modal should open up when an image is clicked. The clicked image should be shown in the presentation modal. You don't need to implement the 3 buttons in the modal for this task: close, previous next. (Hint: Look at PhotoGalleryLib.createModal, PhotoGalleryLib.addImageClickHandlers, PhotoGalleryLib.openPresentationModal, and PhotoGalleryLib.setModalImgSrc functions) 14 | 2. Add click handlers for the 3 buttons in the modal, and make them functional. (Hint: Look at PhotoGalleryLib.initModal) 15 | 3. You will implement a slideshow in this task, which will start the presentation mode, and automatically switch through the images in 1 second intervals. 16 | - Add a "Start Slideshow" button in the HTML which will be the entry point for your slideshow code. 17 | - Implement a click handler for this button, which opens up the presentation mode, and uses JavaScript timers to periodically switch through the images. 18 | 19 | ## Submission Instructions 20 | 21 | - Update either your own code from Assignment 2, or the sample solution code to accommodate the required changes for this assignment. 22 | - Create a branch, and name it appropriately (eg. assignment-3) 23 | - Make sure to push your changes to that branch before midnight (11:59 PM) on the date of the assignment deadline. 24 | -------------------------------------------------------------------------------- /assignment-4.md: -------------------------------------------------------------------------------- 1 | # Assignment 4 2 | 3 | ## Introduction 4 | 5 | This assignment is a continuation of Assignment 3. If you have successfully completed the previous assignment, you may use your own code, or you can use the sample solution for Assignment 3, posted [here](http://ece.ubc.ca/~kumseok/src/vsp2018/solutions/assignment-3.zip), to complete this assignment. 6 | 7 | In this assignment, you will remove the hardcoded list of images from your code, and will also stop using the local image files stored on your computer. You will be using asynchronous requests (AJAX) to receive image URLs from a server, and use them to display the images in the grid. 8 | 9 | You will need to first get the server code from [HERE](https://github.com/jungkumseok/ubc-vsp18-server/). Follow the instructions and then confirm that you can see your client application (assignment-3) at `http://localhost:3000/`. 10 | 11 | Just to clarify, your `assignment-4` branch should look like the following: 12 | 13 | ``` 14 | /public/ 15 | /css/ 16 | /js/ 17 | /libs/ 18 | /index.html 19 | /.gitignore 20 | /index.js 21 | /package.json 22 | ``` 23 | 24 | * `index.js` and `package.json` files are from the server code we provided. 25 | 26 | * Make sure that `/public/` directory contains **your client-side code** and not the default `index.html` included in the server side code. 27 | 28 | * Make sure you have a `.gitignore` file. The file should include `**/node_modules/**` so that you do not commit the npm modules to your repository. 29 | 30 | * If you have `git clone`d the server repository, make sure you remove the `.git/` directory. 31 | 32 | 33 | ## Tasks 34 | 35 | 1. For this task, you do not need to change the code which displays images in the grid. Add code to send a GET HTTP request to `http://localhost:3000/images` endpoint which returns a list of image URLs. **Print this list of URLs to the console.** 36 | 2. For this task, you will **use the list of image URLs downloaded (via AJAX) in the previous task** to display them in the grid. 37 | 38 | ## Submission Instructions 39 | 40 | - Update either your own code from Assignment 3, or the sample solution code to accommodate the required changes for this assignment. 41 | - Create a branch, and name it appropriately (eg. assignment-4) 42 | - Make sure to push your changes to that branch before midnight (11:59 PM) on the date of the assignment deadline. 43 | -------------------------------------------------------------------------------- /PhotoGalleryLib.md: -------------------------------------------------------------------------------- 1 | # PhotoGalleryLib Documentation 2 | 3 | ## Introduction 4 | 5 | This library contains some functions which will be helpful for completing the assignments for this course. It has functions for detecting screen size changes, creating image tables of various sizes, creating modals, etc. 6 | 7 | The JavaScript file can be found [here](PhotoGalleryLib.js). 8 | 9 | Simply add a `` 12 | 13 | ## Functions 14 | 15 | - `PhotoGalleryLib.onSizeClassChange (callback)` 16 | 17 | This function is used for detecting screen size changes. This function takes a callback as an argument, which is called whenever the screen size is changed. One of the strings "small", "medium", or "large" will be passed as an argument to the callback function when the screen size is changed. Note that the callback function will only be called when the screen size changes from one size class to another (ex, small to medium). It will not be called repeatedly while the screen size is being changed within a particular size class like large. 18 | 19 | - `PhotoGalleryLib.generateGrid (imageUrls, size)` 20 | 21 | This function is used for generating a table DOM element which can be used to display a grid of images. The `imageUrls` argument is an array of image URLs which are supposed to be displayed in the table. These can be relative URLs like './images/foo.jpg' or even http URLs. The `size` argument can be one of "small", "medium", or "large". a 1x8 grid is made for small screen sizes, a 2x4 grid is made for medium screen sizes, and a 4x2 grid is made for large screen sizes. 22 | 23 | - `PhotoGalleryLib.createModal ()` 24 | 25 | This function creates a modal which can be used for presentation mode. There will be no visible effect when this function is called since the modal is closed by default. You can however inspect the DOM tree in your browser to see that a new `
` gets inserted into the body which has a CSS attribute `display:none`. 26 | 27 | - `PhotoGalleryLib.initModal (closeBtnCb, previousBtnCb, nextBtnCb)` 28 | 29 | This function is used to register click handlers for close, previous, and next buttons in the modal. The 3 arguments of this function are callbacks which are called when close, previous, or next buttons are clicked respectively. Example usage: 30 | 31 | ```javascript 32 | PhotoGalleryLib.initModal(function() { 33 | console.log("Close button was clicked"); 34 | }, function() { 35 | console.log("Previous button was clicked"); 36 | }, function() { 37 | console.log("Next button was clicked"); 38 | }); 39 | ``` 40 | 41 | - `PhotoGalleryLib.closePresentationModal ()` 42 | 43 | Closes the modal (hides it) 44 | 45 | - `PhotoGalleryLib.openPresentationModal ()` 46 | 47 | Opens the modal (makes it visible) 48 | 49 | - `PhotoGalleryLib.setModalImgSrc (src)` 50 | 51 | Sets the `src` attribute of the image in the presentation modal to the given image URL 52 | 53 | - `PhotoGalleryLib.addImageClickHandlers (callback)` 54 | 55 | This function can be used to add click handlers for the images in the grid. This function takes a callback, which is called whenever an image in the grid is clicked on. The integer index of the image is passed as an argument to the callback function. 56 | -------------------------------------------------------------------------------- /assignment-1.md: -------------------------------------------------------------------------------- 1 | # Assignment 1 2 | 3 | ## Introduction 4 | 5 | **Over the course of the whole project (over the four assignments)**, you are going to build a photo gallery which will download a list of images from a server and display them in a dynamically resizing grid. You will be able to click on any image to enter a presentation mode, and view other images using "previous" and "next" buttons. You will also eventually implement an auto slideshow mode, where images will automatically change after a certain period of time. 6 | 7 | **_Specifically, for assignment 1_, you need to the following:**: 8 | 9 | To help you get started, you will need to structure your project into the following way for the assignments. Submission instructions are given in the end of this document. 10 | 11 | - Root folder 12 | - css 13 | - (all stylesheets go in this folder) 14 | - js 15 | - (all JavaScript files go in this folder) 16 | - libs 17 | - (library files provided by us in this folder) 18 | - images 19 | - (all images go in this folder) 20 | - index.html 21 | - (this should be the entry point to your website) 22 | 23 | For this particular assignment, you will write some basic HTML and CSS to build the homepage for the web app. There is no JavaScript required for this assignment, so you will be penalized if you use JavaScript for this assignment. 24 | 25 | The file [layout.png](layout.pdf) provides a wireframe of what the user interface should look like. You are free to choose colours and fonts of your own choice. 26 | 27 | ## Tasks 28 | 29 | 1. Create the HTML layout that will be required to generate the web page provided in the screenshot. Your homepage should include the following elements: 30 | - Div (id=mainBody) 31 | - Heading 32 | - Table (id=imagesGrid) 33 | - Row 1 34 | - Cell 1 35 | - Image 1 36 | - Cell 2 37 | - Image 2 38 | - Cell 3 39 | - Image 3 40 | - Cell 4 41 | - Image 4 42 | - Row 2 43 | - ... 44 | 45 | - Notes: 46 | - You can find all 8 images in the `images` folder. 47 | - The images will likely be too big to fit on the screen, but that's OK, since that will be fixed in the next task. 48 | 49 | 2. Create a CSS stylesheet to add relevant styles that would help you design the layout for the web page. A few things to keep in mind: 50 | - The width of the content within the website (mainBody) should be 1000px. 51 | - The content (mainBody) should be centered within the web page. 52 | - The mainBody div should have a different background colour than the ``, so it stands out from the rest of the web page. 53 | - Make sure that all 8 images fit nicely inside the table. That is, they do not overflow outside the table. (Hint: You need to modify the width of the images inside the table). 54 | - The cursor should change to a 'hand' when hovered over the images. 55 | - The images should scale to 1.1 times their original size when hovered over (Hint: Look into the transform CSS property). 56 | - Add a shadow to the images when hovered over. 57 | - Make the border of the images rounded on the edges when hovered over. 58 | 59 | Note that you do not need to setup any server to host the webpage you are creating. Simply open the html page with any browser, and the webpage will be displayed. 60 | 61 | ## Submission Instructions 62 | - For each assignment, create a branch called assignment-, for ex: assignment-1, assignment-2, etc. **For this assignment, your branch name should be assignment-1.** 63 | - Make sure you push your changes to that branch before midnight (11:59 PM) on the date of the assignment deadline (**July 23, 2018 11:59 PM**). 64 | -------------------------------------------------------------------------------- /PhotoGalleryLib.js: -------------------------------------------------------------------------------- 1 | var PhotoGalleryLib = (function() { 2 | var PhotoGalleryLib = {}; 3 | 4 | var viewportSmallMin = 0; 5 | var viewportSmallMax = 600; 6 | var viewportMediumMin = 601; 7 | var viewportMediumMax = 800; 8 | var viewportLargeMin = 801; 9 | var viewportLargeMax = Infinity; 10 | 11 | var currentViewportSize; 12 | 13 | PhotoGalleryLib.onSizeClassChange = function(callback) { 14 | if (!callback) { 15 | callback = function(){}; 16 | } 17 | 18 | window.onresize = function() { 19 | var newViewportSize = getViewportSizeName(window.innerWidth); 20 | if (newViewportSize != currentViewportSize) { 21 | currentViewportSize = newViewportSize; 22 | callback(currentViewportSize); 23 | } 24 | }; 25 | 26 | currentViewportSize = getViewportSizeName(window.innerWidth); 27 | callback(currentViewportSize); 28 | }; 29 | 30 | function getViewportSizeName(width) { 31 | if ((width >= viewportSmallMin) && (width <= viewportSmallMax)) { 32 | return 'small'; 33 | } else if ((width >= viewportMediumMin) && (width <= viewportMediumMax)) { 34 | return 'medium'; 35 | } else if ((width >= viewportLargeMin) && (width <= viewportLargeMax)) { 36 | return 'large'; 37 | } else { 38 | console.error('Invalid viewport width.'); 39 | } 40 | }; 41 | 42 | /** 43 | * The 'size' argument must be one of 'small', 'medium', or 'large' 44 | */ 45 | PhotoGalleryLib.generateGrid = function(imageUrls, size) { 46 | var largeScreenGridHtml = ` 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | `; 60 | 61 | var mediumScreenGridHtml = ` 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | `; 79 | 80 | var smallScreenGridHtml = ` 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | `; 106 | 107 | var imagesGrid = document.createElement('table'); 108 | imagesGrid.id = 'imagesGrid'; 109 | if (size == 'large') { 110 | imagesGrid.innerHTML = largeScreenGridHtml; 111 | } else if (size == 'medium') { 112 | imagesGrid.innerHTML = mediumScreenGridHtml; 113 | } else { 114 | imagesGrid.innerHTML = smallScreenGridHtml; 115 | } 116 | 117 | var imageTags = imagesGrid.getElementsByTagName('img'); 118 | for (var i = 0; i < imageTags.length; i++) { 119 | imageTags[i].src = imageUrls[i]; 120 | } 121 | 122 | return imagesGrid; 123 | }; 124 | 125 | /** 126 | * Creates the presentation modal, and adds it to the body. 127 | */ 128 | PhotoGalleryLib.createModal = function() { 129 | var modal = document.createElement('div'); 130 | modal.id = 'presentationModal'; 131 | 132 | modal.innerHTML = ` 133 | 134 |