Sammy's Portfolio

What?

The predictable tale of how I didn't go into STEM

Showcases:

Pure CSS, CSS animations

Idea: to tell you a bit about me, make a fun throwback to my PC past, and practise pure CSS

Approach: "Form1" was constructed using formatted divs and a radial gradient for the dotted background. Delayed animations were used to co-ordinate the typing effect, image carousel, and the story itself.

Challenges: The animations were fiddly but do-able. The main challenge was making the site responsive whilst maintaining proportions and the formatting which underpins the animations.

Room to improve: Currently portrait mode on mobile prompts the user to rotate their device for the best view. I would refactor the page to make a portrait version. Alternatively, I'm keen to explore telling a story in different ways, for example scrollytelling.

What?

An interface to allow a user to read French by hovering over words and phrases for an instant translation

Showcases:

HTML, CSS, vanilla JS

Idea: my great love in life is languages (I speak 5!) and I'm a particular advocate of learning by reading. I wanted to try out an idea to enable complete beginners to start reading in French.

Approach: a Javascript array of objects [{"french": __, "english":___}] acts as the dictionary. Words or phrases in the story are designated as translatable by means of a span around them. On hover, a mouseover event looks up the contents of the relevant span in the dictionary and makes a pop-up translation visible.

Challenges: one challenge was that I didn't want to only let the user translate individual words, but wanted to offer translations and context for word pairs or phrases, where that was more helpful. I achieved this by placing a span around each translatable 'block', be that a word or a phrase, and the logic centring around the content of these spans.

Another challenge was dynamically positioning the pop-up translation so that it appeared centred above the word the user hovered on, and didn't cause an overflow in corner cases. I achieved this using various JS conditions and calculations with reference to the position of the span hovered over and injecting a style attribute to the pop-up. I also had to adapt that positioning for mobile.

Room to improve: this was a concept interface using only a small passage of text and still the makeshift dictonary ran to 87 items! The use of a span to demarcate translatable blocks within the html was also unwieldy. This was the very first project I completed and once I learn more back-end I would love to refactor it to make use of databases and a cleaner data structure.

What?

An interface which uses Google Books API to allow a user to make a collage of book covers

Showcases:

React, API use

Idea: I'm in a lot of online reading groups, and people love to make and share collages of books they've read - but this often involves looking up the books individually, saving the cover images, and making your own collage. For my first React app, I wanted to make the process quicker! I also wanted to incorporate my first API data.

Approach: The app uses the Google Books API to fetch book covers matching a user's search. The user can then add or remove covers from their collage, change the order, customise the look of their collage, and add captions and star ratings.

Challenges: With so many customisation options and seven components, the most challenging element was definitely state management, and controlling the passage of props such that every component had access to the data and functions it needed. Ironically, I recall wishing there was an easier, more central way to store my data... enter Redux ;)

Room to improve: the big missing feature here is the ability to download the collage (currently users have to print screen). I had CORS vs canvas issues which - after several days of hairpulling on Google - I felt couldn't be solved client-side. I'd love to come back to this project one day and put that right!

Having also since learnt Redux and learnt greater economy in React, I would also definitely implement cleaner state management and cleaner code in general (for example favouring functional components and hooks over class components and constructors) in future.

What?

A solitaire card game

Showcases:

React-Redux, Redux Toolkit

Idea: I used to love playing this card game as a child, but the cards would end up in order, which was a hassle to shuffle! So when I decided to make a card game to practise using Redux for state management, this was my first choice!

Approach: I used Redux Toolkit and employed two slices, cardSlice, which tracked the position of cards, and playSlice, which tracked gameplay e.g. wins and losses.

The initial state of cardSlice was an array containing one object per card with the following keys:

To start a new game, a randomiser function shuffles this array. When each card is flipped, it reverts to its ownPos - its default position on the clock. Other conditional logic was used to keep track of which card should be clickable at any time, and a game being won or lost.

This was also my first React project using functional components and hooks, as I used class components in my previous project.

Challenges: One challenge I set myself was to adhere to the clean principles of Redux and not be tempted to pass too many cheeky props to avoid restructuring the state when new data needs arose! In the process, I came to appreciate the cleaner code and easier navigation of this project vs my pure React project with its messy props.

There were two other tricky elements: firstly defining the structure and logic which should underpin the gameplay, and secondly laying out a clock of cards in CSS such that it could be dynamically rendered, and made responsive.

I achieved this by designing a grid, positioning each card pile on the grid in a circular fashion, and then rotating them to varying degrees. I also used logic to dynamically assign class and id attributes to cards based on state, enabling dynamic rendering.

Room to improve: It would be interesting to explore drag and drop, or even to apply what I have learnt to another card game which involves more user choice - as the outcome of this game is pre-ordained!

Github Repo

Idea: to tell you a bit about me, make a fun throwback to my PC past, and practise pure CSS

Approach: "Form1" was constructed using formatted divs and a radial gradient for the dotted background. Delayed animations were used to co-ordinate the typing effect, image carousel, and the story itself.

Challenges: The animations were fiddly but do-able. The main challenge was making the site responsive whilst maintaining proportions and the formatting which underpins the animations.

Room to improve: Currently portrait mode on mobile prompts the user to rotate their device for the best view. I would refactor the page to make a portrait version. Alternatively, I'm keen to explore telling a story in different ways, for example scrollytelling.

Github Repo

Idea: my great love in life is languages (I speak 5!) and I'm a particular advocate of learning by reading. I wanted to try out an idea to enable complete beginners to start reading in French.

Approach: a Javascript array of objects [{"french": __, "english":___}] acts as the dictionary. Words or phrases in the story are designated as translatable by means of a span around them. On hover, a mouseover event looks up the contents of the relevant span in the dictionary and makes a pop-up translation visible.

Challenges: one challenge was that I didn't want to only let the user translate individual words, but wanted to offer translations and context for word pairs or phrases, where that was more helpful. I achieved this by placing a span around each translatable 'block', be that a word or a phrase, and the logic centring around the content of these spans.

Another challenge was dynamically positioning the pop-up translation so that it appeared centred above the word the user hovered on, and didn't cause an overflow in corner cases. I achieved this using various JS conditions and calculations with reference to the position of the span hovered over and injecting a style attribute to the pop-up. I also had to adapt that positioning for mobile.

Room to improve: this was a concept interface using only a small passage of text and still the makeshift dictonary ran to 87 items! The use of a span to demarcate translatable blocks within the html was also unwieldy. This was the very first project I completed and once I learn more back-end I would love to refactor it to make use of databases and a cleaner data structure.

Github Repo

Idea: I'm in a lot of online reading groups, and people love to make and share collages of books they've read - but this often involves looking up the books individually, saving the cover images, and making your own collage. For my first React app, I wanted to make the process quicker! I also wanted to incorporate my first API data.

Approach: The app uses the Google Books API to fetch book covers matching a user's search. The user can then add or remove covers from their collage, change the order, customise the look of their collage, and add captions and star ratings.

Challenges: With so many customisation options and seven components, the most challenging element was definitely state management, and controlling the passage of props such that every component had access to the data and functions it needed. Ironically, I recall wishing there was an easier, more central way to store my data... enter Redux ;)

Room to improve: the big missing feature here is the ability to download the collage (currently users have to print screen). I had CORS vs canvas issues which - after several days of hairpulling on Google - I felt couldn't be solved client-side. I'd love to come back to this project one day and put that right!

Having also since learnt Redux and learnt greater economy in React, I would also definitely implement cleaner state management and cleaner code in general (for example favouring functional components and hooks over class components and constructors) in future.

Github Repo

Idea: I used to love playing this card game as a child, but the cards would end up in order, which was a hassle to shuffle! So when I decided to make a card game to practise using Redux for state management, this was my first choice!

Approach: I used Redux Toolkit and employed two slices, cardSlice, which tracked the position of cards, and playSlice, which tracked gameplay e.g. wins and losses.

The initial state of cardSlice was an array containing one object per card with the following keys:

To start a new game, a randomiser function shuffles this array. When each card is flipped, it reverts to its ownPos - its default position on the clock. Other conditional logic was used to keep track of which card should be clickable at any time, and a game being won or lost.

This was also my first React project using functional components and hooks, as I used class components in my previous project.

Challenges: One challenge I set myself was to adhere to the clean principles of Redux and not be tempted to pass too many cheeky props to avoid restructuring the state when new data needs arose! In the process, I came to appreciate the cleaner code and easier navigation of this project vs my pure React project with its messy props.

There were two other tricky elements: firstly defining the structure and logic which should underpin the gameplay, and secondly laying out a clock of cards in CSS such that it could be dynamically rendered, and made responsive.

I achieved this by designing a grid, positioning each card pile on the grid in a circular fashion, and then rotating them to varying degrees. I also used logic to dynamically assign class and id attributes to cards based on state, enabling dynamic rendering.

Room to improve: It would be interesting to explore drag and drop, or even to apply what I have learnt to another card game which involves more user choice - as the outcome of this game is pre-ordained!