Code Monkey home page Code Monkey logo

type-curve's Introduction

Animated Art Gif Banner




alex rafter

front end, scripting, tinkering...
Hi, i'm Alex. I'm currently working as a front end web developer @MBBluesky. Currently my time is split between new site builds, bespoke projects, internal dev work, supporting junior team members, and working closely with our UX/ UI and Project Management teams.

working

By day you'll find me working with Vue.js, Vanilla JS, Node, Webpack, SASS and modern CSS. We build from custom designs created in house so you'll also find me deeply customising Bootstrap 5. Our back end is ASP.Net, so i write template logic and server-side scripts with VB.Net.

You can check out some of my recent work :

tinkering

By night i like to work on a lot of different projects. I am pretty much constantly tinkering with something.

Here are a few example side projects :

I love exploring cli tools, and scripting with Node and Bash. If you're a Front End Dev or Web Designer you might like to check out my Gist of Bash one-liners and snippets.

reaching

Feel free to get in touch with me. I'm always keen for a collab too!

Twitter Badge

type-curve's People

Contributors

alex-rafter avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar

type-curve's Issues

CSS class naming

It is quite an art to name CSS classes so that their specifity is not so broad that you end up styling elements unintentionally. I think from looking at your code you might use BEM at your shop.

I can't argue with that but it can be overkill for small projects. Also, frameworks like Angular encourage you to use lots of small CSS and HTML files, rather than one giant one, with each CSS+HTML isolated from the other. So the need for absolute unambiguity in one huge global namespace goes away.

Not only that, <p class="letterForm letterForm--phraseOne"> looks 'noisy' and, in all that text, it can be difficult to spot the important difference between phraseOne and phraseTwo.

I would recommend using simple 'inside' selectors wherever possible. So you could code this:

.grid p {
    align-items: center;
    background-color: #EEEEEE;
    display: flex;
    font-size: 1rem;
    height: 100%;
    justify-content: center;
    margin: 0;
    padding: 0;
    text-align: center;
    width: 100%;
}

.grid p .phraseOne {
    color: #999999;
}


.grid p .phraseTwo {
    color: #666666;
}

Now your HTML looks simpler:

<div class="grid">
  ...
  <p class="phraseOne">...</p>
  ...
  <p class="phraseTwo">...</p>
  ...
</div>

Arrow function inside makeInterpolator

Now you know all about arrow functions, you can replace interpFont with one.

return t => {
  ...
};

This code has the advantage that it obeys a good principle: never name anything that can safely be left anonymous. Proper naming IMO is one of the most difficult and important programming tasks, so best not to do it if you don't have to.

Strongly consider using stylint

stylint and its VSCode plugin will help keep you CSS consistent and standard, just like ESLint does for JavaScript.

All the install notes for ESLint apply to stylint.

In the interests of transparency, I should say that I have not used it myself, but I would if I were writing code now!

For loop improvements

You could write your for loop better as:

for (let i = 0; i < letterForms.length; i++) {
    letterForms[i].style.fontSize = x + "px";
}

But it is worth looking at the array functions, in particular forEach and if you feel particularly adventurous, map, reduce etc. Using them is much preferred to for loops in modern programming. Once you get the hang of the syntax of arrow functions, you can see how incredibly useful and compact they are.

letterForms.forEach(item => item.style.fontSize = x + "px");

There's one complication. querySelectorAll is 'special' in that it doesn't return an array. So in this case:

Array.from(letterForms).forEach(item => item.style.fontSize = x + "px");

The Mozilla docs are fabulous references and worth bookmarking - even casual reading! And not just for JavaScript either, as they cover all the Web technologies, HTML, CSS etc.

Optimization to consider

It can be quite expensive to traverse the DOM to make changes, especially if you are manipulating many elements. You could make a nice optimization very simply, given that all you are changing is the font size.

First, remove the font-size: 1rem; property from the letterForm class (or .grid p selector, if you follow my suggestion) and add it to the grid class. Font size is inherited by child elements from their parent.

Next, change your HTML:

<div id="theGrid" class="grid">
  ...
</div>

Now changing the font size is much simpler:

const theGrid = document.querySelector('#theGrid');

function changeFontSize() {
  ...
  theGrid.style.fontSize = `${x}px`;
}

Using an id selector is a good idea because it strengthens the important implicit dependency the code has on the HTML. Maintainers might feel free to change class names and not notice that if they do so they'll break your code. But an ID is a definite signal that some code somewhere is going to use its value.

Ordering within JavaScript file

It doesn't matter much in a small file but, as things get more complex, it gets harder and harder to organize things 'logically'. In my experience, it is best not to try.

Long ago I settled on alphabetical ordering for everything. So functions (or methods in classes) ordered alphabetically. Variables and constants the same.

// just an example; these are no longer needed 
// @see per https://github.com/Alex-Rafter/typeCurve/issues/1
const bigScreen = 1500;
const smallScreen = 320;

let bigFont, smallFont;

That's very much taste, so take that suggestion as you like!

Global code is always very important so it is critical not to bury it. So in this case, I would put the addEventListener calls either before or after your functions. Before works because JavaScript hoists function declarations to the top of the file.

Unused Global Variables.

The first 4 lines of typeCurve.js should probably be deleted
as these global variables are not used now.

//Set interpolator variables and default vaules for the big and small screen sizes
let smallScreen = 320;
let bigScreen = 1500;
let smallFont, bigFont;

Potential querySelector bug

Let's assume you adopt my optimization suggestion. But even if you don't, the same potential bug exists for the querySelectorAll call in the original code.

The problem is that by calling querySelector in open code, you don't have a lot of control over when it is executed. It could be executed, for example, before the document is fully loaded and so the selector you're looking for won't be found.

It is much safer to make the querySelector call just where you need it.

function changeFontSize() {
  ...
  const theGrid = document.querySelector('#theGrid');
  theGrid.style.fontSize = `${x}px`;
}

CSS file organization

My recommendation is also alphabetical! You have to have some organization and for anything but a trivial file it is impossible to order linearly anything that you might think of as 'logical'. Certainly, you could never depend on a maintainer to intuit what you thought of as logical and follow your original pattern. But everyone understands alphabetical order!

So first order selectors alphabetically. If the @media variants only apply to one selector, put them after that selector as you have done. But sometimes you want to affect many selectors, in which case group the @media variants at the end of the file.

Within each selector, group the CSS properties alphabetically too. That can be a pain but VSCode has a nice sort lines plugin.

makeInterpolator improvement

Don't return ft.toPrecision(3); as this unnecessarily restricts the contract of makeInterpolator and makes an unwarranted assumption about what the caller is going to do with the computed font size.

Better to just return ft;. If you really wanted to truncate to 3 decimals, you should do that where it is needed, in the string interpolation `${x.toPrecision(3)}px`.

File naming

Because in general you need to accommodate file systems that are either case-sensitive or case-insensitive, file names in a project are by convention all lowercase. CamelCase names are mapped to kebab-case. So typeCurve.js becomes type-curve.js.

BTW, only old-timey C and Ruby programmers use snake_case!

Especially when you are publishing on GitHub, you don't know if a dev who wants to use your code works on Windows, Mac or Linux.

You might extend this suggestion to include the name of the repo as well, as the repo name becomes a directory on your local file system.

Strongly consider using ESLint

ESLint and its VS Code plug-in will really help ensure a consistent style and one that conforms to standard use. I'll leave you to follow up on the details - especially how to configure ESLint - but let me know if you need help.

Here's a few things I saw in typeCurve.js that it would catch for you.

let smallScreen = 320; Use const instead of let where the variable will not change.

const letterForms = document.querySelectorAll('.letterForm'); Use either single or double quotes consistently.

if(screenOrientation === 'landscape-primary') { Mandatory space between if, for etc and (.

x+"px" Space required either side of operators.

for(i = 0; i < letterForms.length; i++){ mandatory space between ) and {.

  if (t <= smallScreen) {
      return smallFont;
  }; // no ; needed here

Using ESLint (and stylint) is going to mean you'll need to create a package.json and other config files as required, and then commit them as a part of your project. For another dev to use your code, it is standard for them to have to do this:

git clone ...
npm install

To create a package.json from scratch one good way is to run npm init. See Creating a package.json file.

ESLint has good install instructions. You'll install it as a 'dev dependency' to your project with npm install eslint --save-dev. This means that the dependency need only be present during development, not at run time.

All dependencies are kept in a node_modules directory. Be sure to create a .gitignore file and commit it ensure that node_modules and all its contents are not themselves committed. The .gitignore file will have at least this one line:

node_modules

When you later start to use Jest for testing, you'll install it in this same way and not globally as your Dad did to get started.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.