In part 1, we rendered the layers to the DOM, and now we’re going to make it so the layers can be rearranged and interacted with from the DOM.

The important lines here are the ones setting each layer element to draggable: true and associating the actual layer object with the layer element on line 1669 by assigning it to a new property of the layer element. I called it layerObj but you could call it anything.

Now we’re going to use drag events to change the order of the layers.


This won’t be much of a tutorial, but this is a glimpse into my initial attempt to add layers to a drawing app. This is the first time I’ve really thought keeping a state would be useful, so that’s probably the direction I’ll be moving in the future. For now, however, I’ve written some workarounds just to get it started.

Step 1 is to initiate an array of layers and add the default layer:

Most layers will be raster layers, so that’s the only type I’ll focus on for now. …


Try it here.

You may have seen articles about using the box-shadow property in CSS to make pixel art. The process involves creating an element with the width and height of a pixel, and creating a box-shadow for each pixel. It looks something like this:


For my pixel art app, Pixel V, I want to make it easy to use a reference image layered behind or on top of the user’s drawing. For this tutorial, I’m going to go over how to upload files to a website with HTML and JavaScript, as well as how to style that button with CSS.

In HTML, there’s an <input type=”file”/> which we’ll use for getting our file, but it’s not straightforward to style it. So, we’ll create a label for it and style the label instead, while hiding the input element itself.

HTML

<label for="file-upload" class="custom-file-upload btn"> Upload Background…

Try it here.

In my pursuit to render a well-aliased bezier curve for a pixel art tool, I came upon a paper on rasterizing curves by Alois Zingl. The paper covers many types of curves, but I’m just going to focus on quadratic bezier curves. The code in the paper is written in C++, so I translated the code into JavaScript for my purposes. I highly recommend reading the paper, as it explains the concepts very thoroughly.

A bezier curve is defined parametrically, so it can’t be defined with y as a function of x. Instead, you define x and…


Last time we rendered the curve by connecting the pixels with a series of lines, creating a polyline that estimates the bezier curve. That method may work sometimes, but it often produces artifacts when used for pixel art. This time we’re going to try plotting each pixel one after another. However, this is not a simple matter because a bezier curve is a parametric function where the x and y values depend on time (t). Plotting the curve using t results in points that are equally far apart in terms of time, but not in space.

There are two methods…


To give a color picker the expected behavior, there are some tricks to how you set up the interaction between the gradient canvas and the user’s mouse. The main thing is that while the user is holding down click and moving the selector around, the action should still function while the user’s mouse is outside the canvas area.

The key is instead of adding the event listeners to the canvas, add the listeners for mousemove and mouseup to the window.

//canvas listeners
this.target.addEventListener("mousedown", (e) => {
this.handleMouseDown(e);
});
window.addEventListener("mousemove", (e) => {
this.handleMouseMove(e);
});
window.addEventListener("mouseup", (e) => {
this.handleMouseUp(e);
});


In application.rb, add the following line:

config.generators do |g|
g.orm :active_record, primary_key_type: :uuid
end

Create a new migration from the command line:

rails g migration enable_uuid

You should get a file that looks like this:

class EnableUuid < ActiveRecord::Migration[6.0]end

Then add this method inside that migration to enable uuid:

class EnableUuid < ActiveRecord::Migration[6.0]
def change
enable_extension 'uuid-ossp'
enable_extension 'pgcrypto'
end
end

Finally, in your regular migrations, you can set the id type to uuid:

class CreateUsers < ActiveRecord::Migration[6.0]
def change
create_table :users, id: :uuid do |t|
t.string :username
t.timestamps
end
end
end

When you run rails db:migrate, your schema for theUser model should then look like this:

create_table "devices", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
t.string "username"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end

Try it here.

The final product

Last time I went over the basic layout in HTML and CSS. Now I’ll go over creating the gradients and user interaction.

Let’s start by creating a Picker class and assigning all the buttons to associate with. target is the canvas we’ll be using for the main gradient area.

class Picker { constructor(target, width, height) { this.target = target; this.width = width; this.height = height; this.target.width = width; this.target.height = height; //Get context this.context = this.target.getContext("2d"); //mouse this.mouseState = "none"; //color selector circle this.pickerCircle = { x: 10, y: 10, width: 6, height: 6 }; this.clicked =…


A major feature missing from my pixel drawing web app is the ability to select a color. Making a color picker is no simple task, so I’m dividing it up. Before we get to the Javascript, first I’m going to set up the basic layout with HTML and CSS.

This is what it will look like.

It’s important to have a clear vision of what your component will look like, so that’s why I’m starting with a rough layout of the HTML and CSS.

The main container needs to be able to be toggled onto the screen and hidden by the user. …

Tom Cantwell

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store