<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Art - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Art - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Tue, 19 May 2026 04:43:49 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/art/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How I Developed My First Adventure Game ]]>
                </title>
                <description>
                    <![CDATA[ It's hard to tell exactly when my journey creating Occulto, a point and click adventure game, started. But I have a significant date in mind: 3 May 2018. Here's one thing that got the ball rolling: Luigi: Hello Andrea. Sorry to bother you. I would l... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-i-developed-my-first-game/</link>
                <guid isPermaLink="false">66d46011b6b7f664236cbe00</guid>
                
                    <category>
                        <![CDATA[ Art ]]>
                    </category>
                
                    <category>
                        <![CDATA[ C ]]>
                    </category>
                
                    <category>
                        <![CDATA[ #Game Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Game Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ lessons learned ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                    <category>
                        <![CDATA[ unity ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Andrea Koutifaris ]]>
                </dc:creator>
                <pubDate>Wed, 09 Mar 2022 20:05:24 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/03/presentazione-new.min.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>It's hard to tell exactly when my journey creating Occulto, a point and click adventure game, started. But I have a significant date in mind:</p>
<p>3 May 2018.</p>
<p>Here's one thing that got the ball rolling:</p>
<blockquote>
<p>Luigi: Hello Andrea. Sorry to bother you. I would like to learn how to develop an app. Am I crazy?</p>
<p>Me (Andrea): Hmm... I don't have your number... who are you?</p>
</blockquote>
<p>Reading those two WhatsApp messages now makes me smile. But there are also two other pieces of interesting information:</p>
<p>First, that was May 2018. Now it is 2022... 3 years and some months later, we have published our very first game DEMO. So yes, it took us 3 years to release a demo.</p>
<p>But we are now producing at a steady pace, and in the first months of 2023 we will release the whole game.</p>
<p>That said, if you are planning to develop a game yourself, it won't necessarily take you 4 years…and I have some advice that hopefully will help!</p>
<p>Second, an app – everyone wants to make an app. Do we really need another app? What about a game instead? What I mean is: an adventure game is like a book, you install it, play it, enjoy and eventually uninstall it. It is not yet another app polluting your phone's memory.</p>
<p>Before I start, let me step back and explain what this article is about.</p>
<h2 id="heading-what-well-discuss-in-this-article">What We'll Discuss in This Article</h2>
<p>This article is about how I (Andrea) and Luigi developed <em>Occulto</em>, our first adventure game.</p>
<p>It will cover some technical aspects of the project, as well as how we managed creating and developing it. I'll discuss both psychological and practical parts of the journey.</p>
<p>I'll also provide a shallow comparison between using web technologies (like WebGL) for development vs Unity 2D.</p>
<p>This article consists of:</p>
<ul>
<li><p>A brief story about my passion for Adventure P&amp;C games, and how I ended up developing my own game.</p>
</li>
<li><p>A section about <em>Occulto</em>, the game I am developing</p>
</li>
<li><p>A tech section with a comparison between web technologies and Unity 2D</p>
</li>
<li><p>A section about what I learned through the process, along with some advice if you're creating your own game.</p>
</li>
</ul>
<h2 id="heading-how-i-got-into-adventure-games">How I got Into Adventure Games</h2>
<p>Many years ago, a good friend introduced me to <a target="_blank" href="https://amanita-design.net/games/machinarium.html">Machinarium</a>. Machinarium is one of the best adventure games I've ever played.</p>
<p>After I finished it, I felt the need to create my own adventure game. This feeling was not immediate, but grew stronger over time. Eventually it led me to find Luigi and be actually able to create my own indie game.</p>
<h3 id="heading-first-adventure-game-attempt">First adventure game attempt</h3>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/10/newton-scene.jpeg" alt="Image" width="600" height="400" loading="lazy"></p>
<p>In my first attempt at building a game, I contacted some friends and created a small group of people who were enthusiastic about creating an artistic P&amp;C game.</p>
<p>We managed to create a draft of the first scene (see the illustration above). The idea was to make an apple fall on Newton's head, who is resting under the tree.</p>
<p>I used the <a target="_blank" href="https://github.com/playn/playn">Playn Java framework</a> to write in Java and export to Android, iOS and web. At the time I was a Java developer. Playn is still an active project, it may be worth considering if you are looking for a Java 2D game framework.</p>
<p>This first attempt didn't last long. We had a dinner all together, and asked two friends to present us with a draft story of the game. And then I didn't get any feedback from the others and the project vanished into nothing.</p>
<h3 id="heading-second-attempt">Second attempt</h3>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/10/cover-red-moony.min.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p>In my second attempt I managed to create four scenes and some game-play among them. But the project failed because I wasn't ready to lead the project. You'll read about that soon.</p>
<p>Below you can see an image of one of the scenes of the game. It was intended to be a modern revisiting of Little Red Riding Hood were wolves were not bad :).</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/10/room.min.jpeg" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-third-and-final-adventure-game-attempt-occulto">Third and Final Adventure Game Attempt: Occulto</h2>
<p>Developing <em>Occulto</em> is my 3rd attempt at creating an adventure game – and hopefully this one is successful!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/10/village-editor.min.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Unity Editor: 1° Village</em></p>
<h3 id="heading-intro-to-the-game">Intro to the game</h3>
<p>It is a beautiful morning, and Eliot, a young mage apprentice, is going to the studio of his magister for a lesson about magical potions. Something is wrong from the first moment: why isn't the magister opening the door?</p>
<p>Inside the studio everything is a mess, and a note tells Eliot to go to the church in the village. What is going on? Where is the magister?</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/10/studio.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>2° Magister studio</em></p>
<p>Will you help Eliot in his journey to find his magister and regain possession of the powerful forbidden book titled "The never written book" that an evil figure is trying to steal?</p>
<p>The demo consists of four scenes:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/10/monastery.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>3° Monastery</em></p>
<p>and one secret passage between the monastery and the private studio of a monk.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/10/secret-passage.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>4° Secret passage</em></p>
<p>Below you can see the last scene of the demo.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/10/hunckback-studio.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>5° Monk private studio</em></p>
<h2 id="heading-tech-i-used-to-build-my-adventure-game">Tech I Used to Build My Adventure Game</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/03/unity-vs-pixijs.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>We developed <em>Occulto</em> in the beginning using <a target="_blank" href="https://pixijs.com/">Pixi.JS</a> and HTML. Then, later, I switched to Unity using the 2D features that are now included as default in the editor.</p>
<p>Since this article is quite long, I will not enter in the details of the code. But I will provide a description of the technologies we used and the process of creating the game.</p>
<p>I am planning to write a second article for the technical part.</p>
<p>We are a group of 3 people:</p>
<ul>
<li><p>Myself, Andrea, the developer and project/technical manager. I contribute to the story and game/riddle design as well. I am a software engineer.</p>
</li>
<li><p>Luigi, the wonderful artistic designer who designs and draws the scenes. He is also responsible for the game story and game-play. If you like the illustrations above, then you like Luigi's work :). He graduated in Mathematics.</p>
</li>
<li><p>Antonio is the music and sounds designer. He is a software engineer.</p>
</li>
</ul>
<p>Luigi draws the scenes using <a target="_blank" href="https://www.adobe.com/products/photoshop.html">Photoshop</a> and makes the animations using <a target="_blank" href="https://www.adobe.com/products/aftereffects.html">After Effects</a>. Then he exports everything into images (jpg and png) that I later use to assemble the scenes.</p>
<p>In addition Antonio provides me with the sounds and music for the scenes. We are using mp3 files at the moment, but we are planning to switch to <a target="_blank" href="https://www.fmod.com/">FMOD</a> in the future.</p>
<p>The game uses FHD (1920x1080) images, and runs also on low end mobile devices. If you want to run on a device with 1 GB of RAM, you need to reduce the amount of FHD images. If you load in memory more than 50/60 FHD images, the game may crash on devices with not enough memory.</p>
<p>In normal Unity memory management, the entire scene is loaded on memory, so you have to pay attention to what you add to the scene.</p>
<p>A simple and classic solution to reduce the memory imprint, is to use sprite sheets for the animations. Most of the time an animation will fit in a 2048x2048 sprite. I use <a target="_blank" href="https://www.codeandweb.com/texturepacker">Texture Packer</a> to create and import animation sprite sheets in Unity.</p>
<p>In addition I use <a target="_blank" href="https://imagemagick.org/index.php">ImageMagick</a> <a target="_blank" href="https://en.wikipedia.org/wiki/Command-line_interface">CLI</a> to trim images with an object inside. My input is a FHD transparent PNG with an object inside placed in the right position. Then I use:</p>
<pre><code class="lang-bash">magick mogrify -trim -verbose *.png &gt; trim.txt
</code></pre>
<p>to trim the image and get the precise position of the object.</p>
<p>Finally I add the trimmed image to the scene and place it using a script I made that maps the coordinates inside <em>trim.txt</em> file to the x,y values of the Unity scene.</p>
<p>By trimming and using sprite-sheets, I solved all memory problems. Also smaller images means lower time when loading a scene. In cheap mobile devices, loading a scene can require like 5 or 6 seconds (whereas in more powerful devices it takes less than a second).</p>
<p>Regarding fps and performance, Unity is good – so basically you don't have to do anything special. You just need to avoid bad design. And pay attention to <a target="_blank" href="https://en.wikipedia.org/wiki/Time_complexity">time complexity</a>. For example, avoid searching for an element on every tick of the game loop.</p>
<p>As I mentioned earlier, I am planning to write a tech article about how I developed the game using Unity 2D. If you are interested, follow me or follow us on one of our social accounts.</p>
<h3 id="heading-unity-vs-webgl">Unity vs WebGL</h3>
<p>Even if I used both technologies, I am not an expert (this is my first game). So below I will just list some of the pro and cons of both technologies.</p>
<h4 id="heading-pros-of-webgl">Pros of WebGL</h4>
<ul>
<li><p>Easy to port everywhere with <a target="_blank" href="https://capacitorjs.com/">Capacitor</a> or <a target="_blank" href="https://www.electronjs.org/">Electron</a>.</p>
</li>
<li><p>Programmers friendly: <a target="_blank" href="https://pixijs.com/">PixiJS</a> makes it very easy.</p>
</li>
<li><p>Almost the only working solution if you need a web responsive version.</p>
</li>
<li><p>Continuous integration and delivery to web is very easy, since the output is a bunch of files.</p>
</li>
<li><p>Web development is mature, and you have access to tons of libraries, utilities as well as a web packers, like <a target="_blank" href="https://webpack.js.org/">Webpack</a>.</p>
</li>
<li><p>Collaboration is very easy and mature with Git. There is something about collaboration in Unity, I didn't explore it. I don't know what happens if two people work on the same scene.</p>
</li>
</ul>
<h4 id="heading-cons-of-webgl">Cons of WebGL</h4>
<ul>
<li><p>Slightly lower performances compared to more native frameworks.</p>
</li>
<li><p>Subject to WebViews bugs (which you cannot solve).</p>
</li>
<li><p>It can be difficult for programmers who do not know web development.</p>
</li>
<li><p>WebViews doesn't seem to be ready to perfectly support WebGL. The game wasn't working well on my Neffos, and who knows on which devices it had issues. Maybe WebViews are not yet ready for gaming, but they are definitely ready for HTML and hybrids app.</p>
</li>
</ul>
<h4 id="heading-pros-of-unity">Pros of Unity</h4>
<ul>
<li><p>Graphical editor: it is easier to visualize/update the scene and fine tuning.</p>
</li>
<li><p>Easy and complete: it has almost everything you need.</p>
</li>
<li><p>Good performance: 60 fps even on low end devices at 1920 x 1080 resolution.</p>
</li>
<li><p>Cross platform, but the WebGL version does not work well on mobile phones.</p>
</li>
<li><p>A lot of indie games are made using Unity. If the Unity team introduces a bug, it will be found very soon.</p>
</li>
</ul>
<h4 id="heading-cons-of-unity">Cons of Unity</h4>
<ul>
<li><p>Graphical editor: you need a working updated Unity editor in each of the computers you are going to use. With Linux it's not that simple.</p>
</li>
<li><p><a target="_blank" href="https://store.unity.com/compare-plans">Closed licence</a> but it has a free tier if you earned up to $100K in the last 12 months.</p>
</li>
<li><p>At the moment the mobile web version is not officially supported.</p>
</li>
<li><p>Linux Unity editor is alpha (and I managed to make it work after many attempts).</p>
</li>
<li><p>Not a lot of helpful info about it: most of the posts I read to find help about a particular topic were low quality or were videos. That's far away from stack overflow quality. But the documentation is well done.</p>
</li>
</ul>
<p>Keep in mind that this section is not intended to be an exhaustive comparison between Unity 3D and WebGl frameworks. Depending on your target, one technology could be better than the other.</p>
<p>That said, even if I am a web developer, I must admit that Unity is great for developing a 2D games (and I guess 3D games too).</p>
<h2 id="heading-what-i-learned-while-building-occulto">What I learned While Building Occulto</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/03/1_zGuG4nFo8O4e0WMoNWVbMA.jpeg" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-someone-needs-to-lead-the-project">Someone needs to lead the project</h3>
<p>This is my first insight: if it is you who propose a project to others (a game, an app or whatever), they will assume you will lead the project.</p>
<p>At the time I was thinking that I was just a programmer, and didn't act like a project leader. It won't work if someone doesn't actively follow every person in the project.</p>
<h3 id="heading-have-the-right-attitude">Have the right attitude</h3>
<p>It is important to have the right attitude towards people that are participating in the project. You also need to understand if they can be productive.</p>
<p>In this context, "productive" does not have the same meaning it has at work. Productive means "actually able to produce". At work it means how much you produce and how good is your output.</p>
<p>Before I go on, let me tell you a story:</p>
<p>Before embarking on <em>Occulto</em> game development, I decided to help a guy develop the interface for his board game. I did it because I thought the game he invented was a good game that had some brilliant parts to it.</p>
<p>In this case I was the developer, and he was leading the project (being the inventor of a game, doesn't unfortunately imply that you are also good as a project leader).</p>
<p>In the beginning everything was good, and I enjoyed developing the game. In addition I was learning React, which I used as the framework to build the game app. (It is a board game, not a classic one, so React was a good choice, and also it had a lot of pages, not just the game page).</p>
<p>Then things started to become weird: he started asking for deadlines, complaining about delays on the development, and asking for features which I thought weren't really useful in the first version of the game.</p>
<p>In the end it didn't work out and I couldn't work well with him, so I blocked all communication. Remember that I worked on his game for free, and I even solved a nasty bug that caused the back end side of the game to stop working.</p>
<p>So, why this story? To tell you that making a game with a bunch of friends is a very different job than what you do at work. Some advice:</p>
<ul>
<li><p><strong>Don't push people too hard</strong>: if you are making a game for fun, it must be fun. Motivate people and help them. They are working (as you are) for free on a project they believe in.</p>
</li>
<li><p><strong>Don't act like a boss</strong>: even if you direct and follow every step of the game, people should regard you more as a project manager/team leader than a boss.</p>
</li>
</ul>
<h3 id="heading-work-in-your-spare-time">Work in your spare time</h3>
<p>Being able to be "productive" applies also to you. Are you able to work in your spare time on the game? Can you provide a steady output, without long periods of time away from the project?</p>
<p>This is the first obstacle I encountered in my previous attempts. I wasn't able to provide a constant, timely output and people thought the project was falling apart.</p>
<p>In this case, as a programmer, it is important to integrate the output of your other team members (images, animations and sounds) as soon as possible. People will be more engaged if they see their work quickly integrated in the game. Also the sooner you integrate others' work, the sooner you will find and solve problems.</p>
<h3 id="heading-remove-as-many-obstacles-as-you-can">Remove as many obstacles as you can</h3>
<p>In order to work in your spare time, you have to reduce or remove all the obstacles. These can be physical (slow computer, too small a screen, ...) or psychological. The psychological ones are the most subtle. I will try to list some of them:</p>
<p><strong>Feeling guilty for not working</strong>: this is hard, and I think is one of the main reasons for quitting. You have to enjoy working on your project. So deadlines, pushing others to produce more, threatening (like "If you don't work enough you are out") do NOT work.</p>
<p>It is better to motivate people and help them understand what's blocking them (or you) to produce some output.</p>
<p><strong>Obstacles that delays the moment you can actually work</strong>: you may think something like "I'd like to finish that thing I started, I think I can complete it in 10 minutes." Then you think: "But the PC is slow and it will take forever to start... may be tomorrow, now I'll just serf on Instagram".</p>
<p>It is important that when you think you can work a bit on the game, you can actually do it without any delay or obstacle.</p>
<p><strong>Too tired to work on the game</strong>: indeed you must not overdo it. It is important to find a balance between how much you work and how much you rest. But it is also important to avoid long periods of not working on the game.</p>
<p>I noticed that small actions can help: for example for me it is enough to start the Unity Editor to increase the chances that I'll actually work on the game.</p>
<p><strong>Share your results with the others</strong>: even though non technical people may not fully understand what you are doing (and vice-versa), it is satisfying to explain that you solved a performance problem, or that you reduced the bundle size, for example.</p>
<p>In fact, in agile methodologies, telling what you did and what your are going to do is one of the main points.</p>
<p><strong>Persist</strong>. Not everything will be easy. You will have to persist. Even though you are probably making a game because of passion, it is still requires a lot of work and sometimes you have to persevere and overcome problems/blocks. You probably do that all the time at work, you can do it also for your game.</p>
<p><strong>Not every moment is a moment of pleasure</strong>. Imagine when I discovered that the demo, almost ready to be published, wasn't working on some mobile devices and I had to rewrite everything in Unity. I really had a bad weekend.</p>
<p>But then I manage to change my attitude, start with Unity, and regain pleasure in working on the game.</p>
<p>Fortunately Luigi, my partner in the game, understood it and accepted that we needed to delay the release date of the game demo. While it took a lot of time to write the demo (2 years, if you count from the first commit), it took me 3 months to rewrite it.</p>
<h3 id="heading-focus-on-developing-the-game">Focus on developing the game</h3>
<p>It is extremely important to focus on making the game, and not the framework for the game.</p>
<p>Being a programmer you will probably want to write more code than necessary and use your preferred language. Chose a framework based on your needs (cross platform? 2D or 3D? ...) and try to develop a simple level to understand if you made the right choices.</p>
<p>When you start, you won't necessarily have a clear view of the possible frameworks/technologies available to build a game – and there are a lot. In addition you will be biased towards some languages/features.</p>
<p>About that, I can tell you 2 mistakes I made:</p>
<p>I used PixiJS and HTML technologies at first. As opposite as you may think, I was able to go at 60 fps with FHD (1920x1080) resolution even in medium performance mobile devices.</p>
<p>This is because most of the work is done by WebGL. But at a certain point the game started flickering on my old mobile phone (Neffos X1 Max) when ported to a mobile app using Capacitor (webview). But it was working well on the browser and on the other phones I had. Even on my Motorola Moto G first generation (2013 low end device).</p>
<p>I should have tested earlier on mobile (not just with the browser). Also the game wasn't smooth on the my lower end device Moto G (still it was running near 30 fps).</p>
<p>I decided that I wanted my game to run smoothly even on low end devices, so I switched to Unity 2D. Unity is used by a lot of indie game developers, and C# is quite easy. I didn't try Unreal Engine, because I am too rusty on C++. Now it runs smoothly also on my Moto G (60 FPS).</p>
<p>The second thing that was almost a mistake is that I developed a library to find the shortest path on polygon areas with polygon holes. <a target="_blank" href="https://github.com/Kouty/shortest-path-polygon-area">Here</a> you can find the JS code (I have ported it to C#, but not yet release on GitHub).</p>
<p>I took me 3 attempts to get it working properly, and a lot of time. Fortunately by the time I started developing <em>Occulto</em>, the library was ready and working. Now I can just draw the walkable area and have the main character move inside it, avoiding obstacles (polygon holes).</p>
<p>The fact is that having an algorithm to move things inside a walk-able area is not strictly necessary, and it is better to focus on actually making the game. Other P&amp;C games do not use this feature, they just move characters along predefined paths.</p>
<p>So, before you embark on something that is not strictly necessary for the game, see if you can find something already implemented or if it is really worth it.</p>
<h3 id="heading-release-a-one-scene-version-of-the-game">Release a one scene version of the game</h3>
<p>After you've chosen the right framework, take a scene, and develop the entire game which will consist on one scene plus a menu and every UI component that is cross scene. It is important to learn everything you need and to find problems as soon as possible.</p>
<p>Also, submit the game for internal testing (not public) to the stores you are going to use. Yes, do everything that's necessary from developing to publishing (privately) the game.</p>
<p>When I published the game demo on iOS, one animation wasn't working. It was working on Android, Desktop, and even on iPhone with the developer build. So yes, you need to test everything as soon as possible, even the process of publishing.</p>
<p>I made the mistake to first develop the whole demo (four scenes, plus menu and some other screens) just to find out that WebGL technology was not the right choice for my game.</p>
<h2 id="heading-final-notes">Final Notes</h2>
<p>I hope you enjoyed reading this article and found some interesting advice. Maybe I will write another article when I have published the whole game, sharing other insights.</p>
<p>If you are curious about <a target="_blank" href="https://www.sirioartgames.com/"><em>Occulto</em></a> game, follow us on:</p>
<ul>
<li><p>Twitter: <a target="_blank" href="https://twitter.com/SirioArtGames">https://twitter.com/SirioArtGames</a></p>
</li>
<li><p>Instagram: <a target="_blank" href="https://www.instagram.com/sirioartgames/">https://www.instagram.com/sirioartgames</a></p>
</li>
<li><p>Our website: <a target="_blank" href="https://www.sirioartgames.com/">https://www.sirioartgames.com</a></p>
</li>
</ul>
<p>or <a target="_blank" href="http://onelink.to/mxsak4">try the demo</a>: <a target="_blank" href="http://onelink.to/occulto">http://onelink.to/occulto</a>!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Make an NFT and Render it on the OpenSea Marketplace ]]>
                </title>
                <description>
                    <![CDATA[ By Patrick Collins In this article, I'll show you how to make an NFT without software engineering skills. Then we will learn how to make unlimited customizable NFTs with Brownie, Python, and Chainlink. And we'll see how to render and sell our creatio... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-make-an-nft-and-render-on-opensea-marketplace/</link>
                <guid isPermaLink="false">66d46089a326133d12440a45</guid>
                
                    <category>
                        <![CDATA[ Art ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Blockchain ]]>
                    </category>
                
                    <category>
                        <![CDATA[ decentralization ]]>
                    </category>
                
                    <category>
                        <![CDATA[ NFT ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Thu, 01 Apr 2021 17:05:57 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/03/Advanced-NFT-Deployment---1-.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Patrick Collins</p>
<p>In this article, I'll show you how to make an NFT without software engineering skills. Then we will learn how to make unlimited customizable NFTs with <a target="_blank" href="https://eth-brownie.readthedocs.io/en/stable/">Brownie</a>, <a target="_blank" href="https://www.python.org/">Python</a>, and <a target="_blank" href="https://docs.chain.link/docs">Chainlink</a>. And we'll see how to render and sell our creation on the <a target="_blank" href="https://opensea.io/">OpenSea</a> NFT marketplace. </p>
<p>If you're looking for a tutorial that uses Truffle, JavaScript, and fun medieval characters, check out how to <a target="_blank" href="https://blog.chain.link/build-deploy-and-sell-your-own-dynamic-nft/">Build, Deploy, and Sell your NFT here</a>. </p>
<h2 id="heading-what-is-an-nft">What is an NFT?</h2>
<p><a target="_blank" href="https://eips.ethereum.org/EIPS/eip-721">NFTs</a> (Non-Fungible Tokens) can be summed up with one word: "unique". These are smart contracts deployed on a blockchain that represent something unique. </p>
<h3 id="heading-erc20-vs-erc721">ERC20 vs ERC721</h3>
<p>NFTs are a blockchain token standard similar to the <a target="_blank" href="https://www.investopedia.com/news/what-erc20-and-what-does-it-mean-ethereum/">ERC20</a>, like AAVE, SNX, and LINK (technically a ERC677). ERC20s are "fungible" tokens, which means “replaceable” or “interchangeable.” </p>
<p>For example, your dollar bill is going to be worth $1 no matter what dollar bill you use. The serial number on the dollar bill might be different, but the bills are interchangeable and they’ll be worth $1 no matter what. </p>
<p>NFTs, on the other hand, are "non-fungible", and they follow their own token standard, the <a target="_blank" href="https://eips.ethereum.org/EIPS/eip-721">ERC721.</a> For example, the Mona Lisa is "non-fungible". Even though someone can make a copy of it, there will always only be one Mona Lisa. If the Mona Lisa was created on a blockchain, it would be an NFT. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/image-145.png" alt="Make an NFT" width="600" height="400" loading="lazy">
_Original Image from <a target="_blank" href="https://en.wikipedia.org/wiki/Mona_Lisa">Wikipedia</a>_</p>
<h2 id="heading-what-are-nfts-for">What are NFTs for?</h2>
<p>NFTs provide value to creators, artists, game designers and more by having a permanent history of deployment stored on-chain. </p>
<p>You'll always know who created the NFT, who owned the NFT, where it came from, and more, giving them a lot of value over traditional art. In traditional art, it can be tricky to understand what a "fake" is, whereas on-chain the history is easily traceable. </p>
<p>And since smart contracts and NFTs are 100% programmable, NFTs can also have added built-in royalties and any other functionality. Compensating artists has always been an issue, since often times an artist's work is spread around without any attribution. </p>
<p>More and more artists and engineers are jumping on this massive value add, because it's finally a great way for artists to be compensated for their work. And more than just that, NFTs are a fun way to show off your creativity and become a collector in a digital world. </p>
<h3 id="heading-the-value-of-nfts">The Value of NFTs</h3>
<p>NFTs have come a long way, and we keep seeing record breaking NFT sales, like "Everydays: The First 5,000 Days” selling for $69.3 million.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screen-Shot-2021-03-31-at-9.48.19-AM.png" alt="Make an NFT" width="600" height="400" loading="lazy">
<em>Image from <a target="_blank" href="https://twitter.com/ChristiesInc/status/1361670588608176128">Twitter</a></em></p>
<p>So there is a lot of value here, and it's also a fun, dynamic, and engaging way to create art in the digital world and learn about smart contract creation. So now I'll teach you everything you need to know about making NFTs.</p>
<h2 id="heading-how-to-make-an-nft">How to Make an NFT</h2>
<h3 id="heading-what-we-are-not-going-to-cover">What we are not going to cover</h3>
<p>Now, the easiest way to make an NFT is just to go to a platform like <a target="_blank" href="https://opensea.io/">Opensea</a>, <a target="_blank" href="https://rarible.com/">Rarible</a>, or <a target="_blank" href="https://mintable.app/">Mintible</a> and follow their step-by-step guide to deploying on their platform. </p>
<p>You can 100% take this route, however you could be bound to the platform, and you are shoehorned into the functionality the platform has. You can't achieve the unlimited customization, or really utilize any of the advantages NFTs have. But if you're a beginner software engineer, or not very technical, this is the route for you. </p>
<p>If you're looking to become a stronger software engineer, learn some solidity, and have the power to create something with unlimited creativity, then read on!</p>
<p>If you're new to solidity, don't worry, we will go over the basics there as well. </p>
<h2 id="heading-how-to-make-an-nft-with-unlimited-customization">How to Make an NFT with Unlimited Customization</h2>
<p>I'm going to get you jump started with this <a target="_blank" href="https://github.com/PatrickAlphaC/nft-mix">NFT Brownie Mix</a>. This is a working repo with a lot of boilerplate code. </p>
<h3 id="heading-prerequisites">Prerequisites</h3>
<p>We need a few things installed to get started:</p>
<ul>
<li><a target="_blank" href="https://www.python.org/downloads/">Python</a></li>
<li><a target="_blank" href="https://nodejs.org/en/download/">Nodejs</a> and npm</li>
<li><a target="_blank" href="https://metamask.io/">Metamask</a></li>
</ul>
<p>If you're unfamiliar with Metamask, you can <a target="_blank" href="https://docs.chain.link/docs/install-metamask">follow this tutorial</a> to get it set up. </p>
<h3 id="heading-rinkeby-testnet-eth-and-link">Rinkeby Testnet ETH and LINK</h3>
<p>We will also be working on the Rinkeby Ethereum testnet, so we will be deploying our contracts to a real blockchain, for free! </p>
<p>Testnets are great ways to test how our smart contracts behave in the real world. We need Rinkeby ETH and Rinkeby LINK, which we can get for free from the links to the latest faucets from the <a target="_blank" href="https://docs.chain.link/docs/link-token-contracts#rinkeby">Chainlink documentation</a>. </p>
<p>We will also need to add the rinkeby LINK token to our metamask, which we can do by following the <a target="_blank" href="https://docs.chain.link/docs/acquire-link">acquire LINK documentation</a>. </p>
<p>If you're still confused, <a target="_blank" href="https://www.youtube.com/watch?v=4ZgFijd02Jo">you can following along with this video</a>, just be sure to use Rinkeby instead of Ropsten. </p>
<p>When working with a smart contract platform like Ethereum, we need to pay a little bit of ETH, and when getting data from off-chain, we have to pay a little bit of LINK. This is why we need the testnet LINK and ETH.</p>
<p>Awesome, let's dive in. This is <a target="_blank" href="https://testnets.opensea.io/assets/0x8acb7ca932892eb83e4411b59309d44dddbc4cdf/0">the NFT we are going to deploy to OpenSea.</a></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screen-Shot-2021-03-31-at-10.58.35-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-quickstart">Quickstart</h3>
<pre><code class="lang-bash">git <span class="hljs-built_in">clone</span> https://github.com/PatrickAlphaC/nft-mix
<span class="hljs-built_in">cd</span> nft-mix
</code></pre>
<p>Awesome! Now we need to install the <code>ganache-cli</code> and <code>eth-brownie</code>.</p>
<pre><code>pip install eth-brownie
npm install -g ganache-cli
</code></pre><p>Now we can <a target="_blank" href="https://www.twilio.com/blog/2017/01/how-to-set-environment-variables.html">set our environment variables</a>. If you're unfamiliar with environment variables, you can just add them into your <code>.env</code> file, and then run:</p>
<p><code>source .env</code></p>
<p>A sample <code>.env</code> should be in the repo you just cloned with the environment variables commented out. Uncomment them to use them!</p>
<p>You'll need a <code>WEB3_INFURA_PROJECT_ID</code> and a <code>PRIVATE_KEY</code> . The <code>WEB3_INFURA_PROJECT_ID</code> can be found be signing up for a free <a target="_blank" href="https://infura.io/">Infura</a> account. This will give us a way to send transactions to the blockchain.</p>
<p>We will also need a private key, which you can get from your Metamask. Hit the 3 little dots, and click <code>Account Details</code> and <code>Export Private Key</code>. Please do NOT share this key with anyone if you put real money in it!</p>
<pre><code><span class="hljs-keyword">export</span> PRIVATE_KEY=YOUR_KEY_HERE
<span class="hljs-keyword">export</span> WEB3_INFURA_PROJECT_ID=YOUR_PROJECT_ID_HERE
</code></pre><p>Now we can deploy our NFT contract and create our first collectible with the following two commands. </p>
<pre><code>brownie run scripts/simple_collectible/deploy_simple.py --network rinkeby
brownie run scripts/simple_collectible/create_collectible.py --network rinkeby
</code></pre><p>The first script deploys our NFT contract to the Rinkeby blockchain, and the second one creates our first collectible. </p>
<p>You've just deployed your first smart contract!</p>
<p>It doesn't do much at all, but don't worry – I'll show you how to render it on OpenSea in the advanced part of this tutorial. But first, let's look at the ERC721 token standard. </p>
<h2 id="heading-the-erc721-token-standard">The ERC721 Token Standard</h2>
<p>Let's take a look at the contract that we just deployed, in the <code>SimpleCollectible.sol</code> file. </p>
<pre><code class="lang-javascript"><span class="hljs-comment">// SPDX-License-Identifier: MIT</span>
pragma solidity <span class="hljs-number">0.6</span><span class="hljs-number">.6</span>;

<span class="hljs-keyword">import</span> <span class="hljs-string">"@openzeppelin/contracts/token/ERC721/ERC721.sol"</span>;

contract SimpleCollectible is ERC721 {
    uint256 public tokenCounter;
    <span class="hljs-keyword">constructor</span> () public ERC721 ("Dogie", "DOG"){
        tokenCounter = <span class="hljs-number">0</span>;
    }

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createCollectible</span>(<span class="hljs-params">string memory tokenURI</span>) <span class="hljs-title">public</span> <span class="hljs-title">returns</span> (<span class="hljs-params">uint256</span>) </span>{
        uint256 newItemId = tokenCounter;
        _safeMint(msg.sender, newItemId);
        _setTokenURI(newItemId, tokenURI);
        tokenCounter = tokenCounter + <span class="hljs-number">1</span>;
        <span class="hljs-keyword">return</span> newItemId;
    }

}
</code></pre>
<p>We are using the <a target="_blank" href="https://github.com/OpenZeppelin/openzeppelin-contracts">OpenZepplin</a> package for the ERC721 token. This package that we've imported allows us to use all the functions of a typical ERC721 token. This defines all the functionality that our tokens are going to have, like <code>transfer</code> which moves tokens to new users, <code>safeMint</code> which creates new tokens, and more. </p>
<p>You can find all the functions that are given to our contract by checking out the <a target="_blank" href="https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol">OpenZepplin ERC721 token contract</a>. Our contract inherits these functions on this line: </p>
<pre><code>contract SimpleCollectible is ERC721 {
</code></pre><p>This is how solidity does inheritance. When we deploy a contract, the <code>constructor</code> is automatically called, and it takes a few parameters.</p>
<pre><code><span class="hljs-keyword">constructor</span> () public ERC721 ("Dogie", "DOG"){
        tokenCounter = <span class="hljs-number">0</span>;
    }
</code></pre><p>We also use the constructor of the <code>ERC721</code>, in our constructor, and we just have to give it a name and a symbol. In our case, it's "Dogie" and "DOG". This means that every NFT that we create will be of type Dogie/DOG. </p>
<p>This is like how every Pokemon card is still a pokemon, or every baseball player on a trading card is still a baseball player. Each baseball player is unique, but they are still all baseball players. We are just using type <code>DOG</code>. </p>
<p>We have <code>tokenCounter</code> at the top that counts how many NFTs we've created of this type. Each new token gets a <code>tokenId</code> based on the current <code>tokenCounter</code>.</p>
<p>We can actually create an NFT with the <code>createCollectible</code> function. This is what we call in our <code>create_collectible.py</code> script. </p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createCollectible</span>(<span class="hljs-params">string memory tokenURI</span>) <span class="hljs-title">public</span> <span class="hljs-title">returns</span> (<span class="hljs-params">uint256</span>) </span>{
        uint256 newItemId = tokenCounter;
        _safeMint(msg.sender, newItemId);
        _setTokenURI(newItemId, tokenURI);
        tokenCounter = tokenCounter + <span class="hljs-number">1</span>;
        <span class="hljs-keyword">return</span> newItemId;
    }
</code></pre><p>The <code>_safeMint</code> function creates the new NFT, and assigns it to whoever called <code>createdCollectible</code> , aka the <code>msg.sender</code>, with a <code>newItemId</code> derived from the <code>tokenCounter</code>. This is how we can keep track of who owns what, by checking the owner of the <code>tokenId</code>.</p>
<p>You'll notice that we also call <code>_setTokenURI</code>. Let's talk about that.</p>
<h2 id="heading-what-are-nft-metadata-and-tokenuri">What are NFT Metadata and TokenURI?</h2>
<p>When smart contracts were being created, and NFTs were being created, people quickly realized that it's <em>reaaaally</em> expensive to deploy a lot of data to the blockchain. Images as small as one KB can easily <a target="_blank" href="https://ethereum.stackexchange.com/a/896/57451">cost over $1M to store</a>. </p>
<p>This is clearly an issue for NFTs, since having creative art means you have to store this information somewhere. They also wanted a lightweight way to store attributes about an NFT – and this is where the tokenURI and metadata come into play.</p>
<h3 id="heading-tokenuri">TokenURI</h3>
<p>The <code>tokenURI</code> on an NFT is a unique identifier of what the token "looks" like. A URI could be an API call over HTTPS, an IPFS hash, or <a target="_blank" href="https://danielmiessler.com/study/difference-between-uri-url/">anything else</a> unique. </p>
<p>They follow a standard of showing metadata that looks like this:</p>
<pre><code class="lang-json">{
    <span class="hljs-attr">"name"</span>: <span class="hljs-string">"name"</span>,
    <span class="hljs-attr">"description"</span>: <span class="hljs-string">"description"</span>,
    <span class="hljs-attr">"image"</span>: <span class="hljs-string">"https://ipfs.io/ipfs/QmTgqnhFBMkfT9s8PHKcdXBn1f5bG3Q5hmBaR4U6hoTvb1?filename=Chainlink_Elf.png"</span>,
    <span class="hljs-attr">"attributes"</span>: [
        {
            <span class="hljs-attr">"trait_type"</span>: <span class="hljs-string">"trait"</span>,
            <span class="hljs-attr">"value"</span>: <span class="hljs-number">100</span>
        }
    ]
}
</code></pre>
<p>These show what an NFT looks like, and its attributes. The <code>image</code> section points to another URI of what the NFT looks like. This makes it easy for NFT platforms like Opensea, Rarible, and Mintable to render NFTs on their platforms, since they are all looking for this metadata. </p>
<h3 id="heading-off-chain-metadata-vs-on-chain-metadata">Off-Chain Metadata vs On-Chain Metadata</h3>
<p>Now you might be thinking "wait... if the metadata isn't on-chain, does that mean my NFT might go away at some point"? And you'd be correct. </p>
<p>You'd also be correct in thinking that off-chain metadata means that you can't use that metadata to have your smart contracts interact with each other. </p>
<p>This is why we want to focus on on-chain metadata, so that we can program our NFTs to interact with each other. </p>
<p>We still need the <code>image</code> part of the off-chain metadata, though, since we don't have a great way to store large images on-chain. But don't worry, we can do this for free on a decentralized network still by using <a target="_blank" href="https://ipfs.io/">IPFS</a>. </p>
<p>Here's an example imageURI from IPFS that shows the <a target="_blank" href="https://opensea.io/assets/0x8d78277bc2c63f07efc2c0c8a8512de4ad459a05/1">Chainlink Elf</a> created in the <a target="_blank" href="https://blog.chain.link/build-deploy-and-sell-your-own-dynamic-nft/">Dungeons and Dragons tutorial</a>. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screen-Shot-2021-03-31-at-12.15.22-PM.png" alt="Make an NFT" width="600" height="400" loading="lazy">
<em>The Chainlink Elf</em></p>
<p>We didn't set a tokenURI for the simple NFT because we wanted to just show a basic example. </p>
<p>Let's jump into the advanced NFT now, so we can see some of the amazing features we can do with on-chain metadata, have the NFT render on opeansea, and get our Dogie up! </p>
<p>If you want a refresher video on the section we just went over, follow along with the <a target="_blank" href="https://www.youtube.com/watch?v=ZH_7nEIJDUY">deploying a simple NFT video.</a> </p>
<h2 id="heading-dynamic-and-advanced-nfts">Dynamic and Advanced NFTs</h2>
<p><a target="_blank" href="https://blog.chain.link/build-deploy-and-sell-your-own-dynamic-nft/">Dynamic NFTs</a> are NFTs that can change over time, or have on-chain features that we can use to interact with each other. These are the NFTs that have the unlimited customization for us to make entire games, worlds, or interactive art of some-kind. Let's jump into the advanced section.</p>
<h3 id="heading-advanced-quickstart">Advanced Quickstart</h3>
<p>Make sure you have enough testnet ETH and LINK in your metamask, then run the following:</p>
<pre><code>brownie run scripts/advanced_collectible/deploy_advanced.py --network rinkeby
brownie run scripts/advanced_collectible/create_collectible.py --network rinkeby
</code></pre><p>Our collectible here is a random dog breed returned from the <a target="_blank" href="https://docs.chain.link/docs/chainlink-vrf">Chainlink VRF</a>. Chainlink VRF is a way to get provable random numbers, and therefore true scarcity in our NFTs. We then want to create its metadata.</p>
<pre><code>brownie run scripts/advanced_collectible/create_metadata.py --network rinkeby
</code></pre><p>We can then optionally upload this data to IPFS so that we can have a tokenURI. I'll show you how to do that later. For now, we are just going to use the sample tokenURI of:</p>
<pre><code>https:<span class="hljs-comment">//ipfs.io/ipfs/Qmd9MCGtdVz2miNumBHDbvj8bigSgTwnr4SbyH6DNnpWdt?filename=1-PUG.json</span>
</code></pre><p>If you download <a target="_blank" href="https://chrome.google.com/webstore/detail/ipfs-companion/nibjojkomfdiaoajekhjakgkdhaomnch?hl=en">IPFS Companion</a> into your browser you can use that URL to see what the URI returns. It'll look like this:</p>
<pre><code class="lang-json">{
    <span class="hljs-attr">"name"</span>: <span class="hljs-string">"PUG"</span>,
    <span class="hljs-attr">"description"</span>: <span class="hljs-string">"An adorable PUG pup!"</span>,
    <span class="hljs-attr">"image"</span>: <span class="hljs-string">"https://ipfs.io/ipfs/QmSsYRx3LpDAb1GZQm7zZ1AuHZjfbPkD6J7s9r41xu1mf8?filename=pug.png"</span>,
    <span class="hljs-attr">"attributes"</span>: [
        {
            <span class="hljs-attr">"trait_type"</span>: <span class="hljs-string">"cuteness"</span>,
            <span class="hljs-attr">"value"</span>: <span class="hljs-number">100</span>
        }
    ]
}
</code></pre>
<p>Then we can run our <code>set_tokenuri.py</code> script:</p>
<pre><code>brownie run scripts/advanced_collectible/set_tokenuri.py --network rinkeby
</code></pre><p>And we will get an output like this: </p>
<pre><code>Running <span class="hljs-string">'scripts/advanced_collectible/set_tokenuri.py::main'</span>...
Working on rinkeby
Transaction sent: <span class="hljs-number">0x8a83a446c306d6255952880c0ca35fa420248a84ba7484c3798d8bbad421f88e</span>
  Gas price: <span class="hljs-number">1.0</span> gwei   Gas limit: <span class="hljs-number">44601</span>   Nonce: <span class="hljs-number">354</span>
  AdvancedCollectible.setTokenURI confirmed - Block: <span class="hljs-number">8331653</span>   Gas used: <span class="hljs-number">40547</span> (<span class="hljs-number">90.91</span>%)

Awesome! You can view your NFT at https:<span class="hljs-comment">//testnets.opensea.io/assets/0x679c5f9adC630663a6e63Fa27153B215fe021b34/0</span>
Please give up to <span class="hljs-number">20</span> minutes, and hit the <span class="hljs-string">"refresh metadata"</span> button
</code></pre><p>And we can hit the link given to see what it looks like on Opensea! You may have to hit the <code>refresh metadata</code> button and wait a few minutes.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screen-Shot-2021-03-31-at-12.33.42-PM.png" alt="Make an NFT" width="600" height="400" loading="lazy">
<em>Refresh Metadata</em></p>
<h2 id="heading-the-random-breed">The Random Breed</h2>
<p>Let's talk about what we just did. Here is our <code>AdvancedCollectible.sol</code>:</p>
<pre><code>pragma solidity <span class="hljs-number">0.6</span><span class="hljs-number">.6</span>;

<span class="hljs-keyword">import</span> <span class="hljs-string">"@openzeppelin/contracts/token/ERC721/ERC721.sol"</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">"@chainlink/contracts/src/v0.6/VRFConsumerBase.sol"</span>;

contract AdvancedCollectible is ERC721, VRFConsumerBase {
    uint256 public tokenCounter;
    enum Breed{PUG, SHIBA_INU, BRENARD}
    <span class="hljs-comment">// add other things</span>
    mapping(<span class="hljs-function"><span class="hljs-params">bytes32</span> =&gt;</span> address) public requestIdToSender;
    mapping(<span class="hljs-function"><span class="hljs-params">bytes32</span> =&gt;</span> string) public requestIdToTokenURI;
    mapping(<span class="hljs-function"><span class="hljs-params">uint256</span> =&gt;</span> Breed) public tokenIdToBreed;
    mapping(<span class="hljs-function"><span class="hljs-params">bytes32</span> =&gt;</span> uint256) public requestIdToTokenId;
    event requestedCollectible(bytes32 indexed requestId); 


    bytes32 internal keyHash;
    uint256 internal fee;
    uint256 public randomResult;
    <span class="hljs-keyword">constructor</span>(address _VRFCoordinator, address _LinkToken, bytes32 _keyhash)
    public 
    VRFConsumerBase(_VRFCoordinator, _LinkToken)
    ERC721("Dogie", "DOG")
    {
        tokenCounter = <span class="hljs-number">0</span>;
        keyHash = _keyhash;
        fee = <span class="hljs-number">0.1</span> * <span class="hljs-number">10</span> ** <span class="hljs-number">18</span>;
    }

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createCollectible</span>(<span class="hljs-params">string memory tokenURI, uint256 userProvidedSeed</span>) 
        <span class="hljs-title">public</span> <span class="hljs-title">returns</span> (<span class="hljs-params">bytes32</span>)</span>{
            bytes32 requestId = requestRandomness(keyHash, fee, userProvidedSeed);
            requestIdToSender[requestId] = msg.sender;
            requestIdToTokenURI[requestId] = tokenURI;
            emit requestedCollectible(requestId);
    }

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">fulfillRandomness</span>(<span class="hljs-params">bytes32 requestId, uint256 randomNumber</span>) <span class="hljs-title">internal</span> <span class="hljs-title">override</span> </span>{
        address dogOwner = requestIdToSender[requestId];
        string memory tokenURI = requestIdToTokenURI[requestId];
        uint256 newItemId = tokenCounter;
        _safeMint(dogOwner, newItemId);
        _setTokenURI(newItemId, tokenURI);
        Breed breed = Breed(randomNumber % <span class="hljs-number">3</span>); 
        tokenIdToBreed[newItemId] = breed;
        requestIdToTokenId[requestId] = newItemId;
        tokenCounter = tokenCounter + <span class="hljs-number">1</span>;
    }

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">setTokenURI</span>(<span class="hljs-params">uint256 tokenId, string memory _tokenURI</span>) <span class="hljs-title">public</span> </span>{
        <span class="hljs-built_in">require</span>(
            _isApprovedOrOwner(_msgSender(), tokenId),
            <span class="hljs-string">"ERC721: transfer caller is not owner nor approved"</span>
        );
        _setTokenURI(tokenId, _tokenURI);
    }
}
</code></pre><p>We use the Chainlink VRF to create a random breed from a list of <code>PUG, SHIBA_INU, BRENARD</code>. When we call <code>createCollectible</code> this time, we actually kicked off a request to the Chainlink VRF node off-chain, and returned with a random number to create the NFT with one of those 3 breeds. </p>
<p>Using true randomness in your NFTs is a great way to create true scarcity, and using an Chainlink oracle random number means that your number is provably random, and can't be influenced by the miners. </p>
<p>You can learn more about <a target="_blank" href="https://docs.chain.link/docs/chainlink-vrf">Chainlink VRF in the documentation</a>. </p>
<p>The Chainlink node responds by calling the <code>fulfillRandomness</code> function, and creates the collectible based on the random number. We then still have to call <code>_setTokenURI</code> to give our NFT the appearance that it needs. </p>
<p>We didn't give our NFT attributes here, but attributes are a great way to have our NFTs battle and interact. You can see a great example of NFTs with attributes in this <a target="_blank" href="https://github.com/PatrickAlphaC/dungeons-and-dragons-nft">Dungeons and Dragons example</a>. </p>
<h3 id="heading-metadata-from-ipfs">Metadata from IPFS</h3>
<p>We are using IPFS to store two files:</p>
<ol>
<li>The image of the NFT (the pug image)</li>
<li>The tokenURI file (the JSON file which also includes the link of the image)</li>
</ol>
<p>We use IPFS because it's a free decentralized platform. We can add our tokenURIs and images to IPFS by downloading <a target="_blank" href="https://docs.ipfs.io/install/ipfs-desktop/">IPFS desktop</a>, and hitting the <code>import</code> button. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screen-Shot-2021-03-31-at-12.43.13-PM.png" alt="Make an NFT" width="600" height="400" loading="lazy">
<em>IPFS add a file</em></p>
<p>Then, we can share the URI by hitting the 3 dots next to the file we want to share, hitting <code>share link</code> and copying the link given. We can then add this link into our <code>set_tokenuri.py</code> file to change the token URI that we want to use. </p>
<h3 id="heading-persistance">Persistance</h3>
<p>However, if the tokenURI is only on our node, this means when our node is down, no one else can view it. So we want others to <code>pin</code> our NFT. We can use a pinning service like <a target="_blank" href="https://pinata.cloud/">Pinata</a> to help keep our data alive even when our IPFS node is down.</p>
<p>I imagine in the future more and more metadata will be stored on IPFS and decentralized storage platforms. Centralized servers can go down, and would mean that the art on those NFTs is lost forever. Be sure to check where the tokenURI of the NFT you use is located! </p>
<p>I also expect down the line that more people will use dStorage platforms like <a target="_blank" href="https://docs.filecoin.io/">Filecoin</a>, as using a pinning service also isn't as decentralized as it should be.</p>
<h2 id="heading-going-forward">Going forward</h2>
<p>If you'd like a video walkthrough of the advanced NFT, you can watch the <a target="_blank" href="https://www.youtube.com/watch?v=tCR7b9p9GiM">advanced NFT video</a>. </p>
<p>Now you have the skills to make beautiful fun, customizable, interactive NFTs, and have them render on a marketplace. </p>
<p>NFTs are fun, powerful ways to have artists accurately compensated for all the hard work that they do. Good luck, and remember to have fun!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Podcast: Digital artist, game developer, and entrepreneurial college student ]]>
                </title>
                <description>
                    <![CDATA[ In this week's episode, Abbey chats with artist and game developer Angela He. She's a college student at Stanford University.  Angela creates digital art and develops video games that speak to emotional issues. She has more than a dozen games in the ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/podcast-digital-artist-and-game-dev/</link>
                <guid isPermaLink="false">66b1fa5c125aeccef6f65c4c</guid>
                
                    <category>
                        <![CDATA[ Art ]]>
                    </category>
                
                    <category>
                        <![CDATA[ podcast ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Abigail Rennemeyer ]]>
                </dc:creator>
                <pubDate>Mon, 10 Jun 2019 13:51:58 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/06/Angela-podcast.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this week's episode, Abbey chats with artist and game developer Angela He. She's a college student at Stanford University. </p>
<p>Angela creates digital art and develops video games that speak to emotional issues. She has more than a dozen games in the Steam store. And she's almost completely self-taught.</p>
<p>Angela grew up in a suburb of Washington, D.C., and started studying art at the tender age of 3 (after her parents found her drawing on the walls of their home). From there, she has worked with and learned about all different kinds of art, and has taught herself much of what she knows.</p>
<p>As she grew older, she got into game development and started figuring out what sort of games - and art - her peers and the general public might like. When she came to Stanford to start university, she continued to explore new tech and expand her skills.</p>
<p>Now, Angela is launching a clothing and accessories line inspired by her art while going to school and landing internships at companies like Microsoft and Niantic (the Pokémon Go company). She loves exploring the Bay Area with her friends, enjoys shopping for house plants, and eventually wants to write an anime, among many other things.</p>
<p>This interview is a 1 hour listen in your favorite podcast player app - just search "freecodecamp" and you should find it.</p>
<p>If you have an Amazon Echo, you can just say "Alexa - play the freeCodeCamp podcast."</p>
<p>Or you can listen to it <a target="_blank" href="http://podcast.freecodecamp.org/ep-67-digital-artist-game-developer-and-entrepreneurial-college-student">right here in your browser</a>.</p>
<p>You can find <a target="_blank" href="https://twitter.com/zephybite">Angela on twitter here</a>.</p>
<p>And you can <a target="_blank" href="https://softy-shop.com/#/">check out her website here</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to save canvas animations with CCapture ]]>
                </title>
                <description>
                    <![CDATA[ By Ibby EL-Serafy You’ve been learning p5.js and you’ve created a wonderful animation and now you want to share it with the world. How do you go about that? We could use screen capture software, but this only works if the animation is running at the ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-save-canvas-animations-with-ccapture-78c70f0e86ac/</link>
                <guid isPermaLink="false">66c35442d58e4fdd567d51c5</guid>
                
                    <category>
                        <![CDATA[ Art ]]>
                    </category>
                
                    <category>
                        <![CDATA[ generative art ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 22 Mar 2019 17:09:42 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*UDBFB687oY280RLMbOwbSw.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Ibby EL-Serafy</p>
<p>You’ve been learning p5.js and you’ve created a wonderful animation and now you want to share it with the world. How do you go about that?</p>
<p>We could use screen capture software, but this only works if the animation is running at the right speed. With the above animation, I was getting less than half a frame per second. The <a target="_blank" href="https://github.com/spite/ccapture.js">ccapture.js</a> library is mentioned in the p5.js documentation and has worked well for me.</p>
<p>If you’d like to follow along with this tutorial you can fork the sandbox below, which has all the code you’ll need to start.</p>
<p>View my codesandbox <a target="_blank" href="https://codesandbox.io/s/wy11r18xz8?fontsize=14">here</a>.</p>
<p>The first thing we’ll need to do is download the <a target="_blank" href="https://github.com/spite/ccapture.js/blob/master/build/CCapture.all.min.js">minified CCapture javascript file</a>. We’ll move the file into our project folder, or upload it to our sandbox folder. Then we need to add it to our index.html file:</p>
<pre><code>&lt;script src=<span class="hljs-string">"p5.min.js"</span>&gt;&lt;<span class="hljs-regexp">/script&gt;&lt;script src="CCapture.all.min.js"&gt;&lt;/</span>script&gt;<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"sketch.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span>
</code></pre><p>In the sketch.js file, we need to initialize the capturer object. We also need to specify the framerate we’d like our animation to be. We can do this at the top of our file:</p>
<pre><code><span class="hljs-keyword">let</span> framerate = <span class="hljs-number">30</span>;<span class="hljs-keyword">var</span> capturer = <span class="hljs-keyword">new</span> CCapture( {  <span class="hljs-attr">format</span>: <span class="hljs-string">'webm'</span>,  framerate,  <span class="hljs-attr">name</span>: <span class="hljs-string">'noise_visualization'</span>,  <span class="hljs-attr">quality</span>: <span class="hljs-number">100</span>,} );
</code></pre><p>Note that we don’t need to set the framerate using the p5.js <code>frameRate()</code> function.</p>
<p>As well as <code>webm</code> you can select <code>jpeg</code> or <code>png</code> for the format, both of which generate a tar file with each frame as an image. According to the documentation, the <code>gif</code> format may not perform as well. Keep that in mind if you’re planning on using it.</p>
<p>Using the WebM format means we’ll be able to view the animation as soon as it’s ready. That seems a lot more fun than having to go through converting the images into a video first so we’ll go with that.</p>
<p>Next, we need to start the capturer, we’ll do this at the end of the setup function. You could also start it at any point in the animation, or in response to a key press or mouse click.</p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">setup</span>(<span class="hljs-params"></span>) </span>{  <span class="hljs-comment">// Setup code  // ...  capturer.start();}</span>
</code></pre><p>Now we need to capture the frames, but to do that you need to pass the <code>canvas</code> to the <code>capture</code> function first. We can make a small change to the <code>setup</code> function so we can save the canvas to a variable:</p>
<pre><code><span class="hljs-comment">// Initialise canvas outside of setup function so it can be used in the draw functionlet xseed, yseed, incrementxnoise,incrementynoise, canvas;</span>
</code></pre><pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">setup</span>(<span class="hljs-params"></span>) </span>{  <span class="hljs-keyword">let</span> p5canvas = createCanvas(<span class="hljs-number">200</span>, <span class="hljs-number">200</span>);  canvas = p5canvas.canvas;  <span class="hljs-comment">// Rest of setup code}</span>
</code></pre><p>And now at the end of the draw function, we capture the canvas.</p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">draw</span>(<span class="hljs-params"></span>) </span>{  <span class="hljs-comment">// Code for drawing the frame  capturer.capture(canvas);}</span>
</code></pre><p>Now, all we need to do is decide when to stop capturing and then save the animation. We could do this based on elapsed time, using the <code>millis()</code> function in p5.js. But it’s likely we want our animation to be a specific length, and if the frames are rendering slowly the elapsed time won’t reflect that. Instead, we can work out how many seconds have passed using the current <code>frameCount</code>:</p>
<pre><code><span class="hljs-keyword">let</span> secondsElapsed = frameCount/framerate;
</code></pre><p>Now if we want the animation to stop at, say, 5 seconds we could do it like this:</p>
<pre><code><span class="hljs-keyword">let</span> secondsElapsed = frameCount/framerate;<span class="hljs-keyword">if</span> (secondsElapsed &gt;= <span class="hljs-number">5</span>) {  capturer.stop();  capturer.save();  noLoop(); <span class="hljs-comment">// This is optional}</span>
</code></pre><p>And that’s it! Here’s what it all looks like in a sandbox:</p>
<p>View my codesandbox <a target="_blank" href="https://codesandbox.io/s/oqm8yp8ow6?codemirror=1&amp;fontsize=14&amp;module=%2Fsketch.js">here.</a></p>
<p>Note that I’ve commented out the code for downloading for the sake of embedding it on Medium.</p>
<h4 id="heading-using-ffmpeg-to-convert">Using ffmpeg to convert</h4>
<p>Now you have your animation, which is awesome, but you may need it in different formats. There are a lot of programs and online converters which you could use. I’ve been using <a target="_blank" href="https://www.ffmpeg.org/download.html">ffmpeg</a> because it’s flexible and available from the command line. In their own words:</p>
<blockquote>
<p>FFmpeg is the leading multimedia framework, able to <strong>decode</strong>, <strong>encode</strong>, <strong>transcode</strong>, <strong>mux</strong>, <strong>demux</strong>, <strong>stream</strong>, <strong>filter</strong> and <strong>play</strong> pretty much anything that humans and machines have created. It supports the most obscure ancient formats up to the cutting edge.</p>
</blockquote>
<p>To convert the animation into a gif, you can use something like this.</p>
<pre><code>ffmpeg -i noise_visualization.webm -filter_complex <span class="hljs-string">"[0:v] fps=15, split [a][b];[a] palettegen [p];[b][p] paletteuse"</span> noise_visualization.gif
</code></pre><p>GIPHY have a <a target="_blank" href="https://engineering.giphy.com/how-to-make-gifs-with-ffmpeg/">great article</a> that explains what all these options do.</p>
<p>And to convert into an mp4 for Instagram you can use something like this:</p>
<pre><code>ffmpeg -i noise_visualization.webm -c:a copy -c:v libx264 -b:v <span class="hljs-number">5</span>M -maxrate <span class="hljs-number">5</span>M noise_visualization.mp4
</code></pre><p>If you reuse the same ffmpeg options often, it may be useful to save them into an alias. You’ll have to find out the specifics of how to do it for your own terminal program. In cmder it’s under Settings&gt;Environment:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*pNBIDzV04RnAQKZRGb46lw.png" alt="Image" width="769" height="514" loading="lazy">
<em>The cmder settings window</em></p>
<p>In cmder, the alias is set with a command like this:</p>
<pre><code>alias ffinsta=ffmpeg -i $<span class="hljs-number">1</span> -c:a copy -c:v libx264 -b:v <span class="hljs-number">5</span>M -maxrate <span class="hljs-number">5</span>M $<span class="hljs-number">2</span>
</code></pre><p>Here <code>$1</code> is the first argument given to <code>ffinsta</code> and <code>$2</code> is the second argument. Once the alias is set you can use it like this:</p>
<pre><code>ffinsta noise_visualization.webm noise_visualization.mp4
</code></pre><p>Note that, in cmder, you have to restart the terminal after setting the alias. This may be the case for your terminal program too.</p>
<p>I hope you’ve found this tutorial helpful, don’t hesitate to ask if you need any help.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*UDBFB687oY280RLMbOwbSw.jpeg" alt="Image" width="800" height="800" loading="lazy">
_Photo by [Unsplash](https://unsplash.com/photos/cn0-hgcpoL8?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText" rel="noopener" target="_blank" title=""&gt;Markus Spiske on &lt;a href="https://unsplash.com/search/photos/canvas?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText" rel="noopener" target="<em>blank" title=")</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ An introduction to Generative Art: what it is, and how you make it ]]>
                </title>
                <description>
                    <![CDATA[ By Ali Spittel Generative art can be an intimidating topic — it seems like there is a lot of math involved, and art is tricky in itself! But, it doesn’t have to be difficult — you can build some really cool things without a math or art degree. This p... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/an-introduction-to-generative-art-what-it-is-and-how-you-make-it-b0b363b50a70/</link>
                <guid isPermaLink="false">66c3442a42d4db64acf4cbce</guid>
                
                    <category>
                        <![CDATA[ Art ]]>
                    </category>
                
                    <category>
                        <![CDATA[ creativity ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 03 Oct 2018 15:04:17 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/0*JPekOSiNoJpvFeDP.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Ali Spittel</p>
<p>Generative art can be an intimidating topic — it seems like there is a lot of math involved, and art is tricky in itself!</p>
<p>But, it doesn’t have to be difficult — you can build some really cool things without a math or art degree. This post will break down what generative art even is and how you can get started building your own generative art.</p>
<h3 id="heading-first-what-is-code-art">First, what is code art?</h3>
<p>Code art is any art that is built using code. There are endless examples on CodePen — for example <a target="_blank" href="https://dev.to/aspittel/learning-css-through-creating-art-54c0">CSS art</a>.</p>
<h3 id="heading-what-is-generative-art">What is generative art?</h3>
<p>Often, generative art draws inspiration from modern art, especially pop art that makes heavy use of orderly geometric patterns.</p>
<p>However, it is a very broad and rich category of art created with code with a central characteristic. Generative art incorporates a self-governed or autonomous system in some way.</p>
<p>Randomness is one type of autonomous system. By incorporating chance into a piece of code art, you get a different, completely unique piece of art each time you run your script, load your page, or respond to some user interaction.</p>
<p>There are also more orderly autonomous systems. One example is Mandelbrot’s Fractal, derived from a deceptively simple equation.</p>
<p>We can also integrate both approaches, blending order and chaos!</p>
<p>The artwork becomes a collaboration between the computer and the artist. Some aspects of the artwork are controlled by the coder, but not all of them. The artist controls both the randomness and the order in the art.</p>
<p>In a way, with an autonomous system, the artist gives up control over their art, and the computer is doing it for them. A more nuanced perspective emerges when a new creative process is considered.</p>
<p>The coder-artist engages in a feedback loop where they are constantly tweaking a system to produce more desirable and often more surprising results.</p>
<p>This process embraces experimentation and happy accidents in a way that reshapes the role of the artist. As generative artists, we use the code basics like loops, control flow and specialized functions. We then blend them with often unpredictable forces, to produce completely unique results unlike anything else that exists.</p>
<h3 id="heading-examples-of-generative-art">Examples of Generative Art</h3>
<p><a target="_blank" href="http://www.galaxykate.com/apps/Prototypes/LTrees/">Kate Compton’s Flowers</a></p>
<p><a target="_blank" href="http://math.hws.edu/eck/js/edge-of-chaos/CA.html">Cellular Automata and the Edge of Chaos</a></p>
<h4 id="heading-animated-generative-art-in-multi-colour-by-phil-nash">Animated generative art in multi-colour by Phil Nash</h4>
<h4 id="heading-impressionists-blobs-by-murasaki-uma">Impressionists Blobs by Murasaki Uma</h4>
<h4 id="heading-generated-tree-by-miriam-nadler">Generated Tree by Miriam Nadler</h4>
<h3 id="heading-what-goes-into-a-piece-of-generative-art">What goes into a piece of generative art?</h3>
<ul>
<li><strong>Randomness</strong> is crucial for creating generative art. The art should be different each time you run the generation script, so randomness is usually a large part of that.</li>
<li><strong>Algorithms</strong> — Implementing an algorithm visually can often generate awesome art, for example, the binary tree above.</li>
<li><strong>Geometry</strong> — Most generative art incorporates shapes, and the math from high school geometry class can aid in some really cool effects.</li>
</ul>
<h3 id="heading-how-can-you-approach-a-generative-art-piece">How can you approach a generative art piece?</h3>
<p>There are two main strategies for creating generative art, though most will fall between the two strategies.</p>
<p>The first is to have no results in mind and see what the computer generates as you play around.</p>
<p>The second is that you have a very finalized idea of what you want the art to look like, and the randomness only slightly changes the end result.</p>
<h3 id="heading-where-should-you-start">Where should you start?</h3>
<p>If you know JavaScript, <a target="_blank" href="https://p5js.org/">p5.js</a> is an awesome place to start. Its goal is to “make coding accessible for artists, designers, educators, and beginners.” It is a wrapper on the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API">Canvas API</a>, and it simplifies a lot of the math. It focuses on drawing, but you can also do sound, video, or webcam interaction with it if you are interested in those forms of art!</p>
<h4 id="heading-a-quick-introduction-to-p5">A Quick Introduction to P5</h4>
<p>First, load in the <a target="_blank" href="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/p5.js">p5 CDN</a>. Then, in your JavaScript file, you will add two functions that will be used in pretty much ever p5 script: <code>setup</code> and <code>draw</code>. These names are necessary for p5 to call them.</p>
<p><code>setup</code> is called when the program starts. You will probably create a canvas to draw on within it using the <code>createCanvas</code> function, and you may set some defaults there. It is only called once!</p>
<p><code>draw</code> is called after setup, and is executed constantly until you call <code>noLoop</code>, which will stop it from running again. You can control how many times <code>draw</code> runs each second with the <code>frameRate</code> function.</p>
<p>With generative art, I usually put <code>noLoop</code> in the <code>setup</code> function, which makes <code>draw</code> only run once instead of continuously.</p>
<p><a target="_blank" href="https://codepen.io/aspittel/pen/EeJJBm">Here’s a p5 starter template on CodePen</a>.</p>
<p>Since we’ve talked so much about the importance of randomness for generative art, another important function in p5 is <code>random</code>. It works similarly to JavaScript's <code>Math.random</code> but you can set a range for the numbers so that you don't have to do as much math to get the number to a useful format.</p>
<h4 id="heading-p5-lines">p5 Lines</h4>
<p>You can create a line in p5.js like this:</p>
<pre><code>line(startX, startY, endX, endY)
</code></pre><p>Then, you can randomly generate a bunch of lines and create a simple piece of generative art like this:</p>
<p>Even really simple scripts can generate cool pieces of art!</p>
<h4 id="heading-p5-shapes">p5 Shapes</h4>
<p>You can also create shapes with p5 — like circles, triangles, and squares.</p>
<p>Here’s an example of creating some shapes with p5:</p>
<pre><code><span class="hljs-comment">// circle ellipse(xCoordinate, yCoordinate, width, height)</span>
</code></pre><pre><code><span class="hljs-comment">// square rect(xCoordinate, yCoordinate, width, height)</span>
</code></pre><pre><code><span class="hljs-comment">// triangle triangle(xCoordinate1, yCoordinate1, x2, y2, x3, y3)</span>
</code></pre><p>Then, we can create some more shapes to build something more fun!</p>
<h4 id="heading-p5-movement">p5 Movement</h4>
<p>We can add movement to our drawings by removing the <code>noLoop</code> function call in the <code>setup</code> function — check this out!</p>
<h4 id="heading-color">Color</h4>
<p>You can also play with color with generative art by randomly choosing colors. You can do this mathematically through RGB values, or you can generate a color palette with your favorite color picker (we’ve been using <a target="_blank" href="https://www.colorbox.io/">this</a> one).</p>
<p>You can set the fill color with the <code>color</code> function. It takes a bunch of different formats, like named colors, RGBAs, and hex codes.</p>
<p>You can also change the color of the outline using <code>stroke</code>. You can also remove that outline using <code>noStroke</code> or make it a different width with <code>strokeWeight</code>.</p>
<h4 id="heading-putting-it-all-together">Putting it all together</h4>
<p>Once we have all of those pieces in place, we can combine the techniques to build some really cool stuff.</p>
<h3 id="heading-another-strategy-tweaking-tutorials">Another Strategy: Tweaking Tutorials</h3>
<p>You can also generate really cool generative art by taking someone else’s work and building off of it. For example, here’s the result of a tutorial by <a target="_blank" href="https://www.youtube.com/channel/UCvjgXvBlbQiydffZU7m1_aw">Dan Shiffman</a>:</p>
<p>Here are two tweaks of it to create different effects:</p>
<p><a target="_blank" href="https://codepen.io/collection/nMmoem/">Here’s</a> a Codepen Collection with even more!</p>
<p>You can follow tutorials, fork CodePens, or Glitch projects and create something new and unique. Just make sure to give the original artist some credit too.</p>
<h3 id="heading-cheatsheet">Cheatsheet</h3>
<p>Here’s a cheat sheet with all of the P5 functionality we used for this tutorial.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/0*hFfffK_1TdH8MOJf.png" alt="Image" width="800" height="838" loading="lazy"></p>
<h3 id="heading-read-more">Read More</h3>
<ul>
<li><a target="_blank" href="https://generativeartistry.com/">Generative Artistry</a></li>
<li><a target="_blank" href="https://www.youtube.com/channel/UCvjgXvBlbQiydffZU7m1_aw">Coding Train</a></li>
<li><a target="_blank" href="https://www.youtube.com/watch?v=4Se0_w0ISYk">Talk by Tim Holman</a></li>
</ul>
<h3 id="heading-keep-in-touch">Keep in Touch</h3>
<p>This post was co-written with <a target="_blank" href="https://twitter.com/1800thehive">James Reichard</a>. If you create your own art, make sure to Tweet it at us! (<a target="_blank" href="https://twitter.com/ASpittel">Ali</a> and <a target="_blank" href="https://twitter.com/1800THEHIVE">James</a>).</p>
<p><em>Originally published at <a target="_blank" href="https://dev.to/aspittel/intro-to-generative-art-2hi7">dev.to</a>.</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Creative Coding — How to create a VJ engine in JavaScript ]]>
                </title>
                <description>
                    <![CDATA[ By George Gally Learn how to dynamically inject JavaScript into webpages For years I’ve been using the browser for my performances and installations using my own simple homegrown VJ engine. And now, after you learn a few simple tricks, you can too… A... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-create-a-vj-engine-in-javascript-b63b7fb1c87b/</link>
                <guid isPermaLink="false">66c3511ad73001a6c0054beb</guid>
                
                    <category>
                        <![CDATA[ Art ]]>
                    </category>
                
                    <category>
                        <![CDATA[ creative coding ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ learning to code ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 21 May 2018 09:37:10 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*2SwNYMIzezIXuauBXdNbHg.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By George Gally</p>
<h4 id="heading-learn-how-to-dynamically-inject-javascript-into-webpages">Learn how to dynamically inject JavaScript into webpages</h4>
<p>For years I’ve been using the browser for my performances and installations using my own simple homegrown VJ engine. And now, after you learn a few simple tricks, you can too…</p>
<h3 id="heading-a-quick-intro">A quick intro</h3>
<p>Firstly, what is a VJ engine? you might ask. And maybe even: what is a VJ? Here's a <a target="_blank" href="https://en.wikipedia.org/wiki/VJing">basic definition</a> of the characteristics of VJing:</p>
<blockquote>
<p>The creation or manipulation of imagery in realtime through technological mediation and for an audience, in synchronization to music.</p>
</blockquote>
<p>And a VJ engine is simply the software used for VJing.</p>
<p>But why would I build my own when there are so many VJ engines out there?</p>
<p>I never really loved VJ software — they always felt bloated and made everyone’s stuff look kinda the same. It’s kind of like when you first got your hands on Photoshop, and just blended a bunch of stuff together, added some filters, and it was cool (because it was the 90s). But most of all, I wanted tighter and better integration between developing content and the sound input frequencies.</p>
<p>I rarely VJ these days, but it still drives most of my installations and performances — anywhere I need multiple visualisations I use <em>RBVJ</em> (the <em>RB</em> is for <em>Radarboy</em> — that’s me) as a wrapper/player.</p>
<p><em>RBVJ</em> has gone through a number of iterations over the years, as I’ve bounced from Flash, to Processing, and finally now to JavaScript, all using the same simple system.</p>
<p>I had previously open sourced it and my content (before the days of Git and not really knowing there was a thing called open-source). It won a bunch of awards, and I saw my content being used in a whole bunch of places <a target="_blank" href="https://www.youtube.com/watch?v=XOhZgAPn_CU&amp;ab_channel=CalumRodger">which was nice</a>. So I thought it was time to make it available for others again, along with a bunch of content to show how I go about creative coding.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/zXTWFCVzeLIVWd0XKR5aH03BI647fO5gKJwb" alt="Image" width="1200" height="800" loading="lazy">
_from [radarboy3000 on Instagram](https://www.instagram.com/radarboy3000/" rel="noopener" target="<em>blank" title=")</em></p>
<p>Ok, that’s a long enough introduction. Show me the money, you say!</p>
<h3 id="heading-1-structuring-the-content">1. Structuring the Content</h3>
<p>Essentially, a VJ engine is just a fancy content browser and player. So what we really need is a way to retrieve and play our content.</p>
<p>You could just dump all your content in a folder, but this system is what has worked best for me, allowing a simple structure for keyboard control:</p>
<ul>
<li><strong>Shift 0–9 to change sets</strong></li>
<li><strong>Keys 0–9 to change banks</strong></li>
<li><strong>Keys a-z to choose content</strong> within the bank.</li>
</ul>
<p>This gives you 2,700 files to work with. If you really (really!?) wanted more, you could also double that by accessing another 26 files per bank with shift A-Z).</p>
<p>Like most HTML projects, I have a simple top-level structure, and keep the VJ content in a numbered structure inside the <strong>art</strong> folder, like so:</p>
<pre><code>index.html/css/js/art &lt;- content goes here
</code></pre><p>My content folder (/art) contains 10 numbered folders, which I refer to as <strong>sets</strong>. Inside each set are another 10 numbered folders representing <strong>banks</strong>. And inside each bank are 27 individual numbered content files, like so:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/9SfMeEsL-OHXdShxWbJ3ZlihlxiYXlNw0Oqx" alt="Image" width="564" height="1008" loading="lazy">
<em>Inside /art are 10 sets of folders. Each set contains 10 banks, inside each bank are 27 javascript files. Banks and sets are accessed by the number keys and the content through keys a-z</em></p>
<h3 id="heading-2-retrieving-and-playing-the-content">2. Retrieving and Playing the Content</h3>
<p>Now we just need a way to access our files, which is done by injecting content into our index page.</p>
<p>And it’s pretty simple to do this.</p>
<p>The magic happens in a function called I’ve <strong>loadJS().</strong> It creates a script tag within the page’s head and then injects some JavaScript into it (which would be our content). We trigger this function via a keypress (but could also be a midi or OSC signal) and pass the filename of the content we want into it. Then the script is available on the page.</p>
<pre><code><span class="hljs-comment">// INJECT JS ONTO PAGE</span>
</code></pre><pre><code><span class="hljs-keyword">var</span> my_script;
</code></pre><pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">loadJS</span>(<span class="hljs-params">filename</span>) </span>{
</code></pre><pre><code> <span class="hljs-comment">// delete injected JavaScript if there’s been some loaded in before if (my_script != undefined)   document.getElementsByTagName("head")[0].removeChild(my_script);</span>
</code></pre><pre><code> <span class="hljs-comment">// create a script element my_script = document.createElement(’script’); my_script.setAttribute("type", "text/javascript");</span>
</code></pre><pre><code> <span class="hljs-comment">// Load the file in and insert it into the page’s head tag my_script.setAttribute("src", filename); document.getElementsByTagName("head")[0].appendChild(my_script);</span>
</code></pre><pre><code>}
</code></pre><p>We listen for keypresses with an event listener, which calls a function called <strong>onKeyDown()</strong><em>,</em> like so:</p>
<pre><code><span class="hljs-built_in">window</span>.addEventListener( ’keydown’, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"> event </span>) </span>{   onKeyDown( event ); });
</code></pre><p>The listener passes the event object to the function, which contains a bunch of useful stuff. Here what we’re interested in: the <strong>event.keycode</strong>. Pressing the ‘a’ key gives us a <strong>keycode</strong> of 65, and pressing us a ‘z’ gives us a <strong>keycode</strong> of 90. So we simply subtract 65 from the <strong>keycode</strong> to give us the required file number and pass this value into a <strong>changeFile()</strong> function, which I’ll show in a bit.</p>
<p>Similarly we want keys 0–9 (keycodes 48 to 57, so subtract 48 ) to change banks. We also want test to see whether the shift key has been pressed to load sets. The event object has a handy <strong>event.shiftKey</strong> variable for this, so our <strong>onKeyDown</strong> function will look like so:</p>
<pre><code><span class="hljs-comment">// KeyPress Stuff</span>
</code></pre><pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">onKeyDown</span>(<span class="hljs-params"> event </span>) </span>{
</code></pre><pre><code>    <span class="hljs-keyword">var</span> keyCode = event.keyCode;
</code></pre><pre><code>   <span class="hljs-comment">// CHANGE FILE // keys a-z   if ( keyCode &gt;= 65 &amp;&amp; keyCode &lt;= 90 ) {      changeFile(keyCode - 65);</span>
</code></pre><pre><code>   <span class="hljs-comment">// CHANGE SET AND BANK // keys 0-9   } else if ( keyCode &gt;= 48 &amp;&amp; keyCode &lt;= 57 ) {</span>
</code></pre><pre><code>      <span class="hljs-comment">// Test whether the shift key is also being pressed      if( event.shiftKey ) {       changeBank( keyCode-48 );      } else {       changeSet( keyCode-48 );      }</span>
</code></pre><pre><code>   }
</code></pre><pre><code>}
</code></pre><p>The <strong>changeFile()</strong> function basically just takes the keypress and converts it into a URL. It calls our <strong>loadJS()</strong> function to inject the content into the page, and boom we’re away...</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/IzvgpLah3pAqNZ0KLPWx0rHgsqBWGLf916TP" alt="Image" width="800" height="496" loading="lazy">
_from [radarboy3000 on Instagram](https://www.instagram.com/radarboy3000/" rel="noopener" target="<em>blank" title=")</em></p>
<p>So our <strong>changeFile()</strong> function would look like this:</p>
<pre><code><span class="hljs-keyword">var</span> current_file = <span class="hljs-number">0</span>;<span class="hljs-keyword">var</span> current_set = <span class="hljs-number">0</span>;<span class="hljs-keyword">var</span> current_bank = <span class="hljs-number">0</span>;
</code></pre><pre><code><span class="hljs-keyword">var</span> art_location = <span class="hljs-string">"art/"</span>;
</code></pre><pre><code><span class="hljs-comment">// FILE LOADER FUNCTIONS</span>
</code></pre><pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">changeFile</span>(<span class="hljs-params">file</span>) </span>{
</code></pre><pre><code>  current_file = file;  <span class="hljs-keyword">var</span> loc = current_set + <span class="hljs-string">'/'</span> + current_bank + <span class="hljs-string">'/'</span> + current_file;  <span class="hljs-keyword">var</span> filename = contentLocation + loc + <span class="hljs-string">'.js'</span>;  loadJS(filename);  <span class="hljs-built_in">document</span>.location.hash = loc; <span class="hljs-comment">//console.log("File: " + loc);</span>
</code></pre><pre><code>}
</code></pre><p>I also have an <strong>art_location</strong> variable in case I want to have different collections of visuals (so I can have different folders for different shows and installations). I also add the filename as a hash (https://127.0.0.1/#set/bank/file) to the browser’s URL to make it easy to see where I am.</p>
<p>Our <strong>changeBank()</strong> and <strong>changeSet()</strong> functions set the <strong>current_bank</strong> and <strong>current_set</strong> variables. Then they just call the <strong>changeFile()</strong> function to pull up the correct file.</p>
<p>For housekeeping, I also reset all the counters — setting <strong>current_file</strong> back to 0 when I change banks, and the <strong>current_bank</strong> back to 0 when I change sets. This is so I know that when I change <strong>banks</strong>, the file playing will be the first file in the bank. Similarly, when I change <strong>sets,</strong> the file playing will reset to be be the first file from the first bank of the current set (<strong>current_set/0/0.js</strong>).</p>
<p>A bit of a mouthful, but the functions are actually super simple:</p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">changeSet</span>(<span class="hljs-params">set</span>) </span>{
</code></pre><pre><code>  current_set = set;  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"changeSet: "</span> + current_set);
</code></pre><pre><code>  <span class="hljs-comment">// reset bank number  changeBank(0);</span>
</code></pre><pre><code>}
</code></pre><pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">changeBank</span>(<span class="hljs-params">bank</span>) </span>{
</code></pre><pre><code>current_bank = bank;  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"changeBank: "</span> + current_bank);
</code></pre><pre><code>  <span class="hljs-comment">// reset file number and load new file  changeFile(0);</span>
</code></pre><pre><code>}
</code></pre><p>And so the complete code for your basic VJ engine looks like this:</p>
<pre><code><span class="hljs-comment">// FILE LOADER FUNCTIONS</span>
</code></pre><pre><code><span class="hljs-keyword">var</span> art_location = <span class="hljs-string">"/art"</span>;
</code></pre><pre><code><span class="hljs-keyword">var</span> fileref;<span class="hljs-keyword">var</span> current_file = <span class="hljs-number">0</span>;<span class="hljs-keyword">var</span> current_set = <span class="hljs-number">0</span>;<span class="hljs-keyword">var</span> current_bank = <span class="hljs-number">0</span>;
</code></pre><pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">changeFile</span>(<span class="hljs-params"> file </span>) </span>{  reset()  current_file = file;  <span class="hljs-keyword">var</span> loc = current_set + <span class="hljs-string">'/'</span> + current_bank + <span class="hljs-string">'/'</span> + current_file;  <span class="hljs-keyword">var</span> filename = <span class="hljs-string">'art/'</span> + loc + <span class="hljs-string">'.js'</span>;  loadJS( filename );  <span class="hljs-built_in">document</span>.location.hash = loc;  <span class="hljs-comment">//console.log("File: " + loc);}</span>
</code></pre><pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">changeSet</span>(<span class="hljs-params"> set </span>) </span>{  current_set = set;  current_bank = <span class="hljs-number">0</span>;  <span class="hljs-built_in">console</span>.log( <span class="hljs-string">"changeSet: "</span> + current_bank );  <span class="hljs-comment">// reset  changeFile( 0 );}</span>
</code></pre><pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">changeBank</span>(<span class="hljs-params"> bank </span>) </span>{  current_bank = bank;  <span class="hljs-built_in">console</span>.log( <span class="hljs-string">"changeBank: "</span> + current_bank );  changeFile( <span class="hljs-number">0</span> );}
</code></pre><pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">reset</span>(<span class="hljs-params"></span>)</span>{  ctx.clearRect( <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, w, h );  ctx2.clearRect( <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, w, h );  ctx3.clearRect( <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, w, h );  ctx.lineCap = <span class="hljs-string">"butt"</span>;}
</code></pre><pre><code><span class="hljs-comment">// INJECT JS ONTO PAGE</span>
</code></pre><pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">loadJS</span>(<span class="hljs-params"> filename </span>) </span>{
</code></pre><pre><code><span class="hljs-keyword">if</span> ( fileref != <span class="hljs-literal">undefined</span> ) <span class="hljs-built_in">document</span>.getElementsByTagName( <span class="hljs-string">"head"</span> )[ <span class="hljs-number">0</span> ].removeChild( fileref );  fileref = <span class="hljs-built_in">document</span>.createElement( <span class="hljs-string">'script'</span> );  fileref.setAttribute( <span class="hljs-string">"type"</span>, <span class="hljs-string">"text/javascript"</span> );  fileref.setAttribute( <span class="hljs-string">"src"</span>, filename );  <span class="hljs-built_in">document</span>.getElementsByTagName( <span class="hljs-string">"head"</span> )[ <span class="hljs-number">0</span> ].appendChild( fileref );
</code></pre><pre><code>}
</code></pre><p><img src="https://cdn-media-1.freecodecamp.org/images/XnCcboR0KFixjweg9JBvoGifwsfXUZqyMcyT" alt="Image" width="1200" height="800" loading="lazy">
_from [radarboy3000 on Instagram](https://www.instagram.com/radarboy3000/" rel="noopener" target="<em>blank" title=")</em></p>
<p>All that’s left to show you is how I structure the actual content files, which use an encapsulated function like so:</p>
<pre><code><span class="hljs-comment">// RBVJ art</span>
</code></pre><pre><code>rbvj = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
</code></pre><pre><code>  draw = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{     <span class="hljs-comment">// do some creative coding here  }</span>
</code></pre><pre><code>}();
</code></pre><p>The function <strong>rbvj()</strong> is what gets injected into the page. It’s reused, so that every time a new file is inserted into my page, the memory gets flushed from all previous content.</p>
<p>By encapsulating the code (see the ‘()’ after the function), any code inside the <strong>rbvj()</strong> function will run automatically when the file is injected into the page.</p>
<p>You’ll notice that inside the content, I have a <strong>draw()</strong> function (this one from my own <strong>creative_coding.js</strong> utility script). It’s just a simple loop that uses JavaScript’s <strong>requestAnimationFrame()</strong> and is able to vary the frame rate.</p>
<pre><code><span class="hljs-keyword">var</span> frame_number = <span class="hljs-number">0</span>;<span class="hljs-keyword">var</span> frame_rate = <span class="hljs-number">60</span>;<span class="hljs-keyword">var</span> last_update = <span class="hljs-built_in">Date</span>.now();
</code></pre><pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">loop</span>(<span class="hljs-params"></span>) </span>{
</code></pre><pre><code><span class="hljs-keyword">var</span> now = <span class="hljs-built_in">Date</span>.now();  <span class="hljs-keyword">var</span> elapsed_mils = now - last_update;
</code></pre><pre><code><span class="hljs-keyword">if</span> ((<span class="hljs-keyword">typeof</span> <span class="hljs-built_in">window</span>.draw == <span class="hljs-string">'function'</span>) &amp;&amp; (elapsed_mils &gt;= (<span class="hljs-number">1000</span> / <span class="hljs-built_in">window</span>.frame_rate))) {    <span class="hljs-built_in">window</span>.draw();    frame_number++;    last_update = now - elapsed_mils % (<span class="hljs-number">1000</span> / <span class="hljs-built_in">window</span>.frame_rate);  }  requestAnimationFrame(loop);
</code></pre><pre><code>};
</code></pre><p>And that’s pretty much it. You now have a working VJ engine in the bowser.</p>
<h3 id="heading-3-some-other-things-to-know-that-may-be-helpful">3. Some other things to know that may be helpful</h3>
<p>I normally just plug my computer’s sound input straight into an input from the venue’s mixer or amp (I use a version of my standard microphone input <strong>mic.js</strong> file, which you can read more about <a target="_blank" href="https://hackernoon.com/creative-coding-using-the-microphone-to-make-sound-reactive-art-part1-164fd3d972f3">here</a>). And I have keys setup (in my case, the <strong>plus</strong> and <strong>minus</strong> keys) to adjust the input levels up or down, so I don’t have to keep accessing the mixer.</p>
<p>Also note that for sound input, you’ll need a secure HTTPS connection — or if you use something like Atom’s Live Server, then that’s built in.</p>
<p>I also have a bunch of other keys set up for simple audio and visual filters (see how to make a pixelation filter <a target="_blank" href="https://hackernoon.com/creating-a-pixelation-filter-for-creative-coding-fc6dc1d728b2">here</a>).</p>
<p>I mostly don’t use a preview screen/interface, but it’s easy enough to build one. Just create a new HTML page and let the pages talk to each other through a socket.</p>
<p>And finally, one last tip: when developing content, simply make a function to read in the current hash value of the browser, and call the <strong>loadFile()</strong> function on page load. That way, when you’re working on a file and you reload the page, that file is automatically displayed.</p>
<p>And that’s pretty much it. Hope this helps you get out there and show more of your content. As I mentioned previously, I’ve included a whole bunch of content for you to play around with and test so you can get a feel of how I create my stuff. If you use or alter any of it, I’d love to see how, where, and what you did with it. So please drop me a line.</p>
<p><strong><em>Happy coding. And thanks for reading!</em></strong></p>
<p>As usual the full code is available <a target="_blank" href="https://github.com/GeorgeGally/rbvj">on Github</a>.</p>
<p><em>This article is part of an ongoing series of tutorials on learning creative coding in pure JavaScript. As yes, I should be doing this in ES6, but wanted to keep this as simple as possible to understand.</em></p>
<p>You can see previous all my previous creative coding tutorials <a target="_blank" href="https://medium.com/@radarboy3000">here</a>.</p>
<p><strong>And follow me here for updates, techniques and eye candy:</strong></p>
<p><a target="_blank" href="https://www.instagram.com/radarboy3000/"><strong>@radarboy3000 * Instagram photos and videos</strong></a><br><a target="_blank" href="https://www.instagram.com/radarboy3000/">_3,960 Followers, 843 Following, 1,082 Posts - See Instagram photos and videos from @radarboy3000_www.instagram.com</a><a target="_blank" href="https://twitter.com/radarboy_japan"><strong>George Gally (@radarboy_japan) | Twitter</strong></a><br><a target="_blank" href="https://twitter.com/radarboy_japan">_The latest Tweets from George Gally (@radarboy_japan). Media artist, technologist, tinkerer, dreamer. Motion reaction…_twitter.com</a><a target="_blank" href="https://www.facebook.com/radarboy3000"><strong>Radarboy</strong></a><br><a target="_blank" href="https://www.facebook.com/radarboy3000">_Radarboy. 130 likes · 7 talking about this. Art, design visualisation, hacks_www.facebook.com</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ The CSS genius of Bali Balo ]]>
                </title>
                <description>
                    <![CDATA[ Today Bali Balo, a French designer and developer, published a new piece: a cube suspended in darkness that rotates on its own. As it does, it reveals different sides, each offering a glimpse into a different world: a game of 3D pong nested 3D shapes... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/the-css-genius-of-bali-balo-30abd36a3d22/</link>
                <guid isPermaLink="false">66b8d5c6f583f6362a68ce2b</guid>
                
                    <category>
                        <![CDATA[ Art ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ startup ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Quincy Larson ]]>
                </dc:creator>
                <pubDate>Wed, 14 Jun 2017 20:06:03 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*PmWESRqydBdDQ-nipRRW0g.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Today Bali Balo, a French designer and developer, <a target="_blank" href="https://fcc.im/2t3kQ5x">published a new piece</a>: a cube suspended in darkness that rotates on its own. As it does, it reveals different sides, each offering a glimpse into a different world:</p>
<ul>
<li>a game of 3D pong</li>
<li>nested 3D shapes that slide around as the cube tilts</li>
<li>a field of stars whizzing past as if traveling at near light speed</li>
<li>a surreal humanoid figure that seems to tumble forever through space</li>
</ul>
<p><a target="_blank" href="https://fcc.im/2t2CGoV">Bali Balo is famous on CodePen</a> not only for these explorations of geometry, but also for building a pure-CSS Minesweeper game.</p>
<p>That’s right — a fully functioning Minesweeper game — just like the one that has come pre-installed on Windows for decades.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/Vt0XR72kI96EHgmgYrjKPaxIsx9rI8PJcYsr" alt="Image" width="531" height="453" loading="lazy"></p>
<p>You can <a target="_blank" href="https://fcc.im/2rik9DY">play it here</a> and see that it is indeed running without the use of JavaScript.</p>
<p>And if you have time, I encourage you to read <a target="_blank" href="https://www.freecodecamp.org/news/the-css-genius-of-bali-balo-30abd36a3d22/undefined">Preethi Kasireddy</a>’s excellent interview with Chris Coyier, who helped create the CodePen platform itself: (<a target="_blank" href="https://fcc.im/2s1LY6o">17 minute read</a>)</p>
<h3 id="heading-here-are-three-other-links-worth-your-time">Here are three other links worth your time:</h3>
<ol>
<li>A guide that the 500+ engineers at Asian ride-sharing startup Grab use to keep up with changes in front end development (<a target="_blank" href="https://fcc.im/2spxFsP">22 minute read</a>)</li>
<li>Token Network Effects: a new business model for a decentralized web (<a target="_blank" href="https://fcc.im/2sbfXHy">6 minute read</a>)</li>
<li>Yes — some Coursera courses are still free. You just need to know how to access them. Here’s how. (<a target="_blank" href="https://fcc.im/2rwQ4zI">6 minute read</a>)</li>
</ol>
<h3 id="heading-thought-of-the-day">Thought of the day:</h3>
<blockquote>
<p>“I’ve been fairly successful at what I call ‘Tom Sawyering’; it’s the idea that if you want to get your fence painted, you trade something of value with the people with whom you work. You have to be committed to their success as well as your own.” — Chuck Thacker</p>
</blockquote>
<p>Chuck Thacker — who helped create technologies like the mouse, laser printer, and ethernet — died this week. The ACM published this obituary for him: (<a target="_blank" href="https://fcc.im/2tnt5bY">6 minute read</a>)</p>
<h3 id="heading-image-of-the-day">Image of the day:</h3>
<p><img src="https://cdn-media-1.freecodecamp.org/images/5PciiVkBWDqeNdAta3elDBbtvfU2th8G-PnW" alt="Image" width="354" height="281" loading="lazy"></p>
<p><a target="_blank" href="https://fcc.im/2s1JiFK">“The Horrible CERN Girls”</a> was the first image ever published on the World Wide Web. The photo shows a pop quartet comprised entirely of CERN employees.</p>
<p>You can read about the history of images on the web, and how they were originally proposed, here: (<a target="_blank" href="https://fcc.im/2spyZfo">4 minute read</a>)</p>
<h3 id="heading-study-group-of-the-day">Study group of the day:</h3>
<p><a target="_blank" href="https://fcc.im/2stFJcX">freeCodeCamp Bridgend, UK</a></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/dEMvm6i0CH636lh-j2V6RoM5EVuBDTzqZyse" alt="Image" width="800" height="450" loading="lazy"></p>
<p>Happy coding!</p>
<p>– Quincy Larson, teacher at <a target="_blank" href="http://bit.ly/2j7Q1dN">freeCodeCamp</a></p>
<p>If you get value out of these emails, please consider <a target="_blank" href="http://bit.ly/donate-to-fcc">supporting our nonprofit</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ The Principles of UX Choreography ]]>
                </title>
                <description>
                    <![CDATA[ By Rebecca Ussai Henderson The intersection of Disney and UX and why learning how to draw Mickey Mouse will change how you approach design Recently I collaborated together with Glen Keane, Disney animator and legend, on a talk at SXSW. This article i... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/the-principles-of-ux-choreography-69c91c2cbc2a/</link>
                <guid isPermaLink="false">66c3621b5731bdf41f8c643c</guid>
                
                    <category>
                        <![CDATA[ animation ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Art ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ user experience ]]>
                    </category>
                
                    <category>
                        <![CDATA[ UX ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 08 Apr 2015 00:35:17 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*bVba7oDXC6JeLyeUbwvCZw.gif" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Rebecca Ussai Henderson</p>
<h4 id="heading-the-intersection-of-disney-and-ux-and-why-learning-how-to-draw-mickey-mouse-will-change-how-you-approach-design">The intersection of Disney and UX and why learning how to draw Mickey Mouse will change how you approach design</h4>
<p><em>Recently I collaborated together with Glen Keane, Disney animator and legend, on a talk at SXSW. This article is a summary of what we shared during the panel.</em></p>
<p>Before I became a UX designer, I thought I wanted to be a title sequence designer. I took a course at Carnegie Mellon taught by Dan Boyarski called Time, Motion, and Communication. It was all about kinetic typography, rhythm, color, and movement. Dan used to describe every element on screen as if it were an actor on a stage — a character that we were directing, giving it behavior and personality.</p>
<blockquote>
<p>“You are responsible for directing each element’s entrance, performance, and exit.”</p>
</blockquote>
<p>We would constantly revisit this sequence, giving reason to why a character was there and what its role was. Introducing time and motion changed everything for me, because what I realized was that it gave you <em>precise control</em> over the emotion you are trying to convey and how an audience will interpret your message. I’d often look to title sequences for inspiration because I was fascinated with how a 30 second or 3 minute sequence had the ability to set the tone for an entire film and foreshadow what was going to happen. When the job hunt began, it was a happy accident how I ended up as a UX designer at R/GA. I knew R/GA had a history in <a target="_blank" href="http://rga.com/about/featured/our-history/">title sequence design</a> — had no idea if they still did that now — but knew it was a place I wanted to work. I intended to apply for a visual design position but was nudged into UX, so started day one thinking, “what are wireframes?!”</p>
<p>Fast forward to a few years later: I’ve created hundreds of wireframes and thousands of annotations that describe how things work and fit together. Things like: <em>When the user taps on the menu icon, the panel will slide down from the top of the page. When the user clicks the thumbnail, the video will enlarge full screen.</em> And then it hit me. We were stuck designing in these <strong>extreme states</strong> and a huge piece was missing in our work. When our deliverables consist of designing for these static comps like a home page or product page or article page and we only annotate how things flow together, we were completely failing to show what happens in between. Annotating doesn’t provide enough context: we had to start <em>showing it</em>.</p>
<p>The more wireframes I made, the more I started to realize that everything I had once learned about motion design was completely relevant to our roles as UX and visual designers. As I started to pay more attention to everything I engaged with day to day, I realized that the most <em>fluid, delightful, and intuitive</em> experiences were always the ones that put detail into motion design.</p>
<h4 id="heading-disney-amp-ux">Disney &amp; UX</h4>
<p>If we’re going to talk about motion and start somewhere, it’s with Disney. Disney developed <a target="_blank" href="http://en.wikipedia.org/wiki/12_basic_principles_of_animation">12 Principles of Animation</a> which I find to be so important because of the way they depict realistic movement and emotional engagement. Disney had a deep understanding of how things move and behave in real life. They knew that when an audience would watch something on screen, they expected things to move in a way that felt natural. Disney also knew that if they wanted to captivate their audience they needed a layer of emotional engagement. It’s how they became some of the first animators to create full-length feature films that captured an audience’s heart and made characters feel believable and relatable. Realistic movement, emotional engagement, solving extreme states… that’s how this all starts to come together.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*iVWINSa_xrQ13oLckXOCyQ.png" alt="Image" width="800" height="449" loading="lazy"></p>
<blockquote>
<p>UX Choreography is a combination of the <em>how</em> with the <em>when and why</em> — the proper techniques of applying motion and captivating an audience combined with the most integral moments in user experience where you can start engaging your user in a two-way dialogue.</p>
</blockquote>
<h4 id="heading-the-5-principles-of-ux-choreography">The 5 Principles of UX Choreography</h4>
<p>The biggest thing to take away here is that our job as UX and visual designers is not just to make things functional and follow best practices. We’re also trying to make these experiences enjoyable and, most of all, tell a story through experience sequences. The more I paid attention to how motion was applied in digital and the techniques that were being used, the more I started to see a pattern. I arrived at these 5 principles, which I feel address the most important communication points in UX, solve the gaps between extreme states, and overall create a more polished experience. Getting these details right is important because it influences people’s perception and trust in your product, which overall creates a more positive experience and enjoyable experience.</p>
<h3 id="heading-feedback">Feedback</h3>
<p>Feedback helps demonstrate the result of a user’s interaction, whether or not it was successful, and why. It’s often used to show if something is correct or incorrect, if something is loading, if you’re making progress, or simply when you are making selections. Feedback is important because it builds trust with your users and it’s really satisfying and delightful for users to see! It helps add a tactile element to interactions because it makes you forget you may just be tapping a piece of glass and instead makes you feel like you’re interacting with real elements on the screen. It’s nice to feel like things are reacting to what you’re doing. When you think of designing for Feedback, it’s important to work on making it <em>obvious</em> to users. Feedback is more effective when multiple layers of elements are working together to react to what users do.</p>
<p>So, what can Disney teach us here? <strong>Exaggeration</strong>. Glen describes exaggeration as something that is <em>felt</em>, not just seen. Often you’ll see characters react a big, unmistakeable way.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*YctY2u6kWGtQmiNl8gfl5g.jpeg" alt="Image" width="800" height="146" loading="lazy">
<em>Beast getting frustrated and surprised</em></p>
<p>He illustrated an example of Beast getting frustrated with Belle when she said she wasn’t going to dinner. Beast’s face stretched up and his eyes widened, making him look surprised. Then his face squashed down and his brows looked angry. An audience doesn’t even notice the subtleties of what’s happening because it happens so fast, but it makes the end result feel like a jolt and completely obvious.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*_lflrcbyVdMzQURlNcD0DQ.gif" alt="Image" width="498" height="432" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*YB7PwA_y3E2VJCTF8T3v-g.gif" alt="Image" width="498" height="432" loading="lazy">
<em>Examples of Feedback. iOS password shake: simple head shake, directly relates to how we give feedback to each other. Dots: simple and delightful, many different layers working together. Yahoo News: each circle fills one by one, the counter updates, your progress is complete and you are rewarded with a full screen fact. Beats: genres react when you tap, progress building is a queue to the user. (PS — check out capptivate.co for great examples).</em></p>
<h3 id="heading-feedforward">Feedforward</h3>
<p>Feedforward: it’s a form of hinting. It’s visual affordance. It helps convey to users what possible interactions are and what to expect so that they better understand how things work and fit together. Feedforward nudges users through the correct sequence of actions so that they can avoid confusion and better accomplish your goals. It really helps prepare people for what’s about to happen and what to do, hinting at things like, <em>“pay attention, look here!”</em> or <em>“you can drop that here”</em> or <em>“pull this a little further.”</em> Often these are really subtle details… people may not even notice they are happening and recall what little cues helped them. Subtle, but powerful! The payoff can be huge when Feedforward is executed effectively.</p>
<p>Disney’s principle of <strong>Anticipation</strong> has a very similar goal: preparing an audience for what’s about to happen.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*bwwKkgU_aT83UJvFJEpOOw.jpeg" alt="Image" width="400" height="300" loading="lazy">
<em>Mickey’s open hand becomes a symbol for the action of reaching across and grabbing a ball</em></p>
<p>In order to convey this principle, Glen first illustrated a very simple sequence of Mickey reaching across a table to pick up a ball. In the first drawing, his hand was close to him and Mickey was eyeing the ball across the table. In the next drawing, Mickey’s hand was already on the ball. It’s such a simple gesture, that’s all you think you’d need to illustrate, right? The downfall here is that there is no enjoyment for the audience; before they know it, an action is completed. They may not have been ready for what you were about to do, even if it seemed so obvious when you were illustrating it. Taking the time to build anticipation by adding in an extra frame with Mickey’s hand wide open, stretching across table becomes a <em>symbol</em> to the audience where they realize that something is about to happen.</p>
<blockquote>
<p>“You can’t get impatient with the audience, they are just responding.”</p>
</blockquote>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*GOQj0cN_IacXFrJqDNW_Zw.png" alt="Image" width="800" height="448" loading="lazy"></p>
<p>Another example of Anticipation that Glen shared was a scene in Duet where Tosh was climbing down the tree. Initially, Glen just had Tosh hop off. He soon realized, however, that everyone had missed it because it happened too quickly. “You never want your audience behind you,” Glen described. He redrew this scene and had Tosh first look back at Mia, then turn his torso back forward to go down the tree. That subtle cue made all the difference in the world and helped the audience naturally follow where Tosh was going to go next.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*oCXsKtvvbl71b3KniroLNg.gif" alt="Image" width="498" height="432" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*IuE9-JIrOjpLDTXWflHkDg.gif" alt="Image" width="498" height="432" loading="lazy">
<em>Examples of Feedforward. Clear: a subtle hint at a new list item as soon as you pull. Moldiv: a slight peek at the controls behind the home screen gives users a cue. Yummly: what was previously just a white background now becomes an input field. Snapchat: pull to refresh, the hint of a color or a spinner is a cue that something is about to happen.</em></p>
<h3 id="heading-spatial-awareness">Spatial Awareness</h3>
<p>Spatial Awareness helps orient users with their environment and clarify the relationships between every element. If you think about it, there are essentially unlimited possibilities to the fictional, digital environments you are creating. Every experience you make has a unique lay of the land… elements may “live” behind the screen, to the left or right, pinched in-between, in a drawer… anything your little designer heart desires. <em>However,</em> you need to make sure you give logic to your environment. It’s especially important to think this through on smaller screens where you’re forced to think about how to properly use the little screen real estate you have and how you can reduce complexity. Having this open canvas while designing an environment is great for you as a designer, but it means that users have to learn and understand what you made. They have to learn <em>every</em> environment they engage with. There’s always a period of onboarding and orientation. Users need to understand where things come from, where they go next, and where they can find them again. You really have to ease people through these transitions so they understand how they got from point A to point B so that it doesn’t feel like a stark, sudden change. Sudden change doesn’t exist in the real world! The main objectives of Spatial Awareness are orienting your users and giving logic to environments. Disney’s principle of <strong>Staging</strong> teaches us a lot about this.</p>
<p>Glen often talked about how the placement of a character in a scene can create expectation. For example, if a character is far left, the open space to the right creates want, “and when you have want, you have something to work with.” It creates an intensity, as if something is about to click with the audience.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*JzKhmaZ_0KAzz4pTrbfPrQ.png" alt="Image" width="800" height="89" loading="lazy">
<em>sequence of Mia in Duet</em></p>
<p>There is a beautiful sequence in Duet where Mia jumps into a pond, swims and flips, then exits the water and does a cartwheel. Glen described the scene as having a “magnetic power” which responded to what Mia was doing and push her forward. For example, when she first hits the water there is a major change — the bubbles are like an explosion around her. He said, “You can’t change total environments without some kind of impact.” These bubbles help tell you where she’s been, and the fish that then surround her tell the audience where she is going next. It’s as if they are squeezing her to the next frame. What I love about this sequence is how the logic to the environment makes it feel like there is a connected thread from frame to frame, which guides the audience’s attention.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*bwqcE-mGNpy7A4OnCqda6Q.gif" alt="Image" width="498" height="432" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*d99NROjEWxxNxQgdEc_APA.gif" alt="Image" width="498" height="432" loading="lazy">
<em>Examples of Spatial Awareness. Calendar: days of the week rest side by side, ease the user between each one. Stellar: a storytelling app takes the theme further into its UI with the use of pages. VSCO: trays of controls act like a toolkit you can pull up from the bottom. Nike Making: categories zoom full screen, push to top, then the layers of sub-categories drop down and float into place.</em></p>
<h3 id="heading-user-focus">User Focus</h3>
<p>User Focus guides your user’s attention and clarifies change states. It’s all about controlling the transitions of hierarchy at each moment in time. It puts emphasis on the right elements depending on what the objective is. There may be multiple layers of elements working together to support that action. It may not always be as simple as bringing one element to the foreground when it’s need… maybe the background reacts too. It could fade a little or darken in order to give more prominence to the focus. You’ll often see a technique like the use of contextual controls — these important little actions you always want to have on hand — and you know they’re there — but you don’t necessarily have to see them all the time. They only come into focus the second you call for them.</p>
<p>User Focus helps bring Clarity to every objective in your experience. <strong>Clarity</strong>: admittedly this is not an official Disney principle! Let’s name this an honorary 13th. But Glen would tell me how this is one of the most important techniques he learned while at Disney. Eric Larson would always emphasize how they should never leave their audience behind.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*r9rpW_WuNOb4opZhulL1qQ.gif" alt="Image" width="350" height="263" loading="lazy">
<em>A scene from Little Whirlwind, animated by Freddie Moore.</em></p>
<p>“At Disney, I kept hearing about the plausible impossible,” Glen would say. There were moments were you could make someone believe something that may seem ridiculously crazy and they don’t question it. For example, in <em>Little Whirlwind</em> (1941), there was a scene where Freddie Moore was animating Mickey trying to hold down a basket of leaves that the whirlwind kept blowing away. All of a sudden, Mickey reaches into the center of himself and pulls out a <em>huge</em> hammer. It was so big because it was the only instance an audience was going to see it and was the most important thing in the scene at that moment. The audience doesn’t question why the hammer is there or where it came from because it’s what’s needed most in that moment. The <em>plausible impossible</em> makes you feel like you can break the rules a little bit.</p>
<blockquote>
<p>“If the audience is with you, they’re happy. If you lose them, no one is happy.”</p>
</blockquote>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*CF-B3m4bJVyni1Gx5YeGjQ.gif" alt="Image" width="498" height="432" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*pTvUEhSK0rdSHwFAwTpf7w.gif" alt="Image" width="498" height="432" loading="lazy">
<em>Examples of User Focus. Pinterest: contextual controls appear at the moment they are needed. Paper Notifications: layers of animation guide attention — the globe bounces, the tray slides out and there’s a slight glow in the title. Peek: selections take up full screen, get very bright while others fade back, selections float back into place when done. Yahoo Weather: motion is the first thing that grabs your attention at the bottom; communicates wind speed.</em></p>
<h3 id="heading-brand-tone-of-voice">Brand Tone of Voice</h3>
<p>I often tell people to think of this the same way we treat copy guidelines. Every project where we think about, <em>“If a brand were to speak to us, what would it say?”</em> we also need to start thinking, <em>“If a brand were to move, what would it feel like?”</em> Is it whimsical? Is it swift and powerful? Is it a subtle added detail that helps users recognize who exactly you are? Demonstrating your tone of voice leaves your users with these little moments where they feel like saying, “I could totally see this brand doing that” because it felt so right and appropriate.</p>
<p>Think about all of the apps, sites, and experiences you use day to day and why you keep using them. Often there are dozens of other apps out there that can do the same exact thing and accomplish the same tasks. They might all have a <em>good</em> user experience but the ones that people gravitate towards to something more. You feel like they <em>delight</em> you, or they <em>enable</em> you, or you <em>get something out of it</em>. They have more than just a good user experience. They have <em>emotional appeal</em>. <strong>Appeal</strong> is the last Disney principle we’ll reference. It’s one of the most magical, but admittedly can be difficult to design for.</p>
<blockquote>
<p>“Appeal is a mysterious thing because you know when you’ve got it and you know it when you don’t have it but you have no idea how to get it.”</p>
</blockquote>
<p>Freddie Moore was an animator at Disney who was really responsible for creating the “look and feel” of Disney, Glen described. Before he came along, Mickey was “just a circle.” It wasn’t the Mickey we know today. Freddie started creating a relationship between every element in his characters. Frank Thomas and Ollie Johnston would often tell the animators, “Every line relates to another line.” When drawing Mickey, everything would follow a theme. You would start with the circle of Mickey’s head, then draw his nose so it pointed up and followed the curve of his head. His eyes came closer to the nose and relate to it, the followed by his eyebrows and mouth — which would come up and push against his cheek. Suddenly there was something about Mickey that you were drawn to. Mickey had the power to pull an audience in because he had appeal. Glen has this belief that every character already exists before you draw them. When you get it right, you recognize them and you are the one who brings the character into the world. When you have Appeal, you find those moments and it’s a beautiful thing when it all comes together.</p>
<blockquote>
<p>“That is the key to appeal. It’s like the harmony of elements… a chord that is perfect. You hear it and say, ‘that’s it.’”</p>
</blockquote>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*BMBuPw2_9q5uT5YSUnTTfQ.gif" alt="Image" width="498" height="432" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*TMzdQO_JbPjjCGP5mEOpEA.gif" alt="Image" width="498" height="432" loading="lazy">
<em>Examples of Brand Tone of Voice. Snapchat: whimsical — the ghosts have become so iconic, people look forward to seeing what else they are going next. Flickr: subtle and clever — when you refresh someone’s profile, the iconic pink and blue dots cycle around. Nike+: the whole app follows the theme of running, with bold and powerful badges sliding into place on the track. Zappos: people love finding easter eggs…especially if it’s a cat wearing a cape.</em></p>
<p>These 5 principles are how you captivate your audience and how they interact with your story. It’s your responsibility to craft an experience sequence that is realistic and emotional, connecting all the keyframes in your work. This is where we start to solve for the missing pieces and define the characters in our work. But the characters we’re designing for aren’t just the ones on screen — we’re also designing for the human element — our main character is our user.</p>
<p>Whether it’s films, apps, sites, or books….no matter the context, the medium, the environment, <em>our objectives are all the same</em>. We’re all engaging with our character in a narrative, and it’s your responsibility to direct each character’s entrance, performance, and exit. The interface you are designing for is just a window into a larger story.</p>
<p>Designing for motion may be something new and unfamiliar, but we’ve all experienced these moments where you step into a new problem and are at a loss on how to solve it. Glen even shared how designing for <em>Duet</em> was an intimidating task at first — he was used to drawing on a piece of paper where if a character goes off the paper they are gone. But in this interactive experience where the audience could follow characters in every direction, it was as if he’d have to solve for an infinite canvas. That’s why having these principles in your back pocket is a great thing — they’ll serve as the foundation for any problem that may come your way.</p>
<blockquote>
<p>“I’m always doing that which I don’t know how to do in order that I may learn how to do it.” — Picasso</p>
</blockquote>
<h4 id="heading-fin">FIN</h4>
<h4 id="heading-bonus-the-making-of-ux-choreography-and-how-i-was-lucky-enough-to-work-with-a-disney-legend">BONUS: The making of UX Choreography and how I was lucky enough to work with a Disney Legend</h4>
<p>Last year I had a simple goal: give a design talk on a topic I was interested in. It was as simple as that. Motion design is a topic I’ve always been interested in and find to be more and more relevant to what we’re doing today as UX and visual designers, so I put together a talk during an <a target="_blank" href="http://chicago.aiga.org/mentor-program-summer-session-studio-tour-talk-1-rga/">AIGA Mentor event</a> last summer at R/GA (and was pretty happy just to accomplish that). I submitted it to SXSW not thinking anything else would become of it, but after a suggestion to find a Disney animator to collaborate with (<em>where was I going to find that?!</em>), a few attempts to reach out to people, a stroke of luck, a random introduction, and the stars aligning — I was introduced to Glen Keane, Disney legend. Glen worked at Disney for 38 years and was the animator behind the characters in some of our most beloved films of all time, such as the Little Mermaid, Beauty &amp; the Beast, and Aladdin. He left Disney 2 years ago to see what else was out there and how he could apply his animation background to something else and continue to push himself (check out his work for <a target="_blank" href="https://play.google.com/store/apps/details?id=com.motorola.avatar&amp;hl=en">Google’s Spotlight Stories</a>, which includes his most recent animated short, Duet). When I told Glen about UX Choreography, he was interested immediately (!). You see, when he first joined Disney, the “9 old men” had to pass down their knowledge of Disney animation principles. “Some day you’re going to do bigger things than us,” Ollie Johnston told Glen. Glen felt like they had “passed the baton” to him. He never imagined that these Disney principles would be translated into something like UX, so he saw this as an opportunity to “pass the baton” to me. So once upon a time, we collaborated on an absolutely wonderful presentation at <a target="_blank" href="http://schedule.sxsw.com/2015/events/event_IAP37950">SXSW</a>. I could literally go on for hours about the stories Glen shared and what I learned, but we’ll have to save that for another time!</p>
<p>_You made it this far, so thanks for reading! If you want more resources to get started here are a few, or tweet me @becca<em>u</em></p>
<p><strong>Find inspiration</strong></p>
<p>Many of the examples in this article were curated by Alli Dryer, check out her site to see dozens of great examples of motion in practice.</p>
<p><a target="_blank" href="http://capptivate.co/">http://capptivate.co/</a></p>
<p>other favorites:</p>
<p><a target="_blank" href="http://hoverstat.es/">http://hoverstat.es/</a></p>
<p><a target="_blank" href="https://instagram.com/userinterfacesio">https://instagram.com/userinterfacesio</a></p>
<p><strong>More awesome reading:</strong></p>
<p><a target="_blank" href="https://medium.com/@pasql/transitional-interfaces-926eb80d64e3">https://medium.com/@pasql/transitional-interfaces-926eb80d64e3</a></p>
<p><a target="_blank" href="http://www.smashingmagazine.com/2013/10/23/smart-transitions-in-user-experience-design/">http://www.smashingmagazine.com/2013/10/23/smart-transitions-in-user-experience-design/</a></p>
<p><strong>Learn about Disney principles, then start making stuff</strong></p>
<p><a target="_blank" href="http://the12principles.tumblr.com/">http://the12principles.tumblr.com/</a></p>
<p><a target="_blank" href="http://uxinmotion.net/">http://uxinmotion.net/</a></p>
<p><a target="_blank" href="http://digg.com/2015/12-principles-animation-ollie-johnston-frank-thomas-alan-becker">http://digg.com/2015/12-principles-animation-ollie-johnston-frank-thomas-alan-becker</a></p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
