Focused Breathing


title: focused breathing - A CSS animation to help with meditation and focused breathing exercises
published: false
description: My submission to the DigitalOcean App Platform Hackathon!
tags: dohackathon, css, javascript

What I built

My Digital Ocean / DEV hackathon submission is *focused breathing* a CSS animation to help with meditation and focused breathing exercises.

Category Submission

Program for the People

App Link

http://www.shannoncrabill.com/focused-breathing or

https://focused-breathing-ogh7t.ondigitalocean.app/

Screenshots

Screenshot of focused breathing in its default state.

https://i1.wp.com/dev-to-uploads.s3.amazonaws.com/i/58lh7qq52nv5258y9st2.png?w=640&ssl=1

The timing of the animation (expanding, holding and contracting) is set to 8 seconds by default. The timing can be changed using the input field.

Here’s a video of the app in action.

https://i1.wp.com/dev-to-uploads.s3.amazonaws.com/i/3qy903gwz9cfkz9siett.gif?w=640&ssl=1

Description

focused breathing includes a circle div that expands for 2 seconds, holds it’s shape for 2 seconds, then contracts to its original size for 4 seconds. The breathing exercise involves inhaling through the nose as the circle expands. Holding the breath. Then exhaling through the mouth as the circle contracts.

Link to Source Code

https://github.com/scrabill/focused-breathing

Permissive License

MIT

Background

(What made you decide to build this particular app? What inspired you?)

I recently learned about focused breathing exercises as part of a meditation or calming routine. I kept forgetting the timing of how long to inhale, hold long do I hold, etc. So, I decided to make a little app to help me with the pacing.

I’ve been having fun experimenting with CSS animations and thought this would be an excellent opportunity to learn about the animation property, transitions, and @keyframes.

How I built it

(How did you utilize DigitalOcean’s App Platform? Did you learn something new along the way? Pick up a new skill?)

I built *focused breathing* in two parts. The first version was an experiment with CSS animations and @keyframes. I wanted to see if I could achieve the transitions and cadence I wanted with only HTML and CSS. It was possible! No Javascript was needed for the original version, which can be found on CodePen.

For the second part, I wanted to see if I change the duration of the animation (which is in the CSS file) based on input from the user. I know I could get input values from the HTML file with Javascript, but could I pass those updated variables back to the CSS and render it to the page. It turns out this was possible too!

Here’s how I approached building parts one and two and what I learned along the way.

Part One – HTML & CSS

Before I started coding, I was helpful for me to write down high-level steps of the focused breathing technique I had been taught.

It goes like this.

  • Inhale through the nose
  • Hold the breath
  • Exhale through the mouth for 4 seconds

The amount of time to inhale of hold the breath may not matter, but to make it easier from a coding perspective, 2 seconds to inhale and 2 seconds to hold a breath seemed reasonable.

Visually, there would be a small to medium sized circle that would expand, cueing you inhale and contract when it was time to exhale.

Visualizing the Animation

Using @keyframes was the best want to handle the expanding and contracting of the circle so that I control the timing and pacing of each step. With @keyframes the stops or offsets range between 0% and 100%. The beginning or start of the animation would be 0% stop and the end would be 100%. Or, any number in between.

I’ve worked with @keyframes on other projects and had a difficult time visualizing what code I needed to write to achieve what I visualized in my mind.

It makes sense to map out what I wanted to happen like a timeline. A line segment with two endpoints could represent the timeline of the animation. The left endpoint would be the beginning of the animation cycle and the right, the end.

Some quick labels, notes and visuals and I have a timeline that looks like this.

https://i1.wp.com/shannoncrabill.com/blog/wp-content/uploads/2020/12/step3.png?resize=640%2C86&ssl=1

Translating the Timeline to @keyframes

Looking at the timeline above, it may look like we need 8 or 4 steps in the animation, but this is not the case. Each offset point in a @keyframe animation is a point where properties can be changed from their original values.

The circle starts small, then it’s changed to be larger than it was originally, then it holds that size, then it shrinks down to the size it was originally and the animation starts over. The @keyframe only needs 2 offset points (at the 25% and 50% marks) and the original styling of the circle handles the starting (and ending) visuals.

Similar to grouping other CSS attributes, multiple properties and offsets can be set at one time within the @keyframe declaration.

@keyframes breath {
 25%, 50% {
    background-color: lightpink;
    width: 200px;
    height: 200px;
    border-radius: 100px;
 }   
}

And, to make it a bit easier on ourselves, let’s divide the line into 8 even parts (1 part for each second of the animation).

The timing of the changes and width and height of the circle meant that I couldn’t

The expanding and contracting of the circle can be handled with @keyframes.

https://codepen.io/scrabill/pen/QWKgRMr

Part 2 – Javascript

For the second part of this project, I wanted to add some customization. To start, I wanted to see if I could change the duration of the animation—which was 8s to start—to another value. Building an input field was straight forward, but how could that value get updated in the animation property?

In doing some Googling, I was reminded that CSS variables could be accessed and updated with Javascript using getComputedStyle and getPropertyValue. I was already using CSS variables for colors and sizes, so created a new one for timing.

:root {
    --timing: 8s;
}

And updated my animation property to include that variable (var(–timing)) instead of the hardcoded value (8s)

animation: breath var(--timing) ease infinite none running

Visually, nothing changed, which meant it worked! I could double check the value of --timing by running the following in the Console.

getComputedStyle(document.documentElement).getPropertyValue('--timing') // 8s

And I could change it with the following and see the animation speed up dramtically.

document.documentElement.style.setProperty('--timing', '1s');

Then, by adding an input field onto the page, I could grab the value of that input, pass it into .setProperty and update the CSS.

Wrap Up

Overall, I learned a lot about @keyframes with this project! Drawing out what I had in mind made coding go smoother with less trial and error.

Looking back at this project, I tried for the first time, or became more comfortable with:

  • CSS Grid (centering things, amiright?)
  • CSS Animations (the animation and @keyframes property)
  • Manipulating CSS variables with Javascript ( getComputedStyle and getPropertyValue)
  • Continuous deployment (yikes to manually copy and pasting files like I usually do)

For future enhancements, some thoughts are:

  • The ability to change other variables (hold time is longer, shorter, etc)
  • The ability to start and stop (or, incorporate a timer for 5 mins of focused breathing, etc)
  • Sounds or music so accompany to indicate when you breath in, breath out, etc.
  • A detailed tutorial on how to build your own focused breathing animation/app from scratch
  • CSS grid
  • CSS Variables
  • CSS Animations
  • Javascript
  • Redirect

Learned

  • Did not need to use setTimout for initial build Can change CSS variable with javascript

Additional Resources/Info

Automatically Open the Current Directory in VS Code From Terminal

Last year, I was blown away by some Terminal commands that I learned. My favorite one is open . to open a Finder window for whichever directory you are currently in.

At one point I had a similar command to instantly open a folder in VS Code (Visual Studio Code), but deleted it after I switched from VS Code to Atom. I’ve since switched back to VS Code and after begrudgingly dragging folders into VS Code to open them, I decided to figure out how to enable that command.

Luckily, it’s takes a few steps to activate.

  • With VS Code running, enter Command + Shift + P to open the Command Palette (or View > Command Palette from the menu bar)
  • A search bar will open up. Search for “Shell” or “Shell Command” and you should see one named Shell Command: install "code" command in PATH.
  • Select it and a confirmation Shell command "code" successfully installed in PATH. should pop up (for me the pop up appeared in the lower, righthand corner).
  • If you already have a Terminal session running, quit or restart it.
  • When you are in the directory of the files you want to open in VS Code, type code . (that is the word “code” followed by a space, then a period) and the folder will automatically open in VS code.

Engineering Blogs to Follow

There is more to being in tech than coding. Coding, yes you need it to grow your technical skills, but there’s more than that.

One concept I’ve struggled with is not knowing what to learn next.

I got the 100 level concepts. But did not know how to get to level 200. Or what level 200 even looked like. This made it easy to fall into tutorial hell.

It’s like, yes, you know the basics. You know how to code. But what does coding look like outside the confines of a personal project? What does it look like at scale? Thinking even further ahead, what does it look like at a large, global (planetary!) company?

And it’s difficult to see what that could look like, without already being on the inside of those companies.

Lucky, some companies give us peak.

Keyframes

I’ve been experimenting with CSS Animations recently. One aspect of animation that I had a difficult time grasping was the @keyframes syntax. While I understood @keyframes as stops or points in the lifecycle of the animation, it was difficult to translate what I visualized into workable code.

While coding an animation to help with focus breathing exercises, I decided to sketch out what animation changed I wanted, before coding. I wanted to see if this approach would work better than trying offsets and hoping for the best.

In this post, I’ll outline how I visualized my idea for animation and broke it into smaller steps that would be coded as steps in the animation.

Focused Breathing

Before I get into coding or drawing out any ideas, it was helpful to me to write down high-level steps of what I wanted my animation to be. I was basing my animation on a 4-second breathing technique I recently, learned, which goes like this

  • Inhale through the nose
  • Hold the breath
  • Exhale through the mouth for 4 seconds

The amount of time to inhale or hold the breath may not matter, but to make it easier for this project, 2 seconds to inhale and 2 seconds to hold a breath seemed reasonable.

For the animation it’s self, I visualized a circle that would expand, cueing you inhale and contract when it was time to exhale.

Visualizing the Animation

With @keyframes the stops or offsets range between 0% and 100%. The beginning or start of the animation would be 0% stop and the end would be 100%. Or, any number in between.

It makes sense to map out what I wanted to happen like a timeline. A line segment with two endpoints could represent our timeline. And, to make it a bit easier on ourselves, let’s divide the line into 8 even parts (1 part for each second of the animation).

And labels for which sections represent inhaling, holding a breath and exhaling.

And some quick representations and notes on what the circle should look like at each step on the timeline.

Now that we have drawn out what we want our animation to look like, we are almost ready to start coding.

Translating the Timeline to @keyframes

Looking at the timeline, it may look like we need 8 or 4 steps in the animation, but this is not the case. Each offset point in a @keyframe animation is a point where properties can be changed from their original values.

The circle starts small, then it’s changed to be larger than it was originally, then it holds that size, then it shrinks down to the size it was originally and the animation starts over. The @keyframe only needs 2 offset points (at the 25% and 50% marks) and the original styling of the circle handles the starting (and ending) visuals.

Here’s the CSS for my circle (div) as a reference.

div{
    background-color: lightsteelblue;
    width: 10px;
    height: 10px;
    border-radius: 5px;
}

Which looks like this.

That’s a small, light purple circle.

To apply @keyframes to that circle, we use the animation property, which takes in multiple values including breath which is we’ll call our @keyframe animation.

div{
    background-color: lightsteelblue;
    width: 10px;
    height: 10px;
    border-radius: 5px;
    animation: breath 8s ease infinite none running;
}

Now we can write the code for our @keyframes. The format is like this

@keyframes nameofanimation {
 offset {
    property: value;
 }   
}

Multiple properties can be changed and multiple offsets can be set at one time. For our animation, we can group the changes to the size of the circle together in one offset declaration in our @keyframe

@keyframes breath {
 25%, 50% {
    background-color: lightpink;
    width: 200px;
    height: 200px;
    border-radius: 100px;
 }   
}

At the 25% and 50% points in the animation, the circle will look like this.

That’s a much larger, light pink circle.

Going back to the animation: breath 8s ease infinite none running; property we added, 8s is how long the animation (from 0% to 100%) will run. So, 25% would be 2 seconds, in, 50% would be 4 seconds in and so forth.

Putting everything together, here’s what our animation looks like.

See the Pen Focused Breathing by Shannon Crabill (@scrabill) on CodePen.

Conclusion

Going back to my idea that sketching each step of the animation before coding, did save me a lot of time and trial and error when came to writing the code for the @keyframe. As I experiment with more complex animations, jotting it down on paper first will help me to clarify my thoughts and work through any conflicts. Overall, it took one correction before I got the effect I wanted. This process reminded me of pseudo coding which is something I had gotten out of the habit of doing lately.

Resources

Orphan Branches in Git

You may run into a situation where a branch of a project doesn’t need to share history with the main branch. I had this happen when I wanted to create a temporary-landing page for a project I was working on deploying. The landing page would be a “coming soon” page with a short blurb, hosted on the domain the project will eventually live on. I had been working on this project for months, including building React for the frontend and Ruby on Rails for the backend. That’s a lot of files and git history for a temporary, static landing page.

I did some Googling and learned that git supports orphan branches. An orphan branch, not surprisingly, has no parents (meaning, git history) when it is created. The history of the orphan branch is separate from other branches in the repository, including the main or root branch it was created from.

Here’s a quick example of how to create an orphan branch and use cases.

Creating an Orphan Branch

In your project repository an orphan branch can be created with the following Terminal command.

git checkout --orphan BRANCH-NAME

In my case, I want my new branch to be named landing-page. With the git checkout --orphan landing-page command, a landing-page branch is created and checked out.

At first, nothing will look different than if we created a branch without the --orphan flag.

While on your orphan branch, running git log will return your current branch 'landing-page' does not have any commits yet. Whereas git log on your main brain will return a list of all previous commits and commit messages.

In a use case like mine where your orphan branch does not need the files from the previous branch, type git rm -rf . to remove all content from that branch.

Note that this will also delete your .gitignore file so you’ll to have create a new one, if it’s needed.

Use Cases

What I liked about creating an orphan branch for the landing page, was that it made for one less repository or set of files to keep track of. I can still commit changes on the landing-page branch and push them to a remote server just like my main or primary branch.

Another plus is that apps like continuous deployment solutions like Digital Ocean or Netlify allow you to select which branch in your git repository it should deploy. Later, when I’ve finished my app on the main branch, I can make that the branch it listens to without having to do any additional configuration.

Resources