Рисуем машину на Canvas

canvas
В последнее время тема Canvas стала очень популярной. Многие уже во всю стали использовать данную технологию. А что же в нем можно нарисовать? Да практически всё что угодно. Недавно у меня возникла идея нарисовать какую-нибудь машину на canvas.

Конечно не трудно догадаться, что код JavaScript будет занимать много места, но все-таки я решил попытаться это сделать, тем более в интернете подобных тем я не встречал. И так для рисования машины нам понадобятся следующие методы:

  1. beginPath();
  2. moveTo();
  3. bezierCurveTo();
  4. lineTo();
  5. lineJoin;
  6. quadraticCurveTo();
  7. stroke();

Сложность всей работы сводится к тому, что очень сложно отследить координаты линий которые рисуешь т.е рисунок практически не возможно нарисовать не оборвав какой-нибудь линии. Расписывать методы я не буду так как уже писали раньше о них. Единственное скажу, что дополнительно ко всему использовалась функция drawEllipse(x, y, a, b), которая позволяет рисовать эллипс.

А вот и сам код:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Машина на canvas</title>
</head>
<body>
<style>
canvas{
border:1px solid #a1a4a8; 
-moz-border-radius:20px;
-webkit-border-radius: 20px;
-khtml-border-radius: 20px;
border-radius:20px;
padding-top:20px;
box-shadow:0 0 10px 0 #555555;
-webkit-box-shadow:0 0 10px 0 #555555;
-moz-box-shadow:0 0 10px 0 #555555;}
</style>
<canvas id="Mycanvas" width="800" height="300"></canvas>
<script>
 var canvas = document.getElementById("Mycanvas");
    var car = canvas.getContext('2d');
car.translate(0, 30);
    car.beginPath();
       car.moveTo(95, 125);
       car.bezierCurveTo(160, 155, 225, 110, 235, 175);
car.lineTo(290,160);
car.lineJoin='round';
car.bezierCurveTo(300, 50, 360, 60, 350, 140);
car.lineTo(500,107);
car.lineJoin='round';
car.bezierCurveTo(510, 110, 530, 10, 560, 40);
car.bezierCurveTo(570, 25, 550, 25, 560, 20);
car.quadraticCurveTo(530,10,502,10);
       car.stroke(); 
car.beginPath();
car.moveTo(100, 155);
    car.quadraticCurveTo(140, 190, 233, 165);

        car.stroke(); 
car.beginPath();
car.moveTo(120,167);
car.lineTo(110, 132);
car.quadraticCurveTo(110,105,180,65);
car.bezierCurveTo(300,-20,525,-20,500,15);
car.lineTo(340,60);
car.lineTo(370,20);
car.quadraticCurveTo(340,15,275,20);
car.stroke(); 
car.beginPath();
car.moveTo(350,58);
car.bezierCurveTo(375,-10,465,10,450,30);
car.stroke(); 
car.beginPath();
car.moveTo(370,20);
car.bezierCurveTo(375,10,465,-10,455,27);
car.stroke();
car.beginPath();
car.moveTo(150, 136);
car.quadraticCurveTo(155,175,170,175);
car.stroke();
car.beginPath();
car.moveTo(150, 136);
car.quadraticCurveTo(215,95,340,60);
car.quadraticCurveTo(170,95,180,65);
car.stroke();
car.beginPath();
car.moveTo(100, 155);
car.bezierCurveTo(100, 157, 88, 130, 95, 125);
car.quadraticCurveTo(95, 105, 180, 65);
car.stroke();
CanvasRenderingContext2D.prototype.drawEllipse = function (x, y, a, b) {
  // Запоминаем положение системы координат (CК) и масштаб
  this.save();
  this.beginPath();
 
  // Переносим СК в центр будущего эллипса
  this.translate(x, y);
 
  /*
   * Масштабируем по х.
   * Теперь нарисованная окружность вытянется в a / b раз
   * и станет эллипсом
   */
 
  this.scale(a / b, 1);
 
  // Рисуем окружность, которая благодаря масштабированию станет эллипсом
  this.arc(0, 0, b, 0, Math.PI * 2, true);
 
  // Восстанавливаем СК и масштаб
  this.restore();
 
  this.closePath();
}
car.beginPath();    
car.drawEllipse(325, 126, 25, 43);
car.stroke();
car.beginPath();    
car.drawEllipse(325, 126, 22, 40);
car.stroke();
car.beginPath();    
car.moveTo(320, 169);
car.quadraticCurveTo(295,170,295,155);
car.lineTo(293, 149);
car.stroke();
car.beginPath();    
car.drawEllipse(549, 75, 22, 38);
car.stroke();
car.beginPath();    
car.drawEllipse(549, 75, 19, 35);
car.stroke();
car.beginPath();    
car.moveTo(545, 114);
car.quadraticCurveTo(525,115,522,100);
car.lineTo(517, 75);
car.stroke();
 </script>
</body>
</html>


Результат можно посмотреть здесь.

P/s: Машинка ещё не дорисована и требует доработки. Со временем выложу весь код и рисунок.

4 комментария

avatar
А если нарисовать в Илюстраторе и посмотреть на полученный код? Сильно отличается?)
avatar
Да фиг его знает? Писал код ручками в иллюстраторе не работал.
avatar
Ну и извращения

Положу ка я тут две функции:
<code>// n-угольник
function ngon(cont,x,y,sides,angle,size) {
    var ang = (Math.PI * 2) / sides;
    
    cont.beginPath();
    
    for (i = 0; i <= Math.PI * 2; i += ang) {
        cont.lineTo(x+Math.cos(i+angle)*(size.w/2),y+Math.sin(i+angle)*(size.h/2));
    }
    
    cont.closePath();
    cont.fill();
    cont.stroke();
    
}</code>
и
<code>// Прямоугольник с закругленными углами
function roundedRect(cont, x,y,w,h,r) {
    cont.beginPath();
    
    cont.moveTo(x-w/2,y-h/2 + r);
    cont.bezierCurveTo(x-w/2,y-h/2,x-w/2,y-h/2,x-w/2 + r,y-h/2);
    cont.lineTo(x+w/2-r,y-h/2);
    cont.bezierCurveTo(x+w/2,y-h/2,x+w/2,y-h/2,x+w/2,y-h/2 + r);
    cont.lineTo(x+w/2,y+h/2 - r);
    cont.bezierCurveTo(x+w/2,y+h/2,x+w/2,y+h/2,x+w/2-r,y+h/2);
    cont.lineTo(x-w/2+r,y+h/2);
    cont.bezierCurveTo(x-w/2,y+h/2,x-w/2,y+h/2,x-w/2,y+h/2 - r);
    
    cont.closePath();
    cont.fill();
    cont.stroke();
}</code>
avatar
Пардон, забыл поблагодарить за статью и похвалить автора за огромную работу :)