Chris Padilla/Blog


My passion project! Posts spanning music, art, software, books, and more. Equal parts journal, sketchbook, mixtape, dev diary, and commonplace book.


    Snivy & Mareep

    Charge!!!

    Pokémon — the gateway to doodling on math homework.

    ALSO!! Today marks a year of me drawing everyday! If you've ever wanted to give it a whirl, let me tell ya, a lot can happen in a year!


    Gurlitt – The Return


    Restoring 4 Hearts

    Yum!

    We haven't found the recipe for Ice Cream Cookie Sandwiches in Tears of the Kingdom yet!


    Strauss - Blue Danube Waltz

    Listen on Youtube

    🚀 🪐

    Too late for the Space Odyssey reference in the Barbie move?


    Moblin Mask

    The way it flops! 😂

    I just think this Moblin hat in Tears of the Kingdom is swell.


    New Blog Layout and Pagination

    I've updated my blog home page to show posts in full instead of just the titles. I'm doing too much art and music making to let all that fun stuff hide behind a click!

    I also found out I've posted over 200 times to this blog!! A great milestone! And a fun performance issue to navigate with pagination. :)

    Hey Diglett!

    Pagination

    In a big picture sense, you need these things:

    • Loads of data to render, like blog posts
    • A way to query it
    • A maximum number per page (the interval at which to show data)
    • A way to keep track of which page you're on.

    That translates to:

    • Content
    • API/DB Calls
    • Limit value
    • Skip value

    Calculating Skip

    Skip value is the most interesting value up there. If you have a limit of 5 posts per page, you'll know your starting place if you know what page you're on. Page 1 will shows items 0-4, so there's no skip.

    Page 2, however, starts at 5. So we can get this for each page by multiplying the page number minus 1 by 5.

    const skip = limit * (page - 1)

    From there, passing that to the DB will get you just the data you need.

    Getting Page State

    Plenty of ways to do it, though the most user friendly is likely to keep it in your query params. Your url will look something like /blog?p=2. It has the benefit of allowing users to use the back button on their browser.

    Here's how you can get that value in getServerSideProps in Next:

    export async function getServerSideProps(context) {
      const page = context.query.p || 1;
      const count = getPostsCount();
    
      const skip = (page - 1) * 5;
      const allPosts = getAllPosts(
        {
          skip,
          limit: 5,
        }
      );
    
      return {
        props: { allPosts },
      };
    }

    context is passed from next with the query params (including any that you set yourself through the [id].js naming convention.) Very handy!

    Setting Page State

    It's as simple as linking to the new url! First I'll get the current page through the client side router:

    import { useRouter } from 'next/router';
    
    export default function Blog({ allPosts, count }) {
      const router = useRouter();
      const query = router.query;
      const currentPage = parseInt(query.p) || 1;
      const lastPage = Math.ceil(count / 5);

    And then I can use it in my links below.

    <div className="pagination-controller" style={{ display: 'flex' }}>
      <div className="left" style={{ flex: '1' }}>
        {currentPage !== 1 && (
          <Link href={`${router.pathname}?p=${currentPage - 1}`}>Back</Link>
        )}
      </div>
      <div className="right" style={{ flex: '1', textAlign: 'right' }}>
        {currentPage < lastPage && (
          <Link href={`${router.pathname}?p=${currentPage + 1}`}>Next</Link>
        )}
      </div>
    </div>

    You'll have to do the math to add or reduce a page while ensuring you're not going out of bounds. Above I'm hiding the links based on the calculated lastPage.


    Neil Gaiman on Writing

    Several great nuggets of writing insight from Neil Gaiman's introduction to the 10th Anniversary Edition of American Gods.

    Storm's coming...

    Like Carl Barks, Gaiman started with a locale:

    A couple of weeks later, my editor sent me a mock-up of the book cover. It showed a road, and a lightning strike, and, at the top, it said, “American Gods.” It seemed to be the cover of the book I had planned to write.

    I found it both off-putting and exhilarating to have the cover before the book. I put it up on the wall and looked at it, intimidated, all thoughts of ever finding another title gone forever. This was the book cover. This was the book.

    Now I just had to write it.

    I think about this often, because it feels so true. Each project really does take it's own path:

    I remember when it was all done in first draft telling Gene Wolfe, who is the wisest writer I know and has written more excellent novels than any man I’ve met, that I thought I had now learned how to write a novel. Gene looked at me, and smiled kindly. “You never learn how to write a novel,” he told me. “You only learn to write the novel you’re on.”

    And then, of course, a great reminder to ship imperfection:

    I finished it, eventually, and I handed it in, taking a certain amount of comfort in the old saying that a novel can best be defined as a long piece of prose with something wrong with it, and I was fairly sure that I’d written one of those.


    Faber - 100 Degree Blues

    Listen on Youtube

    Sounds about right down here in Texas 😓


    Diglett! 🪨

    Jenn suggested I do some color studies from the master, Ken Sugimori. Here's a lil Diglett study from the original Pokémon art!

    Lil guy is just poking right out of my desk, wondering how he got here


    NVM, Next 13, and the "Latest" Package Version, OH MY!

    I received notice from Vercel, the host of this very website, that Node 14 and 16 were being deprecated. This very website was developed with a local version of Node 12! 😱

    I didn't anticipate any breaking changes with Node, I'm not using edge case functions here for this website, but I wanted to do my due diligence for Vercel.

    What started as a harmless updated nearly ended in a nightmare for me. Come along as I regale the tale of NVM, Next 13, and npm package versions!

    NVM

    Node Version Manager is exactly that — a utility for loading multiple versions of Node on your machine and switching between them. I'm already using multiple versions of Python, so I decided it was time to give NVM a whirl.

    Installation was pretty straight forward following Digital Ocean's guide.

    So the switch is made: Node 12 updated to version 18.

    NPM

    On to testing my site locally with npm run dev. Doing so alerted me to a few conflicting dependencies, which was a surprise. Seems nvm also manages npm versions as well, which is great! This new version was catching potential issues in my packages. The conflict was mainly between react testing library and react.

    Easy enough, I adjusted the version numbers and ran npm i

    Next Version 13

    Suddenly, surprise!! My starter project that this is based on left this in the package.json:

      "dependencies": {
          "next": "latest",
       },

    I've never seen that before, and with good reason. Latest will upgrade the major version when available, bringing breaking changes along with it! Suddenly, my Next <Image /> elements weren't sizing correctly, and my <Link /> tags were deprecated.

    All fine and well if this were a production site I had ample time to maintain. But, that, this is not.

    Long story short — a dive into trying to upgrade to version 13 ultimately ended with me setting my next version to "^12.0.0" for simplicity's sake.

    Deployed Build

    Surprisingly, I only ran into this issue locally. It lead me to wonder why I wasn't seeing the same errors from Next 13 on the live site.

    I thought that it might be because the Next version is set through the CLI or on Vercel, but neither are true.

    It seems that it's likely actually dependent on the node version. Here's Vercel's upgrading guide on the matter:

    The minimum Node.js version has been bumped from 12.22.0 to 14.18.0, since 12.x has reached end-of-life.

    The minimum React version has been bumped from 17.0.2 to 18.2.0.

    I'm just shy on both of those, so I imagine there were some checks that fell back to a previous version of Next in those cases.

    Moral of the story: beware of "Latest" versions in your package.json files!


    Faber - Chocolate Blues

    Listen on Youtube

    Ah yes, the ol' "Piano Playin', Chocolate Eater Blues."

    CHOCOLATE!!!!


    I Drew 250 Boxes for Drawabox. Should you?

    Yes.

    I've written about the infamous 250 box challenge over at Drawabox. I've admittedly started and forfeited the challenge a couple of times. I resisted the 50% rule at my own peril.

    And I'm here to say I'm so glad I went back in and saw it to completion.

    The challenge is outlined on their site, but for anyone unfamiliar, the gist is to draw boxes. In three point perspective. In ink. And extend your edges to their vanishing points.

    It's a bit gnarly, which is why Uncomfortable and the community around the site are very adamant about the 50% percent rule. Even if you don't learn any technique, I think the 50% rule of balancing study with play is a fantastic lesson to carry into any practice, art or otherwise.

    It's tempting to assume the reward of completing it is simply to really nail boxes. But here's what all you learn along the way:

    • Improved line quality
    • Comfort with failure
    • Intuitive perspective
    • Spacial reasoning
    • Balancing play with study
    • Persistence for a craft that's not easy to pick up

    Best yet, these all culminate in the following lessons on drawing bugs and animals. Those lessons are where things really started to click for me as far as seeing every drawing as a combination of shapes that can be manipulated in 3D space. Even if the ultimate goal is a flat, 2D image, an understanding of 3D underneath all that makes it all the easier to play with those shapes.

    I've looked at a few different avenues for getting started with drawing: Proko, Andrew Loomis, Preston Blair. I'd say, though, drawabox is where I'd recommend someone brand new start out. The material can be dense, but uncomfortable does an amazing job of starting right away with the meat of what you really need to invent with your drawings.

    At this point, I'm up to the cylinder challenge, getting ready to start lesson 6 — Drawing Everyday objects. I think most folks will get the most mileage out of completing up to about where I am, but I'm excited to see how this last leg of the course builds.


    These ROCK

    Going after sketching more from life with these big hunky rocks.

    🤘


    Migrating a React App To TypeScript

    After 10 years on the scene, TypeScript has become an essential tool in many codebases.

    The benefits are primarily static testing: Similar to C#, you'll get compile time errors regarding type-mismatches.

    Though, most folks I know that use it love it for the DX. VS Code has first class support for TypeScript, providing stellar autocomplete for all objects and classes that are typed in your codebase. Likely, you've already enjoyed the benefits of autocomplete for methods from external libraries that ship with Types.

    Migrating Create React App to TypeScript

    There was a time when getting the tooling for TypeScript up and running was a headache. Not anymore! Many modern frameworks can initialize a project with TypeScript using a simple options flag in the CLI.

    If working with Create React App, migrating is wildly easy. Simply install typescript dependencies, then restart your dev server.

    npm install --save typescript @types/node @types/react @types/react-dom @types/jest

    Opt In

    It's easy to dip your toes into TypeScript because it's an opt in system. The same TypeScript project can have as many JS files in your /src.

    So to get started, simply convert a file.js to file.tsx for react and you're off and running!

    A note here: your bundler may support JS imports without the file name, but you may need to be explicit with TypeScript imports.

    // JS File
    import EditAuthors from './components/EditAuthors';
    
    // TSX Files, will not compile without file extension
    import EditBook from './components/EditBook.tsx';
    import Books from './components/Books.tsx';
    import Book from './components/Book.tsx';

    Package Types

    Again — there was a time where not all packages shipped with Types. Long gone are those days now! When using an external library, you should be able to find info in their documentation about supported types. Here's Formik as an example.

    import { Formik, FormikErrors } from 'formik';
    import { BookSubmitObject } from '../types';
    
     <Formik
        initialValues={initialValues}
        validate={(values: BookSubmitObject) => {
          const errors: FormikErrors<BookSubmitObject> = {};
          // Validate Errors
          if (values.rating > 5 || values.rating < 1) {
            errors.rating = 'Must be within 1 and 5';
          }
          return errors;
        }}
        ...
      >

    So that's getting setup! More on how to actually write with TypeScript another time. 👋


    Picking a Locale — Overcoming the Blank Page with Carl Barks

    A fun rabbit hole I've been down is learning more about "The Good Duck Artist" Carl Barks.

    The Good Duck Artist

    Barks was a self taught cartoonist and an early legend in comics. He's known for his Donald Duck and Scrooge McDuck cartoons. Wickedly talented in every domain within comics — Story, drawing, expression, color, inking — he was also incredibly prolific, releasing comics regularly over a 25 year career.

    The Good Duck

    Interestingly enough, Barks was more widely famous in Danish culture as opposed to the US due to Donald Duck being the lead character in Denmark instead of Mickey Mouse. Hence, why one of my top searches for "Carl Barks Interviews" brought me to a Danish recording:

    Watch on YouTube

    Aside from how lighthearted Barks is about his work and characters, my favorite part of the interview comes from the question of how he came up with all of these stories:

    "I would just start thinking of what I would like to draw. Because those comic book stories required a great number of hours of drawing and if I could think of some pleasant place — a south sea island or trip into the mountains — something that would give me some good backgrounds and interesting things to draw, then I would chose that as the locale of my store. Then once I've chosen the locale... somehow the ideas for a story, something for those ducks to do, would just come about! The ideas would just pour down onto my head."

    I've heard elsewhere that Barks would use National Geographic issues as reference and inspiration for these far-flung adventures.

    From his Biography, Terry Pratchett described in his process having a horizon off in the distance. He didn't always know how he was going to hit certain story beats, but having a destination helped move the story there.

    My biggest case of "fearing the blank page" comes with writing music. Something about music being less physical makes it a bit more daunting to get started on. But stories really aren't so different. Nothing helps me kick start a song quicker than deciding on a "locale" — be it genre, a pallet of instruments, or even just a song title.

    As is my contractual obligation to say in these posts: So it is with anything creative. Starting with a title helps with writing. Starting with a subject matter helps with drawing. Starting with an app idea helps with software.

    Starting an adventure is easier once you've settled on a point of departure.