For my final project, I made an interactive drawing panel for users to drag and create whatever shape they want with certain constraint. This project is meant to express an idea that with limit resources, we could create infinite possibilities. The project was inspired by a hiring site from Google Creative Lab (www.creativelab5.com). Check the below link for my project demo:
Two basic operations:
- Click onto the end point of “N Y U S H”, and after you see the control points (showing as a little rectangle), you could drag these 5 five letters into any shape.
- Click onto any of the flying torch and drag them. The torch will not move when you click onto them. If you want them to move again, mouse hover onto that torch, and type “d”.
The complete source code is on my GitHub. Check it out here:
(Check the git log to see my developing process if you are interested 🙂 There were some weird experiments going on…)
The most interesting part for me in this project is to provide my user a way of controlling different objects on the screen, while leave them with maximum flexibility to create their ideal “NYUSH”. I’ll briefly explain how I manage the letter and the flying torch interaction.
I’ll separate my work into “letter” and “torch” part.
For the letters “N, Y, U, S”, each of them are controlled by 4 control points, and for “H”, it’s controlled by 6 control points. These control points are statically defined during the setup process to make the letters appear normally on the screen. The below screenshot explains the idea of control points.
- Create the control-drag effect:
In the main drawing loop, I keep calculating my current mouse cursor and it’s distance with all the control points. If the distance is less than a certain value for a certain point, I get which control point that is and which letter it belongs to, marked the letter as under control, and if the user clicked onto the point at the same time, control points for that letter shows up. For “N, Y, H”, it’s simply connecting control points with lines (actually, patterns that forms a line), and for “U, S”, it’s Bezier curve constructed with 4 control points using p5’s build in Bezier curve function. When a mouseDrag() event occurs (meaning that when I dragged a certain control point) I keep tracking of my mouse position and updating the value of that point.
- Create the (ellipse or other filling) shape out of these control points:
We focus on filling out a pattern between two control points. We had a start point and an end point. Then, by representing these two points in vectors and subtracting these two points, we had a direction. We passed in a ‘step’ parameter to define how many repetitive patterns we want between two end points, adding some small adjustment regarding the length and width of the pattern, and we have our fill pattern function below:
After having such function, it’s fairly straightforward to apply it into N, Y, H since these are just all straight lines. It’s a littler tricker for U and S. Bezier curve in p5 allows you to define bezier points that, given a start point, an end point, and how many points you want on the curve between these terminal points, generate points on the curve. I take use of these and defined some points on the curve, and fill each pair of these ‘terminal points’ in the same way as fill a straight line.
For the torch, I loaded a pre-processed image with a specific width and height. Dragging the torch for moving around is similar as dragging the control points on letters. When I implemented dragging, I though it might also be nice to implement a ‘free’ that allows the still torch to move again. I tried to implement it with re-clicking on the same torch (so that the first click will stop it and the second will make it move). But it turns out that there might be mouse event conflicts in this implementation. I gave up trying to define the correct mouse event but went for an easier approach: using keyboard.
Similarly, mouse hovering the torch will mark it under control and waiting for the “d” key to be typed. These torch are moving in a flocking system so the direction are totally random and based on their environment.
An interesting piece that I like is that I put 20 torch on the screen which are divided up into 5 groups. So that if you find the correct 4 torch of the same size and positioning them well, you can create a NYUSH logo.
For the background adjustment, I adopt the HSL color mode and let the user to adjust the H value. The code for background is as below:
As moon suggested, it might be fun if I could eventually create a multi-player drawing panel with some server side code that stores and pushes the state of each user. This will be the future direction that I headed towards. Let me know if you have other cool ideas. 😀