Μαθήματα στην HTML Canvas
Τι Είναι το HTML Canvas
Το tag <canvas> της HTML χρησιμοποιείται για τον σχεδιασμό γραφικών στο αέρα (on the fly), με τη βοήθεια κώδικα (scripting), που είναι συνήθως η JavaScript. Το tag αυτό είναι απλά ένα container για τα γραφικά και πρέπει να χρησιμοποιήσουμε ένα script για να δημιουργηθεί το γραφικό. Η τεχνολογία canvas διαθέτει πολλές μεθόδους (συναρτήσεις) για τον σχεδιασμό διαδρομών (paths), κουτιών (boxes), κύκλων (circles), κειμένου (text) καθώς και για την προσθήκη εικόνων (images).
Όλοι οι φυλλομετρητές (browsers) υποστηρίζουν την τεχνολογία canvas, αλλά καλύτερη υποστήριξη παρέχουν ο Internet Explorer και ο Opera.
Μια συνοπτική περιγραφή των δυνατοτήτων της τεχνολογίας Canvas :
- Το Canvas μπορεί να σχεδιάσει πολύχρωμο κείμενο, με ή χωρίς κίνηση (animation).
- Το Canvas διαθέτει σπουδαίες δυνατότητες για σχεδίαση γραφικών, με πολλά γραφήματα και διαγράμματα (charts).
- Τα αντικείμενα του Canvas μπορούν να μετακινούνται, από μια απλή αναπήδηση μπάλας μέχρι και πολύπλοκα animations.
- Το Canvas είναι διαδραστικό (interactive) και μπορεί να ανταποκριθεί σε συμβάντα (events) της JavaScript αλλά και σε ενέργειες του χρήστη, όπως κλικ από το πληκτρολόγιο, κλικ του ποντικιού κ.ά.
- Το Canvas μπορεί να χρησιμοποιηθεί σε παιχνίδια (games).
Παράδειγμα σε Canvas
Στην HTML, ένα στοιχείο <canvas> φαίνεται κάπως έτσι :
<canvas id="myCanvas" width="200" height="100"> </canvas>
Το στοιχείο (tag) <canvas> θα πρέπει να έχει ένα αναγνωριστικό (id attribute), ώστε να μπορούμε να αναφερόμαστε σ’ αυτό από την JavaScript. Οι ιδιότητες (χαρακτηριστικά, attributes) width και height είναι απαραίτητα για να μπορούμε να ορίσουμε το μέγεθος (size) του canvas.
Φυσικά, μπορούμε να έχουμε πολλά στοιχεία <canvas> σε μια HTML σελίδα. Εξ ορισμού, το στοιχείο <canvas> δεν έχει καθόλου περιθώριο (border) και καθόλου περιεχόμενο (content). Για να προσθέσουμε border, πρέπει να χρησιμοποιήσουμε ένα το χαρακτηριστικό (attribute) style :
Παράδειγμα
<!DOCTYPE html> <html> <body> <canvas id="myCanvas" width="200" height="100" style="border:1px solid #000000;"> </canvas> </body> </html>
Ο παραπάνω HTML κώδικας θα εμφανίσει ένα ορθογώνιο.
Σχεδίαση σε Canvas με JavaScript
Όλη η σχεδίαση σ’ ένα HTML canvas πρέπει να γίνει με κώδικα JavaScript :
Παράδειγμα
<!DOCTYPE html> <html> <body> <canvas id="myCanvas" width="200" height="100" style="border:1px solid #c3c3c3;"> Your browser does not support the canvas element. </canvas> <script> var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); ctx.fillStyle = "#FF0000"; ctx.fillRect(0, 0, 150, 75); </script> </body> </html>
Ο παραπάνω HTML κώδικας θα εμφανίσει ένα ορθογώνιο με κόκκινο περίγραμμα και με ενσωματωμένο ένα άλλο κόκκινο γεμιστό ορθογώνιο πάνω και αριστερά.
1ο Βήμα : Εύρεση του Στοιχείου Canvas
Αρχικά, θα πρέπει να εντοπίσουμε το στοιχείο <canvas>, κάτι που γίνεται χρησιμοποιώντας την μέθοδο της DOM HTML getElementById() :
var canvas = document.getElementById("myCanvas");
2ο Βήμα : Δημιουργία ενός Αντικειμένου Σχεδίασης
Δεύτερο, χρειαζόμαστε ένα αντικείμενο σχεδίασης για το. Η μέθοδος getContext() είναι ένα ενσωματωμένο αντικείμενο της HTML, με ιδιότητες και μεθόδους ειδικά για σχεδίαση :
var ctx = canvas.getContext("2d");
3ο Βήμα : Σχεδίαση Πάνω στο Canvas
Τέλος, μπορούμε να σχεδιάσουμε πάνω στο. Απλά θα πρέπει να ορίσουμε την ιδιότητα γεμίσματος (fillstyle) του αντικειμένου σχεδίασης στο κόκκινο χρώμα :
ctx.fillStyle = "#FF0000";
Η τιμή της ιδιότητας fillStyle μπορεί να είναι ένα χρώμα CSS, ένα βαθμωτό (gradient) ή ένα υπόδειγμα (pattern). Η εξ ορισμού τιμή της (default) είναι το μαύρο χρώμα (black).
Η μέθοδος fillRect(x, y, width, height) σχεδιάζει ένα ορθογώνιο (rectangle), που είναι γεμάτο με το χρώμα που έχουμε ορίσει νωρίτερα στο canvas και ξεκινώντας από τη θέση (0, 0), δηλ. από πάνω αριστερά, έως και τη θέση (150, 75), δηλ. κάτω δεξιά για ένα ορθογώνιο με πλάτος 150 pixels και ύψος 75 pixels :
ctx.fillRect(0, 0, 150, 75);
Οι Συντεταγμένες του Canvas
Το στοιχείο canvas της HTML είναι ένα πλέγμα (grid) δύο διαστάσεων, όπου η πάνω αριστερή γωνία του canvas έχει τις συντεταγμένες (0, 0).
Σχεδίαση μιας Γραμμής
Για να σχεδιάσουμε μια ευθεία γραμμή σ’ ένα canvas, χρησιμοποιούμε τις παρακάτω μεθόδους :
- moveTo(x, y) – ορίζει το σημείο εκκίνησης της γραμμής
- lineTo(x, y) – ορίζει το σημείο τερματισμού της γραμμής
Για να σχεδιαστεί τώρα η γραμμή, θα πρέπει να χρησιμοποιήσουμε μια από τις μεθόδους «μελάνης» (“ink” methods), όπως είναι η μέθοδος stroke().
Παράδειγμα
Ορίζουμε ένα σημείο εκκίνησης (starting point) στη θέση (0, 0) και ένα σημείο τερματισμού (ending point) στη θέση (200, 100). Μετά χρησιμοποιούμε την μέθοδο stroke() για να σχεδιάσουμε τη γραμμή :
<!DOCTYPE html> <html> <body> <canvas id="myCanvas" width="200" height="100" style="border:1px solid #d3d3d3;"> Your browser does not support the canvas element. </canvas> <script> var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); ctx.moveTo(0, 0); ctx.lineTo(200, 100); ctx.stroke(); </script> </body> </html>
Ο παραπάνω HTML κώδικας θα σχεδιάσει ένα ορθογώνιο (canvas) από τη θέση (0, 0) έως και τη θέση (200, 100) αλλά και μια ευθεία γραμμή από τη θέση (0, 0) έως και τη θέση (200, 100).
Σχεδίαση Κύκλου
Για να σχεδιάσουμε έναν κύκλο, χρησιμοποιούμε τις εξής μεθόδους :
- beginPath();
- arc(x, y, r, start, stop) – ορίζει τις συντεταγμένες του κέντρου του κύκλου σε pixels, την ακτίνα του κύκλου σε pixels και το σημείο εκκίνησης και τερματισμού ενός τόξου (arc), σε ακτίνια και όχι σε μοίρες
Παράδειγμα
Ορίζουμε έναν κύκλο με τη μέθοδο arc() και μετά χρησιμοποιούμε τη μέθοδο stroke() για να σχεδιάσουμε τον κύκλο :
<!DOCTYPE html> <html> <body> <canvas id="myCanvas" width="200" height="100" style="border:1px solid #d3d3d3;"> Your browser does not support the canvas element. </canvas> <script> var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); ctx.beginPath(); ctx.arc(95, 50, 40, 0, 2*Math.PI); ctx.stroke(); </script> </body> </html>
Βαθμωτά (Gradients) σε Canvas
Τα βαθμωτά (gradients) μπορούν να χρησιμοποιηθούν για να γεμίσουμε ορθογώνια, κύκλους, γραμμές, κείμενα κ.ά. Δηλαδή τα σχήματα στο canvas δεν περιορίζονται μόνο σε συμπαγή (solid) χρώματα.
Υπάρχουν δύο διαφορετικά είδη gradients :
- createLinearGradient(x, y, x1, y1) – δημιουργεί ένα γραμμικό (linear) gradient
- createRadialGradient(x, y, r, x1, y1, r1) – δημιουργεί ένα ακτινωτό/κυκλικό (radial/circular) gradient
Όταν έχουμε ένα βαθμωτό (gradient) αντικείμενο, πρέπει να προσθέσουμε δύο ή περισσότερα stops χρωμάτων. Η μέθοδος addColorStop() καθορίζει τα stops των χρωμάτων και τη θέση τους μέσα στο gradient. Οι θέσεις των gradients μπορεί να είναι οπουδήποτε από 0 έως 1. Για να χρησιμοποιήσουμε ένα gradient, ορίζουμε την ιδιότητα fillStyle ή την ιδιότητα strokeStyle σε τιμή gradient και μετά σχεδιάζουμε το σχήμα, που μπορεί να είναι ορθογώνιο, κείμενο ή μια γραμμή.
Η Μέθοδος createLinearGradient()
Παράδειγμα
Δημιουργία ενός γραμμικού (linear) gradient, όπου γεμίζουμε ένα ορθογώνιο (rectangle) με το συγκεκριμένο gradient :
<!DOCTYPE html> <html> <body> <canvas id="myCanvas" width="200" height="100" style="border:1px solid #d3d3d3;"> Your browser does not support the HTML5 canvas tag. </canvas> <script> var c = document.getElementById("myCanvas"); var ctx = c.getContext("2d"); // Δημιουργία του gradient var grd = ctx.createLinearGradient(0, 0, 200, 0); grd.addColorStop(0, "red"); grd.addColorStop(1, "white"); // Γέμισμα με το gradient ctx.fillStyle = grd; ctx.fillRect(10, 10, 150, 80); </script> </body> </html>
Ο παραπάνω κώδικας θα εμφανίσει μια γραμμική κλιμάκωση από κόκκινο σε άσπρο χρώμα μέσα σ’ ένα ορθογώνιο διαστάσεων 200 Χ 100 pixels. Το gradient δημιουργείται από τη θέση (10, 10) έως και τη θέση (150, 80).
Η Μέθοδος createRadialGradient()
Παράδειγμα
Δημιουργία ενός ακτινωτού/κυκλικού (radial/circular) gradient, όπου γεμίζουμε ένα ορθογώνιο (rectangle) με το gradient :
<!DOCTYPE html> <html> <body> <canvas id="myCanvas" width="200" height="100" style="border:1px solid #d3d3d3;"> Your browser does not support the HTML5 canvas tag. </canvas> <script> var c = document.getElementById("myCanvas"); var ctx = c.getContext("2d"); // Δημιουργία του gradient var grd = ctx.createRadialGradient(75, 50, 5, 90, 60, 100); grd.addColorStop(0, "red"); grd.addColorStop(1, "white"); // Γέμισμα με το gradient ctx.fillStyle = grd; ctx.fillRect(10, 10, 150, 80); </script> </body> </html>
Ο παραπάνω κώδικας θα εμφανίσει μια κυκλική κλιμάκωση από κόκκινο σε άσπρο χρώμα μέσα σ’ ένα ορθογώνιο διαστάσεων 200 Χ 100 pixels. Το gradient δημιουργείται από τη θέση (10, 10) έως και τη θέση (150, 80).
Σχεδίαση Κειμένου στο Canvas
Για να σχεδιάσουμε κείμενο σ’ ένα canvas, η σημαντικότερη ιδιότητα και οι σημαντικότερες μέθοδοι είναι οι εξής :
- font – ορίζει τις ιδιότητες γραμματοσειράς (font properties) του κειμένου
- fillText(text, x, y) – σχεδιάζει ένα «γεμισμένο» κείμενο στο canvas
- strokeText(text, x, y) – σχεδιάζει κείμενο στο canvas (όχι γεμισμένο)
Η Μέθοδος fillText()
Παράδειγμα
Ορίζει τη γραμματοσειρά (font) σε 30px “Arial” και δημιουργεί ένα «γεμισμένο» κείμενο μέσα στο canvas :
<!DOCTYPE html> <html> <body> <canvas id="myCanvas" width="200" height="100" style="border:1px solid #d3d3d3;"> Your browser does not support the canvas element. </canvas> <script> var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); ctx.font = "30px Arial"; ctx.fillText("Hello World", 10, 50); </script> </body> </html>
Ο παραπάνω κώδικας θα εμφανίσει το γεμισμένο κείμενο «Hello World» μέσα σ’ ένα ορθογώνιο διαστάσεων 200 Χ 100 pixels, ξεκινώντας από τη θέση (10, 50).
Η Μέθοδος strokeText()
Παράδειγμα
Ορίζει τη γραμματοσειρά (font) σε 30px “Arial” και δημιουργεί μέσα στο canvas ένα κείμενο χωρίς γέμισμα :
<!DOCTYPE html> <html> <body> <canvas id="myCanvas" width="200" height="100" style="border:1px solid #d3d3d3;"> Your browser does not support the canvas element. </canvas> <script> var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); ctx.font = "30px Arial"; ctx.strokeText("Hello World", 10, 50); </script> </body> </html>
Ο παραπάνω κώδικας θα εμφανίσει το κείμενο «Hello World» μέσα σ’ ένα ορθογώνιο διαστάσεων 200 Χ 100 pixels, ξεκινώντας από τη θέση (10, 50).
Προσθήκη Χρώματος και Κεντράρισμα Κειμένου
Παράδειγμα
Ορίζει τη γραμματοσειρά (font) σε 30px “Comic Sans MS” και εμφανίζει ένα γεμισμένο κόκκινο κείμενο στο κέντρο του canvas :
<!DOCTYPE html> <html> <body> <canvas id="myCanvas" width="300" height="200" style="border:1px solid #d3d3d3;"> Your browser does not support the canvas element. </canvas> <script> var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); ctx.font ="30px Comic Sans MS"; ctx.fillStyle = "red"; ctx.textAlign = "center"; ctx.fillText("Hello World", canvas.width/2, canvas.height/2); </script> </body> </html>
Ο παραπάνω κώδικας θα εμφανίσει το κείμενο «Hello World» μέσα σ’ ένα ορθογώνιο διαστάσεων 300 Χ 200 pixels, στο κέντρο.
Εικόνες στο Canvas
Για να εμφανίσουμε μια εικόνα σ’ ένα canvas, χρησιμοποιούμε την παρακάτω μέθοδο :
- drawImage(image, x, y)
Παράδειγμα
<!DOCTYPE html> <html> <body> <p>Η εικόνα που θα χρησιμοποιηθεί : </p> <img id="scream" width="220" height="277" src="pic_the_scream.jpg" alt="The Scream"> <p>Canvas : </p> <canvas id="myCanvas" width="240" height="297" style="border:1px solid #d3d3d3;"> Your browser does not support the HTML5 canvas tag. </canvas> <script> window.onload = function() { var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); var img = document.getElementById("scream"); ctx.drawImage(img, 10, 10); }; </script> </body> </html>
Θα πρέπει να έχουμε υπόψη μας ότι δεν μπορούμε να εμφανίσουμε την εικόνα πριν αυτή φορτωθεί. Προς τον σκοπό αυτό θα πρέπει να καλέσουμε τη συνάρτηση window.onload().
Ρολόι στο Canvas
Θα δημιουργήσουμε ένα αναλογικό ρολόι με την HTML canvas.
Μέρος Ι – Δημιουργία του Canvas
Το ρολόι χρειάζεται ένα HTML container. Δημιουργούμε ένα 300 x 300 pixel HTML canvas:
<!DOCTYPE html> <html> <body> <canvas id="canvas" width="300" height="300" style="background-color:#333"> </canvas> <script> var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); var radius = canvas.height / 2; ctx.translate(radius, radius); radius = radius * 0.90 drawClock(); function drawClock() { ctx.arc(0, 0, radius, 0 , 2*Math.PI); ctx.fillStyle = "white"; ctx.fill(); } </script> </body> </html>
Επεξήγηση του Κώδικα
Προσθέτουμε ένα στοιχείο HTML <canvas> στην ιστοσελίδα :
<canvas id="canvas" width="300" height="300" style="background-color:#333"> </canvas>
Δημιουργούμε ένα αντικείμενο (object) canvas με την εντολή var canvas από το στοιχείο HTML :
var canvas = document.getElementById("canvas");
Δημιουργούμε ένα 2d αντικείμενο σχεδίασης (drawing object) με την εντολή var ctx για το αντικείμενο canvas :
var ctx = canvas.getContext("2d");
Υπολογίζουμε την ακτίνα (radius) του ρολογιού με βάση το ύψος (height) του canvas :
var radius = canvas.height / 2;
Ξανατοποθετούμε τη θέση (0, 0) του αντικειμένου σχεδίασης στο κέντρο του canvas :
ctx.translate(radius, radius);
Ελαττώνουμε την ακτίνα του ρολογιού στο 90% ώστε το ρολόι να σχεδιαστεί (χωρέσει) μέσα στο canvas :
radius = radius * 0.90;
Δημιουργούμε μια συνάρτηση (function) για να σχεδιασθεί το ρολόι (clock) :
function drawClock() { ctx.arc(0, 0, radius, 0 , 2*Math.PI); ctx.fillStyle = "white"; ctx.fill(); }
Canvas Clock Face
Μέρος II – Σχεδίαση του Προσώπου του Ρολογιού (Clock Face)
Το ρολόι χρειάζεται ένα πρόσωπο (face) και προς τον σκοπό αυτό δημιουργούμε μια σχετική συνάρτηση στην JavaScript :
<!DOCTYPE html> <html> <body> <canvas id="canvas" width="400" height="400" style="background-color:#333"> </canvas> <script> var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); var radius = canvas.height / 2; ctx.translate(radius, radius); radius = radius * 0.90 drawClock(); function drawClock() { drawFace(ctx, radius); } function drawFace(ctx, radius) { var grad; ctx.beginPath(); ctx.arc(0, 0, radius, 0, 2*Math.PI); ctx.fillStyle = 'white'; ctx.fill(); grad = ctx.createRadialGradient(0, 0, radius*0.95, 0, 0, radius * 1.05); grad.addColorStop(0, '#333'); grad.addColorStop(0.5, 'white'); grad.addColorStop(1, '#333'); ctx.strokeStyle = grad; ctx.lineWidth = radius*0.1; ctx.stroke(); ctx.beginPath(); ctx.arc(0, 0, radius*0.1, 0, 2*Math.PI); ctx.fillStyle = '#333'; ctx.fill(); } </script> </body> </html>
Επεξήγηση του Κώδικα
Δημιουργούμε μια συνάρτηση drawFace() για να σχεδιάσουμε το πρόσωπο (face) του ρολογιού :
function drawClock() { drawFace(ctx, radius); } function drawFace(ctx, radius) { }
Σχεδίαση του άσπρου κύκλου :
ctx.beginPath(); ctx.arc(0, 0, radius, 0, 2*Math.PI); ctx.fillStyle = 'white'; ctx.fill();
Δημιουργία ενός ακτινωτού (radial) gradient (95% και 105% από την αρχική ακτίνα του ρολογιού) :
grad = ctx.createRadialGradient(0,0,radius*0.95, 0,0,radius*1.05);
Δημιουργία 3 color stops, που αντιστοιχούν στο εσωτερικό (inner), μεσαίο (middle) και έξω (outer) άκρο του τόξου (arc) :
grad.addColorStop(0, '#333'); grad.addColorStop(0.5, 'white'); grad.addColorStop(1, '#333');
Θα πρέπει να έχουμε υπόψη μας ότι τα color stops δημιουργούν ένα3D effect.
Ορισμός του gradient ως το stroke style για το αντικείμενο σχεδίασης :
ctx.strokeStyle = grad;
Ορισμός του πλάτους της γραμμής (line width) του αντικειμένου σχεδίασης (10% της ακτίνας-radius) :
ctx.lineWidth = radius * 0.1;
Σχεδίαση του κύκλου :
ctx.stroke();
Σχεδίαση του κέντρου του κύκλου :
ctx.beginPath(); ctx.arc(0, 0, radius*0.1, 0, 2*Math.PI); ctx.fillStyle = '#333'; ctx.fill();
Αριθμοί Ρολογιού στο Canvas
Μέρος III – Σχεδίαση των Αριθμών του Ρολογιού
Το ρολόι χρειάζεται αριθμούς και προς τον σκοπό αυτό δημιουργούμε μια συνάρτηση στην JavaScript :
<!DOCTYPE html> <html> <body> <canvas id="canvas" width="400" height="400" style="background-color:#333"> </canvas> <script> var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); var radius = canvas.height / 2; ctx.translate(radius, radius); radius = radius * 0.90 drawClock(); function drawClock() { drawFace(ctx, radius); drawNumbers(ctx, radius); } function drawFace(ctx, radius) { var grad; ctx.beginPath(); ctx.arc(0, 0, radius, 0, 2*Math.PI); ctx.fillStyle = 'white'; ctx.fill(); grad = ctx.createRadialGradient(0, 0, radius * 0.95, 0, 0, radius * 1.05); grad.addColorStop(0, '#333'); grad.addColorStop(0.5, 'white'); grad.addColorStop(1, '#333'); ctx.strokeStyle = grad; ctx.lineWidth = radius*0.1; ctx.stroke(); ctx.beginPath(); ctx.arc(0, 0, radius*0.1, 0, 2*Math.PI); ctx.fillStyle = '#333'; ctx.fill(); } function drawNumbers(ctx, radius) { var ang; var num; ctx.font = radius*0.15 + "px arial"; ctx.textBaseline="middle"; ctx.textAlign="center"; for (num = 1; num < 13; num++) { ang = num * Math.PI / 6; ctx.rotate(ang); ctx.translate(0, -radius*0.85); ctx.rotate(-ang); ctx.fillText(num.toString(), 0, 0); ctx.rotate(ang); ctx.translate(0, radius*0.85); ctx.rotate(-ang); } } </script> </body> </html>
Επεξήγηση του Κώδικα
Ορίζουμε το μέγεθος της γραμματοσειράς (font size) του αντικειμένου σχεδίασης στο 15% της ακτίνας (radius) :
ctx.font = radius*0.15 + "px arial";
Ορίζουμε την ευθυγράμμιση κειμένου (text alignment) στο μέσο και το κέντρο της θέσης εκτύπωσης :
ctx.textBaseline="middle"; ctx.textAlign="center";
Υπολογίζουμε τη θέση εκτύπωσης (print position) για 12 αριθμούς στο 85% της ακτίνας (radius), με περιστροφή (PI/6 = π/6) για τον κάθε αριθμό :
for (num= 1; num < 13; num++) { ang = num * Math.PI / 6; ctx.rotate(ang); ctx.translate(0, -radius*0.85); ctx.rotate(-ang); ctx.fillText(num.toString(), 0, 0); ctx.rotate(ang); ctx.translate(0, radius*0.85); ctx.rotate(-ang); }
Οι Δείχτες του Ρολογιού του Canvas
Μέρος IV – Σχεδίαση των Δειχτών του Ρολογιού
Το ρολόι χρειάζεται δείχτες (hands) και προς τον σκοπό αυτό δημιουργούμε μια συνάρτηση στην JavaScript :
<!DOCTYPE html> <html> <body> <canvas id="canvas" width="400" height="400" style="background-color:#333"> </canvas> <script> var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); var radius = canvas.height / 2; ctx.translate(radius, radius); radius = radius * 0.90 drawClock(); function drawClock() { drawFace(ctx, radius); drawNumbers(ctx, radius); drawTime(ctx, radius); } function drawFace(ctx, radius) { var grad; ctx.beginPath(); ctx.arc(0, 0, radius, 0, 2*Math.PI); ctx.fillStyle = 'white'; ctx.fill(); grad = ctx.createRadialGradient(0, 0, radius*0.95, 0, 0, radius * 1.05); grad.addColorStop(0, '#333'); grad.addColorStop(0.5, 'white'); grad.addColorStop(1, '#333'); ctx.strokeStyle = grad; ctx.lineWidth = radius*0.1; ctx.stroke(); ctx.beginPath(); ctx.arc(0, 0, radius*0.1, 0, 2*Math.PI); ctx.fillStyle = '#333'; ctx.fill(); } function drawNumbers(ctx, radius) { var ang; var num; ctx.font = radius*0.15 + "px arial"; ctx.textBaseline="middle"; ctx.textAlign="center"; for(num = 1; num < 13; num++) { ang = num * Math.PI / 6; ctx.rotate(ang); ctx.translate(0, -radius*0.85); ctx.rotate(-ang); ctx.fillText(num.toString(), 0, 0); ctx.rotate(ang); ctx.translate(0, radius*0.85); ctx.rotate(-ang); } } function drawTime(ctx, radius){ var now = new Date(); var hour = now.getHours(); var minute = now.getMinutes(); var second = now.getSeconds(); // hour hour = hour%12; hour = (hour*Math.PI/6) + (minute*Math.PI/(6*60)) + (second * Math.PI / (360*60)); drawHand(ctx, hour, radius*0.5, radius*0.07); // minute minute = (minute*Math.PI / 30) + (second * Math.PI / (30*60)); drawHand(ctx, minute, radius*0.8, radius*0.07); // second second=(second*Math.PI/30); drawHand(ctx, second, radius*0.9, radius*0.02); } function drawHand(ctx, pos, length, width) { ctx.beginPath(); ctx.lineWidth = width; ctx.lineCap = "round"; ctx.moveTo(0,0); ctx.rotate(pos); ctx.lineTo(0, -length); ctx.stroke(); ctx.rotate(-pos); } </script> </body> </html>
Επεξήγηση του Κώδικα
Χρησιμοποιούμε τη συνάρτηση Date() για να πάρουμε από το σύστημα την ώρα (hour), τα λεπτά (minute) και τα δευτερόλεπτα (second) :
var now = new Date(); var hour = now.getHours(); var minute = now.getMinutes(); var second = now.getSeconds();
Υπολογίζουμε τη γωνία του δείχτη της ώρας (hour hand) και το σχεδιάζουμε με μήκος το 50% της ακτίνας (radius) και με πλάτος το 7% της ακτίνας (radius) :
hour = hour % 12; hour = (hour * Math.PI/6) + (minute * Math.PI / (6*60)) + (second * Math.PI / (360*60)); drawHand(ctx, hour, radius*0.5, radius*0.07);
Χρησιμοποιούμε την ίδια τεχνική για τα λεπτά (minutes) και τα δευτερόλεπτα (seconds). Η ρουτίνα drawHand() απλά σχεδιάζει μια γραμμή με δεδομένο μήκος (length) και πλάτος (width).
Λειτουργία του Ρολογιού Canvas
Θα κατασκευάσουμε τώρα ένα αναλογικό ρολόι με την τεχνολογία HTML Canvas.
Μέρος V – Ξεκίνημα του Ρολογιού
Για να ξεκινήσει (δουλέψει) το ρολόι, καλούμε κατά διαστήματα τη συνάρτηση drawClock() :
<!DOCTYPE html> <html> <body> <canvas id="canvas" width="400" height="400" style="background-color:#333"> </canvas> <script> var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); var radius = canvas.height / 2; ctx.translate(radius, radius); radius = radius * 0.90 setInterval(drawClock, 1000); function drawClock() { drawFace(ctx, radius); drawNumbers(ctx, radius); drawTime(ctx, radius); } function drawFace(ctx, radius) { var grad; ctx.beginPath(); ctx.arc(0, 0, radius, 0, 2*Math.PI); ctx.fillStyle = 'white'; ctx.fill(); grad = ctx.createRadialGradient(0, 0, radius*0.95, 0, 0, radius*1.05); grad.addColorStop(0, '#333'); grad.addColorStop(0.5, 'white'); grad.addColorStop(1, '#333'); ctx.strokeStyle = grad; ctx.lineWidth = radius*0.1; ctx.stroke(); ctx.beginPath(); ctx.arc(0, 0, radius*0.1, 0, 2*Math.PI); ctx.fillStyle = '#333'; ctx.fill(); } function drawNumbers(ctx, radius) { var ang; var num; ctx.font = radius*0.15 + "px arial"; ctx.textBaseline = "middle"; ctx.textAlign = "center"; for(num = 1; num < 13; num++) { ang = num * Math.PI / 6; ctx.rotate(ang); ctx.translate(0, -radius*0.85); ctx.rotate(-ang); ctx.fillText(num.toString(), 0, 0); ctx.rotate(ang); ctx.translate(0, radius*0.85); ctx.rotate(-ang); } } function drawTime(ctx, radius){ var now = new Date(); var hour = now.getHours(); var minute = now.getMinutes(); var second = now.getSeconds(); //hour hour = hour%12; hour = (hour*Math.PI/6) + (minute*Math.PI/(6*60)) + (second*Math.PI/(360*60)); drawHand(ctx, hour, radius*0.5, radius*0.07); //minute minute = (minute * Math.PI/30) + (second * Math.PI/(30*60)); drawHand(ctx, minute, radius*0.8, radius*0.07); // second second = (second*Math.PI/30) drawHand(ctx, second, radius*0.9, radius*0.02); } function drawHand(ctx, pos, length, width) { ctx.beginPath(); ctx.lineWidth = width; ctx.lineCap = "round"; ctx.moveTo(0, 0); ctx.rotate(pos); ctx.lineTo(0, -length); ctx.stroke(); ctx.rotate(-pos); } </script> </body> </html>
Επεξήγηση του Κώδικα
Το μόνο πράγμα που πρέπει να κάνουμε για να ξεκινήσει το ρολόι είναι να καλούμε κατά διαστήματα τη συνάρτηση drawClock() .
Substitute: drawClock(); With: setInterval(drawClock, 1000);
Το διάστημα (interval) είναι σε χιλιοστά του δευτερολέπτου (milliseconds) και έτσι η συνάρτηση drawClock() θα καλείται κάθε 1 δευτερόλεπτο (1.000 milliseconds).
HTML Canvas Reference
Το tag (ετικέτα) HTML5 <canvas> χρησιμοποιείται για να σχεδιάσουμε γραφικά (graphics), στον αέρα, μέσω κώδικα (scripting), που είναι συνήθως η JavaScript. Όμως, το στοιχείο <canvas> δεν διαθέτει από μόνο του κάποιες σχεδιαστικές δυνατότητες (είναι απλά ένα container για γραφικά), οπότε πρέπει να χρησιμοποιήσουμε ένα script για να σχεδιάσουμε τα γραφικά.
Η μέθοδος getContext() επιστρέφει ένα αντικείμενο (object) που παρέχει μεθόδους (methods) και ιδιότητες (properties) για σχεδίαση πάνω στο canvas. Αυτή η αναφορά (reference) θα καλύψει τις μεθόδους και τις ιδιότητες του αντικειμένου getContext(“2d”), το οποίο μπορούμε να χρησιμοποιήσουμε για να σχεδιάσουμε κείμενα (text), γραμμές (lines), κουτιά (boxes), κύκλους (circles) κ.ά., πάνω στο canvas.
Χρώματα, Στυλ και Σκιές
Ιδιότητα | Περιγραφή |
fillStyle | Ορίζει ή επιστρέφει το χρώμα, το gradient ή το pattern που θα χρησιμοποιηθεί για να γεμίσει το σχέδιο |
strokeStyle | Ορίζει ή επιστρέφει το χρώμα, το gradient ή το υπόδειγμα που θα χρησιμοποιηθεί για τα strokes |
shadowColor | Ορίζει ή επιστρέφει το χρώμα που θα χρησιμοποιηθεί για σκιές |
shadowBlur | Ορίζει ή επιστρέφει το επίπεδο θόλωσης (blur level) για τις σκιές |
shadowOffsetX | Ορίζει ή επιστρέφει το χρώμα την οριζόντια απόσταση της σκιάς από το σχήμα |
shadowOffsetY | Ορίζει ή επιστρέφει το χρώμα την κάθετη απόσταση της σκιάς από το σχήμα |
Μέθοδος | Περιγραφή |
createLinearGradient() | Δημιουργεί ένα γραμμικό (linear) gradient για χρήση στο περιεχόμενο του canvas |
createPattern() | Επιστρέφει ένα συγκεκριμένο στοιχείο στην καθορισμένη διεύθυνση (κατεύθυνση) |
createRadialGradient() | Δημιουργεί ένα ακτινωτό.κυκλικό (radial/circular)gradient για χρήση στο περιεχόμενο του canvas |
addColorStop() | Καθορίζει τα χρώματα και τη θέση stop σ’ ένα αντικείμενο gradient |
Στυλ Γραμμής
Ιδιότητα | Περιγραφή |
lineCap | Ορίζει ή επιστρέφει το στυλ (style) των άκρων (end caps) μιας γραμμής |
lineJoin | Ορίζει ή επιστρέφει το είδος (type) της γωνίας που δημιουργείται όταν συναντιούνται δύο γραμμές |
lineWidth | Ορίζει ή επιστρέφει το τρέχον πλάτος της γραμμής |
miterLimit | Ορίζει ή επιστρέφει το μέγιστο μήκος θηλυκώματος (miter) |
Ορθογώνια
Μέθοδος | Περιγραφή |
rect() | Δημιουργεί ένα ορθογώνιο (rectangle) |
fillRect() | Σχεδιάζει ένα γεμισμένο (filled) ορθογώνιο (rectangle) |
strokeRect() | Σχεδιάζει ένα μη γεμισμένο (no fill) ορθογώνιο (rectangle) |
clearRect() | Καθαρίζει τα συγκεκριμένα pixels εντός ενός δεδομένου ορθογωνίου (rectangle) |
Διαδρομές
Μέθοδος | Περιγραφή |
fill() | Γεμίζει το τρέχον σχέδιο ή διαδρομή (path) |
stroke() | Σχεδιάζει (δημιουργεί) τη διαδρομή (path) που έχουμε ορίσει προηγουμένως |
beginPath() | Ξεκινάει μια διαδρομή (path) ή επαναφέρει (reset) το τρέχον path |
moveTo() | Μετακινεί το path στο συγκεκριμένο σημείο του canvas, χωρίς να δημιουργεί μια γραμμή |
closePath() | Δημιουργεί μια διαδρομή (path) από το τρέχον σημείο πίσω προς το αρχικό σημείο |
lineTo() | Προσθέτει ένα καινούργιο σημείο και δημιουργεί μια γραμμή προς εκείνο το σημείο από το τελευταίο καθορισμένο σημείο στο canvas |
clip() | Κόβει (clip) μια περιοχή συγκεκριμένου σχήματος και μεγέθους από ένα σχήμα από το αρχικό canvas |
quadraticCurveTo() | Δημιουργεί μια καμπύλη Bézier 2ου βαθμού (τετραγωνική) |
bezierCurveTo() | Δημιουργεί μια καμπύλη Bézier 3ου βαθμού (κυβική) |
arc() | Δημιουργεί τόξο, καμπύλη ή κύκλο |
arcTo() | Δημιουργεί ένα τόξο ή καμπύλη ανάμεσα σε δύο εφαπτομένες |
isPointInPath() | Επιστρέφει την τιμή true αν το συγκεκριμένο σημείο βρίσκεται στην τρέχουσα διαδρομή (path), αλλιώς επιστρέφει false |
Μετασχηματισμοί
Μέθοδος | Περιγραφή |
scale() | Κλιμακώνει, δηλ. μεγαλώνει ή μικραίνει το τρέχον σχέδιο (drawing) |
rotate() | Περιστρέφει το τρέχον σχέδιο (drawing) |
translate() | Μεταφέρει την θέση (0, 0) πάνω στο canvas |
transform() | Αντικαθιστά τον τρέχον πίνακα μετασχηματισμού (matrix) για το σχέδιο (drawing) |
setTransform() | Επαναφέρει τον τρέχον μετασχηματισμό (transform) σε πίνακα ταυτότητα (identity matrix) και μετά τρέχει (εκτελεί) τη συνάρτηση transform() |
Κείμενο
Ιδιότητα | Περιγραφή |
font | Ορίζει ή επιστρέφει τις τρέχουσες ιδιότητες fontγια το περιεχόμενο του κειμένου |
textAlign | Ορίζει ή επιστρέφει την τρέχουσα ευθυγράμμιση για το περιεχόμενο του κειμένου |
textBaseline | Ορίζει ή επιστρέφει το τρέχον text baseline που χρησιμοποιήθηκεused when drawing text |
Μέθοδος | Περιγραφή |
fillText() | Σχεδιάζει ένα γεμισμένο κείμενο (filled) στο canvas |
strokeText() | Σχεδιάζει μη γεμισμένο κείμενο (no fill) στοcanvas |
measureText() | Επιστρέφει ένα αντικείμενο που περιέχει το πλάτος του καθορισμένου κειμένου |
Σχεδίαση Εικόνας
Method | Description |
drawImage() | Σχεδιάζει μια εικόνα, ένα canvas ή video στο canvas |
Χειρισμός Pixels
Property | Description |
width | Επιστρέφει το πλάτος (width) ενός αντικειμένου ImageData |
height | Επιστρέφει το ύψος (height) ενός αντικειμένου ImageData |
data | Επιστρέφει ένα αντικείμενο που περιέχει τα δεδομένα εικόνας ενός συγκεκριμένου αντικειμένου ImageData |
Method | Description |
createImageData() | Δημιουργεί ένα καινούργιο, κενό αντικείμενο ImageData |
getImageData() | Επιστρέφει ένα αντικείμενο ImageData που αντιγράφει τα δεδομένα των pixels για ένα ορθογώνιο ενός canvas |
putImageData() | Τοποθετεί τα δεδομένα μιας εικόνας (από ένα καθορισμένο αντικείμενο ImageData) πίσω στο canvas |
Σύνθεση
Property | Description |
globalAlpha | Ορίζει ή επιστρέφει την τρέχουσα τιμή alpha ή transparency (διαφάνειας) του σχεδίου |
globalCompositeOperation | Ορίζει ή επιστρέφει το πώς μια καινούργια εικόνα σχεδιάζεται πάνω σε μια υπάρχουσα εικόνα |
Άλλα
Method | Description |
save() | Αποθηκεύει την κατάσταση (state) του τρέχοντος context |
restore() | Επιστρέφει την πρόσφατα αποθηκευμένη κατάσταση του path και τα χαρακτηριστικά του (attributes) |
createEvent() | |
getContext() | |
toDataURL() |
Πηγή:
Αν βρήκατε το άρθρο μας χρήσιμο, θέλετε να μείνετε ενημερωμένοι για όλα τα νέα στο τομέα της τεχνολογίας καθώς και σε χρηστικά άρθρα, βοηθήστε μας κάνοντας like στην σελίδα μας στο Facebook πατώντας εδώ