機械制圖國家標準的繪圖模板
The theme for week #5 of the Weekly Coding Challenge is:
每周編碼挑戰第5周的主題是:
創建繪圖應用程序 (Creating a Drawing Application)
This is the first application that we are building in the #weeklyCodingChallenge program. So far we have built smaller projects, so this is pretty exciting if you ask me! ?
這是我們在#weeklyCodingChallenge程序中構建的第一個應用程序。 到目前為止,我們已經建立了較小的項目,因此如果您問我,這將非常令人興奮! ?
In this article we’ll use p5js, a drawing library, to build a Drawing Application:
在本文中,我們將使用繪圖庫p5js來構建繪圖應用程序 :
Check out the CodePen here:
在此處查看CodePen:
If you want to learn more about p5js and what it does, you can visit their official website. Basically, I am using it because it works very well on top of the browser’s canvas element by providing a clear API.
如果您想了解更多有關p5js及其功能的信息,可以訪問其官方網站 。 基本上,我使用它是因為它通過提供一個清晰的API在瀏覽器的canvas元素上很好地工作。
HTML (The HTML)
As you can notice in the example above, on the left side of the screen we have a .sidebar
. We'll put inside it our 'tools' - a color
picker, a weight
selector and the clear
button (trashcan icon):
您可以在上面的示例中注意到,在屏幕的左側,我們有一個.sidebar
。 我們將在其中放入“工具”-一個color
選擇器,一個weight
選擇器和一個clear
按鈕(垃圾桶圖標):
<div class="sidebar"><ul><li><label for="color">Color:</label><input type="color" id="color" /></li><li><label for="weight">Stroke:</label><input type="number" id="weight" min="2" max="200" value="3" /></li><li><button id="clear"><i class="fa fa-trash"></i></button></li></ul>
</div>
CSS (The CSS)
Using CSS we’ll move the .sidebar
and everything that’s inside it in the left side. We will style it a little bit to make it look nicer (nothing fancy, basic CSS):
使用CSS,我們將.sidebar
及其內部的所有內容移到左側。 我們將對其進行一些樣式設置,使其看起來更好(沒什么花哨的,基本CSS):
.sidebar {background-color: #333;box-shadow: 0px 0px 10px rgba(30, 30, 30, 0.7);color: #fff;position: absolute;left: 0;top: 0;height: 100vh;padding: 5px;z-index: 1000;
}.sidebar ul {display: flex;justify-content: center;align-items: flex-start;flex-direction: column;list-style-type: none;padding: 0;margin: 0;height: 100%;
}.sidebar ul li {padding: 5px 0;
}.sidebar input,
.sidebar button {text-align: center;width: 45px;
}.sidebar li:last-of-type {margin-top: auto;
}.sidebar button {background-color: transparent;border: none;color: #fff;font-size: 20px;
}.sidebar label {display: block;font-size: 12px;margin-bottom: 3px;
}
Now for the important part…
現在重要的是……
JS / P5JS (The JS / P5JS)
As you might have noticed, we haven’t added a canvas
element into our HTML since p5js will create it for us.
您可能已經注意到,我們沒有在HTML中添加canvas
元素,因為p5js會為我們創建它。
There are two important functions which we’ll use from the p5js library:
我們將在p5js庫中使用兩個重要的函數:
setup — is called once when the program starts. It’s used to define initial environment properties such as screen size and background color.
設置 —在程序啟動時被調用一次。 它用于定義初始環境屬性,例如屏幕尺寸和背景色。
draw —is called directly after
setup()
. Thedraw()
function continuously executes the lines of code contained inside its block.draw —在
setup()
之后直接調用。draw()
函數連續執行其塊內包含的代碼行。
function setup() {// create a canvas which is full width and heightcreateCanvas(window.innerWidth, window.innerHeight);// Add a white background to the canvasbackground(255);
}function draw() {}
Before moving forward, let’s stop for a moment and see what we want to achieve.
在繼續前進之前,讓我們先停下來看看我們要實現的目標。
So, basically, we want to add a mousepressed
eventListener to the canvas
that will start 'drawing' a shape inside it as long as the mouseIsPressed
.
所以,基本上,我們要添加一個mousepressed
事件監聽到canvas
,將啟動“繪制”里面的形狀,只要mouseIsPressed
。
We’ll create an array of points which we’re going to use to create a path
(or a shape) using the beginShape and endShape methods to draw this shape inside the canvas. The shape is going to be constructed by connecting a series of vertices (see vertex for more information).
我們將使用BeginShape和endShape方法創建一個點數組,這些點將用于創建path
(或形狀)以在畫布內繪制該形狀。 將通過連接一系列頂點來構造形狀(有關更多信息,請參見頂點 )。
As we want this shape to be re-drawn every time, we’ll put this code inside the draw
method:
由于我們希望每次都重新繪制此形狀,因此將這段代碼放入draw
方法中:
const path = [];function draw() {// disabled filling geometry - p5js functionnoFill();if (mouseIsPressed) {// Store the location of the mouseconst point = {x: mouseX,y: mouseY};path.push(point);}beginShape();path.forEach(point => {// create a vertex at the specified locationvertex(point.x, point.y);});endShape();
}
As you can see, p5js has a mouseIsPressed flag that we can use to detect when the mouse buttons are pressed.
如您所見,p5js有一個mouseIsPressed標志,我們可以用來檢測何時按下鼠標按鈕。
Everything might look good so far, but there is a big issue. Once the mouse button is released and we try to draw another shape, the last point from the previous shape will be connected to the first point of the new shape. This is definitely not what we want, so we need to change our approach a little bit.
到目前為止,一切看起來都不錯,但是有一個大問題。 釋放鼠標按鈕并嘗試繪制其他形狀后,先前形狀的最后一個點將連接到新形狀的第一個點。 這絕對不是我們想要的,因此我們需要稍微改變一下方法。
Instead of having one array of points (the path array), we’ll create a pathsarray
and we are going to store all the paths
inside it. Basically, we’ll have a double array with points. Also, for this, we will need to keep track of the currentPath
while the mouse is still pressed. We’ll reset this array once the mouse button is pressed again. Confusing? ? Let’s see the code and I bet that it will become clearer:
除了創建一個點數組(路徑數組)以外,我們將創建一個pathsarray
,并將所有paths
存儲在其中。 基本上,我們將有一個帶有點的雙精度數組。 同樣,為此,我們將需要在仍然按下鼠標的同時跟蹤currentPath
。 再次按下鼠標按鈕后,我們將重置此數組。 令人困惑? ? 讓我們看一下代碼,我敢打賭它將變得更加清晰:
const paths = [];
let currentPath = [];function draw() {noFill();if (mouseIsPressed) {const point = {x: mouseX,y: mouseY};// Adding the point to the `currentPath` arraycurrentPath.push(point);}// Looping over all the paths and drawing all the points inside thempaths.forEach(path => {beginShape();path.forEach(point => {stroke(point.color);strokeWeight(point.weight);vertex(point.x, point.y);});endShape();});
}// When the mouse is pressed, this even will fire
function mousePressed() {// Clean up the currentPathcurrentPath = [];// Push the path inside the `paths` arraypaths.push(currentPath);
}
I also added some comments in the code above, make sure you check them out.
我還在上面的代碼中添加了一些注釋,請確保將它們簽出。
The mousePressed function is called once after every time a mouse button is pressed — p5js stuff! ?
每次按下鼠標按鈕時都會調用一次 mousePressed 函數 -p5js的東西! ?
Great! Now we can draw individual shapes in our canvas! ?
大! 現在我們可以在畫布上繪制單個形狀了! ?
The last thing to do is to hook up those buttons that we created in the HTML and use the values that are inside them to style the shape:
最后要做的是連接我們在HTML中創建的按鈕,并使用其中的值來設置形狀的樣式:
const colorInput = document.getElementById('color');
const weight = document.getElementById('weight');
const clear = document.getElementById('clear');function draw() {noFill();if (mouseIsPressed) {const point = {x: mouseX,y: mouseY,// storing the color and weights provided by the inputs for each pointcolor: colorInput.value,weight: weight.value};currentPath.push(point);}paths.forEach(path => {beginShape();path.forEach(point => {// using the color and the weight to style the strokestroke(point.color);strokeWeight(point.weight);vertex(point.x, point.y);});endShape();});
}clear.addEventListener('click', () => {// Remove all the pathspaths.splice(0);// Clear the backgroundbackground(255);
});
And with this, we have finished our little application! Yay! ?
至此,我們完成了我們的小應用程序! 好極了! ?
整個JS代碼 (The entire JS code)
const colorInput = document.getElementById('color');
const weight = document.getElementById('weight');
const clear = document.getElementById('clear');
const paths = [];
let currentPath = [];function setup() {createCanvas(window.innerWidth, window.innerHeight);background(255);
}function draw() {noFill();if (mouseIsPressed) {const point = {x: mouseX,y: mouseY,color: colorInput.value,weight: weight.value};currentPath.push(point);}paths.forEach(path => {beginShape();path.forEach(point => {stroke(point.color);strokeWeight(point.weight);vertex(point.x, point.y);});endShape();});
}function mousePressed() {currentPath = [];paths.push(currentPath);
}clear.addEventListener('click', () => {paths.splice(0);background(255);
});
Also, make sure that you import the p5js
file in your html too before importing this js
file.
另外,在導入此js
文件之前,請確保p5js
html中導入p5js
文件。
結論 (Conclusion)
I hope that you liked this drawing app that we’ve built. There are a bunch of functionalities that could be added to this app and I challenge you to let your creative mind to come up with new ideas! ?
希望您喜歡我們構建的此繪圖應用程序。 有很多功能可以添加到此應用程序中,我挑戰您讓您的創意思維提出新想法! ?
What if you could save the drawing as an image (.png
or .jpg
)? ? (you can do this with the p5js library).
如果可以將圖形另存為圖像( .png
或.jpg
)怎么辦? ? (您可以使用p5js庫執行此操作)。
As of now, we are only checking the mouse
events. Maybe you could make it work on mobile, too, by figuring out the touch
events? The sky is the limit with the amount of functionalities that could be added to this app!
截至目前,我們僅檢查mouse
事件。 通過弄清touch
事件,也許您也可以使其在移動設備上工作? 天空是可以添加到此應用程序的功能數量的限制!
I’d love to see what you are going to build! Tweet me @florinpop1705 with your creation!
我很想看看你要建立什么! 用您的創作給我@ florinpop1705發推文 !
You might also like one of the other challenges from the Weekly Coding Challenge program. Check them out here.
您可能還會喜歡“每周編碼挑戰”計劃中的其他挑戰之一。 在這里查看它們。
See ya next time! Happy Coding! ?
下次見! 編碼愉快! ?
Originally published at www.florin-pop.com.
最初在www.florin-pop.com上發布。
翻譯自: https://www.freecodecamp.org/news/how-to-build-a-drawing-app-with-p5js-9b8d16e9364a/
機械制圖國家標準的繪圖模板