[JS DOM&UI] домашно canvas - задача 1


1
Здравейте колеги,
Имам въпрос по първата задача от домашното за canvas - как правите елипсите? С помощта на кривите линии или с код. Поразрових се и намерих ето този линк:
http://www.html5canvastutorials.com/advanced/html5-canvas-ovals/
Елипсите се получават, само че след задаването на .scale() става разминаване на координатите и малко трудно за нацелване на точна позиция.
Дали има някакъв начин друг начин за правене на елиспите с curves или нещо друго, което ползвате. Човечето с шапката е почити само елипси и ми взе здравето:)
Благодаря.



Отговори



1
Това правя... идеята е  взета от твоя линк, но аз не използвам транслате и смятам правилно координатите.
 
this.ellipse = function (x, y, diameterX, diameterY, strokeColor, fillColor, start, finish) {
        var scaleHeight = diameterY / diameterX;
        var radius = diameterX / 2;
 
        this.ctx.save();
        this.ctx.scale(1, scaleHeight);
 
        this.ctx.beginPath();
 
        if (start === undefined || start === null) {
            start = 0;
        }
 
        if (finish === undefined || start === null) {
            finish = 2 * Math.PI;
        }
 
        this.ctx.arc(x, y / scaleHeight, radius, start, finish);
 
        this.ctx.restore();
 
        if (fillColor !== undefined && fillColor !== null) {
            this.ctx.fillStyle = fillColor;
            this.ctx.fill();
        }
 
        if (strokeColor !== undefined && strokeColor !== null) {
            this.ctx.strokeStyle = strokeColor;
            this.ctx.stroke();
        }
    };

от lithical (992 точки)


0
Можеш да замениш проверката if(start === undefined || start === null) с if(start) в случая. if(!start) е обратния случай. Предложените варианти са удобни само когато не очакваш start да съдържа числото 0-ла, което се изчислява до false, иначе ще си задаваш доста въпроси. :>

от martin.nikolov (4535 точки)


2
Аз използвах функциите от този линк (адаптирано за "легнала" и "изправена" елипса):
http://www.williammalone.com/briefs/how-to-draw-ellipse-html5-canvas/
Ползва криви с две контролни точки.



0
Колеги, някаква идея за цилиндъра от шапката на човечето. Опитвам се bezierCurve, но нещо не ми се получава?



0
Можеш да използваш готов метод за рисуване на цилиндър: http://stackoverflow.com/questions/14498521/how-to-draw-a-cylinder-on-html5-canvas
Мисля, че трябва да се пипне нещо, тъй като не оцветяваше горната окръжност.

от martin.nikolov (4535 точки)


1

Това ми е кода за човека с шапката: http://jsfiddle.net/8mbJ9/

Имам 2 проблемa: 

1. Ако погледнете устата, очертанието бледнее в горната и долната част на елипсата - ако преместя устата да се създава преди context.stroke() за носа,  носа изчезва, но пък устата се очертава както трябва. Как да фиксна този бъг?

2. Когато задам context.rotate(15), за да наклоня устата с 15 градуса, тя направо изчезва. 

Къде бъркам? Ще съм благодарен ако някой ми помогне!smiley

 


от m.tonkov (161 точки)


0
Ако намалиш ротате на 0.05, поне ще видиш къде е устата. //context.rotate(0.05); Аз обаче я направих с setTransform(). Чукни го в google да видиш какво му означават параметрите. В твоя случай : context.setTransform(1, 0.25, -0.5, 1, 90, -15); май е добре.

от d.brezoev (212 точки)

0
В кода ти, аз преместих устата да се създава преди носа и нямаше проблем носа да изчезне, сложих ти context.lineWidth = 2; и stroke(); - за устата, а за носа върнах обратно context.lineWidth = 1; стои прилично :)

от tsonko_genov (708 точки)



4

http://pastebin.com/NgbYHvdT

 

Абсолютно хардкоднато, но има коментари къде се рисува носът, устата, шапката и т.н. Може би най-простия, но със сигурност не и най-елегантен метод. Дано помогне на някой..


от ivan.mihov1 (4988 точки)


0
https://github.com/NikolayNanev/JavaScriptDOMandUI/tree/master/2.Canvas
Трите изображения, но изчертани с KineticJS. Може малко да читвам, защото все пак целта на домашното е да се запознаем с чистия canvas, но предполагам, че за в бъдеще рядко ще пише без някаква библиотека.
Постарах се всичко да е във функции и да е КПК, но приветствам всякакви предложения за подобряване на кода. : )

от Николай Нанев (0 точки)


0
Спестил си си големи мъки, колега... Не одобрявам. Искам всички да се мъчат така, както аз се мъчих! :D
Шегувам се.

от easlavov (4118 точки)


1

Ето го и моето човече от първа задача за елипсите си ползвам следната функция 

function drawEllipse(ctx, x, y, w, h) {
  var kappa = 0.5522848,     // 4 * ((√(2) - 1) / 3)
      ox = (w / 2) * kappa, // control point offset horizontal
      oy = (h / 2) * kappa, // control point offset vertical
      xe = x + w,           // x-end
      ye = y + h,           // y-end
      xm = x + w / 2,       // x-middle
      ym = y + h / 2;       // y-middle
 
  ctx.beginPath();
  ctx.moveTo(x, ym);
  ctx.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y);
  ctx.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym);
  ctx.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye);
  ctx.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym);
  ctx.stroke();
}
 
Edit: Дали има възможност да се избегне непрекъснатото повторение на context.stroke() и context.fill(); някои има ли идея?

от petar_nikov (564 точки)


4

Ето го и моето решение.

Това което съм направил е функция за чертане на кръг, елипса и линия.

Кръгът и елипсата имат optional параметри да се зададе начален и краен ъгъл - ако не са зададени ги приема от 0 до 2xPI.

След това решението с използването на функциите е доста лесно. Самите картинки съм ги направил също като функции, така че лесно може да се местят по canvas-а


от wnvko (3123 точки)


1
Това е моето мегадърводелско решение http://jsbin.com/daqibugo/1/edit . Чак сега като видях други решения се сетих, че можеше да сложа някоя друга функция :D
P.S. Имам един въпрос. Трябва ли, когато рисувам цяля октъжност, да слагам ctx.closePath(), защото го видях по различни начини?

от half.human (242 точки)


0
Можеш да пуснеш за устата arc да ти се изчертае за координата x да ти е 115 вместо 105, и ще изглежда като на заданието то презентацията :).

от tsonko_genov (708 точки)

0
Не виждам смисъл да го слагаш за окръжността. Така или иначе, когато на следващия елемент кажеш beginPath, ще започнеш нова пътека.

от Vazzzz (1380 точки)