Homework 2: Vue.js Prototyping Practice
In this homework you'll practice using Vue.js (version 3 + composition API) to create a drum simulator app prototype.
The course material needed to complete this assignment was covered in classes 3-5.
Learning Objectives
- Compartmentalize functionality into components.
- Use props to pass data from parent to child components.
- Use events to pass data from child to parent components.
- Use reactive variables to store and update state.
- Use the
v-fordirective to render lists of elements. - Use watchers to react to changes in reactive variables.
- Use conditional rendering to render elements based on state.
- Use conditional styling to style elements based on state.
- Emit events from child components to parent components.
- Watch reactive variables in child components to react to changes in state.
Help & Support Resources
We want you to get the help and support you need. Use the course's support resources for help with this assignment.
Git Repository & Codespace
-
Create your assignment repository.
Visit https://landrace.infosci.cornell.edu/courses/info4340-2026fa/repos/hw2 in your browser to create your assignment repository.
-
Open your assignment repository in GitHub.
After creating your repository, visit https://landrace.infosci.cornell.edu/courses/info4340-2026fa/repos/hw2 in your browser and follow the link to open the repository on github.com
-
Open your assignment repository as a codespace.
Submission Requirements
Professionalism means meeting the client's requirements. Not doing less and not doing more.
Your submission should meet the requirements specified for this assignment and no more (or less). If you do more than the requirements, you will receive a 0 for the assignment. If you do less than the requirements, you will receive a 0 for the assignment.
Your assignment should meet the following requirements for credit:
-
Submit your own original work (design and code) for this assignment.
No credit is provided for submitting design and/or code that is taken from the course-provided examples.
-
Your code should be original. However, the structure of the code will mirror the class examples.
The structure of your code will align with the class examples. This is to be expected.
-
You are required to use the methods and techniques covered in class.
ImportantNo credit is provided for using methods that are not covered in this class.
You may not use any methods that have not been covered in class prior to the release of this assignment.
-
Your assignment's prototype should be visible in the browser and functional upon launching the development web server using Run Without Debugging.
If your assignment does not launch using this method or is not visible in the browser after launching the development server, we are unable to provide any credit.
-
All files should be in the location specified in this document for credit.
Professionalism is important. Incorrectly placed files will not be graded; no partial credit is provided either.
-
Follow the submission instructions below.
Submit all materials to your GitHub repository's main branch for this assignment. When you're finished stage, commit, and push your submission to GitHub. Then fill-out the submission form to complete your submission.
Failure to complete the submission form will result in 0 credit; no submission form = no submission. No leniency. No exceptions.
Sprint 1: An Unstyled Working Drum Simulator
Credit: ~30 points. Completion credit provided for meeting the requirements below. No partial credit is provided.
Goal: Create an unstyled, but functional drum simulator app prototype.
Requirements
Create a drum simulator app prototype that meets the following requirements:
-
Your simulator should have at least 4 audio samples (e.g. "Kick", "Snare", "Hi-Hat", "Cymbal"), but no more than 8 audio samples.
- You may use the provided audio samples (
/public/samples) or you may use your own samples. (If you use your own samples, the files should be included in your submission repository; no credit for hotlinked samples.) - You may select any samples you like, but they should be appropriate for a drum simulator.
- Adding a new sample should only require modifying a single array of samples. (If your samples are hard-coded in your template, you will receive 0 credit for this sprint.)
- You may use the provided audio samples (
-
Render each sample as a row of buttons.
- Label the row, so that the user knows which sample is represented by that row of buttons.
-
For each sample, render exactly 4 buttons to represent 4 beats/steps.
- Render the buttons in a grid-like layout, with each sample's buttons in a row.
- Next to each sample label, render 4 buttons (in 4 columns) that represent the 4 beats/steps for that sample.
- When a sample's step button is clicked, that sample is "on" for that step. When the button is clicked again, that sample is "off" for that step.
- Minimally style the buttons to indicate whether they are "on" or "off" (e.g. a different background color for "on" vs "off").
-
Implement a play/pause button that plays the drum simulator's sequence of samples in a loop.
- Play the first "column" of buttons (the first step for all samples), then the second column, then the third column, then the fourth column, and then repeat from the first column.
- When a "column" of samples is playing, visually indicate which column is currently playing (e.g. by highlighting the buttons in that column).
- If the play/pause button is clicked while the simulator is playing, the simulator should pause and stop playing the sequence of samples.
- A step's duration should be about 350 milliseconds (ms) per step. Use a
setIntervalto implement this functionality. - The audio play functionality (i.e.
new Audio(sampleFile).play()) should be implemented in theSampleButtoncomponent, not in theAppcomponent.
-
Your prototype should be largely unstyled.
- You may use CSS grid or flexbox to render the "grid" of samples, however everything else should be unstyled for this sprint.
- You may minimally use styling to indicate whether a sample button is "on" or "off" (e.g. a different background color for "on" vs "off").
- You may minimally style the currently playing column of buttons (i.e. by highlighting the buttons in that column).
- If your prototype is mostly styled for this sprint, you will receive 0 credit for the entire sprint. No exceptions. No leniency.
-
You may only use the methods covered thus far in class (classes 2-5) to implement your prototype.
- You may only use Vue.js (version 3) and its composition API to program your prototype. (These are the methods covered in class.)
- For credit, your prototype should use each of the methods we covered in class. (See the list below.) Yes, you need to each of these methods to receive credit for this sprint. No exceptions. No leniency.
- You may create your own components, pass props, use reactive variables, bind props to reactive variables, handle events, emit events, conditionally render using
v-if, conditionally style elements using:classbindings, use thev-fordirective to render lists of elements, and employ watchers to react to changes in reactive variables. - 0 credit is provided if any other methods are used to implement your prototype. No exceptions. No leniency.
Instructions
While you may use AI to complete this assignment, remember the purpose of these assignments is to practice the material from class. You will be asked to do something very similar in your first oral exam. In that exam you will not be permitted to use AI in any capacity.
You are highly encouraged to complete this assignment yourself without using AI. Doing so will help you learn the material and prepare for your first oral exam.
This assignment has been designed so that the simplest solution requires that you use each of the Vue.js methods we've covered in class.
If you find yourself stuck, review your code from the class activities and try and apply those ideas to this problem.
-
Create a
SampleButtoncomponent that represents a single sample's step button.Each sample button should know the sample file it represents (i.e.
/samples/snare.ogg). -
In the
Appcomponent, create an array of samples (i.e. sample file names). Use this list, to render the label for each sample, and additionally render a list of 4SampleButtoncomponents for each sample (in a row). -
In the
Appcomponent, remember the state of each sample's step button (i.e. whether it is "on" or "off") as a 2D array.A prop should be passed to each
SampleButtoncomponent to indicate whether that button is "on" or "off".When a sample button is clicked, update the state of that button in
App's 2D array. -
Implement the play/pause button in the
Appcomponent.When the play button is clicked, use a
setIntervalto play each column of samples in sequence (i.e. first column, second column, third column, fourth column, then repeat).When the pause button is clicked, stop the
setIntervaland stop playing the sequence of samples.Use the code to implement the play/pause functionality:
const STEP_COUNT = 4const STEP_DURATION = 350 // ms between stepsconst currentStep = ref(-1)let timer = nullfunction startPlayback() {currentStep.value = 0// TODO: play the step (i.e. play the samples that are "on" for that step)timer = setInterval(() => {currentStep.value = (currentStep.value + 1) % STEP_COUNT // loop back to the first step after the last step// TODO: play the step (i.e. play the samples that are "on" for that step)}, STEP_DURATION)}function stopPlayback() {currentStep.value = -1clearInterval(timer)timer = null}(You are required to use this code. You may not use any other methods to implement the play/pause functionality.)
-
A
SampleButtonshould always be notified fromAppwhether it's currently "playing". TheSampleButtonshould watch whether it's currently "playing" and play its sample if its status changes to "on".You may use the following code to play a sample file:
const audio = new Audio(sampleFile)audio.play() -
When a step is playing, visually indicate which column of buttons is currently playing (e.g. by highlighting the buttons in that column).
Submission
Stage, commit and push all changed files in your Git repository to the GitHub server. (All commits should reside on the main branch.)
Complete the submission form for hw2, sprint1 to submit the assignment.
The submission form asks you to check your submission. Checking your work will ensure you receive credit for this assignment. We ask you to check your submission because this is where some students lose points. It's easy to forget something and checking your work prevents the heartache of getting a 0 because your submission wasn't submitted in a way that we can access and grade it.
Sprint 2: A Styled Working Drum Simulator
Credit: ~20 points. Completion credit provided for meeting the requirements below. No partial credit is provided.
Goal: Style your functional drum simulator app prototype mostly using TailwindCSS and demonstrate your ability to use Vue.js's v-model directive.
Requirements
In this sprint, meet the following requirements (no more, no less):
-
Style your functional drum simulator app prototype using TailwindCSS.
- The primary method of styling the app should be using TailwindCSS utility classes.
- You may use a small amount of custom CSS to style your app, but the majority of the styling should be done using TailwindCSS utility classes.
- There shouldn't be much custom CSS from sprint 1 (the app was unstyled afterall), but if you do have quite a bit, you'll need to remove it and replace it with TailwindCSS utility classes for this sprint.
-
Design your app's prototype theme to be fun, joyful, playful, and energetic.
- The app should not be professional or serious.
- A good place to start is changing the entire color theme of the app.
-
Implement a playback speed control using an HTML user input element and Vue.js's
v-modeldirective.- Control the user input using only the
v-modeldirective. Do not use any other methods to control the user input. - The user should be able to control the playback speed of the drum simulator using a user input element (e.g. a slider, a number input, etc.).
- Set the default playback speed to around 350ms per step.
- The playback speed should be adjustable between 100ms and 1000ms per step.
- The playback speed should be stored in a reactive variable and used to control the
setIntervalduration for the play/pause functionality. - All HTML input elements (i.e.
<input>,<textarea>,<select>) are acceptable.
- Control the user input using only the
-
The prototype's design should be polished and complete.
- This should look like a finished product.
- The final design should employ visual design principles, especially alignment.
Instructions
-
Style your drum simulator using mostly TailwindCSS utility classes.
You may use a small amount of custom CSS, but the majority of the styling should be done using TailwindCSS utility classes.
There should be very little custom CSS from the previous sprint, but if there is, you'll probably need to remove nearly all of it and replace it with TailwindCSS utility classes for this sprint.
-
Implement a playback speed control using an HTML user input element and Vue.js's
v-modeldirective. -
Polish your app's prototype so that you would be proud to show it to a client.
tipAlignment is commonly overlooked when polishing a design. Make sure your app's components are aligned and guide the user's eye through the app's interface.
Submission
Stage, commit and push all changed files in your Git repository to the GitHub server. (All commits should reside on the main branch.)
Complete the submission form for hw2, sprint2 to submit the assignment.
The submission form asks you to check your submission. Checking your work will ensure you receive credit for this assignment. We ask you to check your submission because this is where some students lose points. It's easy to forget something and checking your work prevents the heartache of getting a 0 because your submission wasn't submitted in a way that we can access and grade it.
Contributors
Copyright © 2026:
- Kyle Harms