• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Ograniczenie długości linii (canvas)

Object Storage Arubacloud
+1 głos
562 wizyt
pytanie zadane 31 marca 2019 w JavaScript przez program naczelny Gaduła (3,320 p.)
Witam!

Tworzę program który ma na celu kierowanie linii o STAŁEJ długości w stronę myszki, jeżeli znajduje się w polu płótna canvas. Ta długość to może być, powiedzmy 50 px. Zaczęłem próbując sinusami i cosinusami, ale nie wychodziło, więc spróbowałem chwycić się innego sposobu. Więc od x y naszego punktu poprostu tworzę linię do x y myszki, i linia pięknie podąża za myszką. Sęk w tym iż jej długość ma być jak już napisałem stała i nie wiem jak to zrobić. lineTo(x/3,y/3) odpada bo długość linii będzie się proporcjonalnie zmieniała.

Pytam po raz drugi bo ostatnio pytanie przeszło bez odpowiedzi, na której mi niewiarygodnie zależy.

1 odpowiedź

+1 głos
odpowiedź 31 marca 2019 przez Chess Szeryf (76,710 p.)
edycja 31 marca 2019 przez Chess
 
Najlepsza
<canvas id="canvas"></canvas>
const canvas = document.getElementById('canvas');

const ctx = canvas.getContext('2d');

canvas.width = 400;
canvas.height = 400;
canvas.style.border = '1px solid black';

const line_length = 50;
const line_margin_left = 0;
const line_margin_top = 0;

canvas.addEventListener('mousemove', function(e) {

		var bounding = this.getBoundingClientRect();
		
		var x = e.clientX - bounding.left - line_margin_left;
		var y = e.clientY - bounding.top - line_margin_top;
		
		ctx.clearRect(0, 0, this.width, this.height);
		ctx.beginPath();
		ctx.moveTo(x, y);
		ctx.lineTo(x + 0, y + line_length);
		ctx.stroke();
		ctx.closePath();
		
}, false);

Jeśli coś można było napisać lepiej, to popraw.

Proszę:

<canvas id="canvas"></canvas>
const canvas = document.getElementById('canvas');

const ctx = canvas.getContext('2d');

canvas.width = 400;
canvas.height = 400;
canvas.style.border = '1px solid black';

const line_length = 50;
const line_margin_left = 0; //length cursor mouse from line in horizontal
const line_margin_top = 0; //length cursor mouse from line in vertical

canvas.addEventListener('mousemove', function(e) {

		var bounding = this.getBoundingClientRect();
		
		var x = e.clientX - bounding.left - line_margin_left;
		var y = e.clientY - bounding.top - line_margin_top;
		
		const line_direction = -1; // -1 normal, 1 reverse
		const canvas_coordinates_middle_x = this.width/2;
		const canvas_coordinates_middle_y = this.height/2;
		
		
		x = (x - canvas_coordinates_middle_x);
		y = line_direction * (y - canvas_coordinates_middle_y);
		
		var pd = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); // Pitagoras definition
		
		var c1 = ((line_length * y) / pd); // coefficient
		
		ctx.clearRect(0, 0, this.width, this.height);
		ctx.beginPath();
		ctx.moveTo(canvas_coordinates_middle_x, canvas_coordinates_middle_y);
		ctx.lineTo(((x * c1 / y) + canvas_coordinates_middle_x), (canvas_coordinates_middle_y - (c1) + 0));
		ctx.stroke();
		ctx.closePath();
		
}, false);

Tales definition

c=5, x=3, y=4, l=50.

c/y = l/a 5/4=50/a 5a=200 a=40

x/y=d/a 3/4=d/40 4d=120 d=30

Odpowiedź: (30, 40) - współrzędne.

Dojście do rozwiązania:

Jeśli myszka np. jest na współrzędnych (3, 4) i chcemy żeby linia była długa na 50 jednostek, to wtedy możemy posłużyć się metodą układania odpowiednich proporcji. Po obliczeniu poprawnych długości boków otrzymujemy współrzędne na osi x, y, które należy podać w ctx.lineTo(x, y);. Rysunek przedstawia jak należało narysować linie (trójkąty), aby móc następnie ułożyć odpowiednie równanie. Reasumując należało obliczyć współrzędne (d, a).

Moim zdaniem też tak ja powinieneś rozrysować sobie te zadanie na kartce i trochę zacząć dumać nad łamigłówką. Nieraz lepiej wziąć kartkę i ołówek niż tak ślęczeć przed krzemem.

Czasem warto podstawić jakieś dane, aby otrzymać odpowiedź i sporo informacji na temat zadania.

Jest to twierdzenie Talesa i/lub podobieństwo trójkątów, więc odsyłam tutaj:

https://www.matemaks.pl/podobienstwo-trojkatow.html

https://www.youtube.com/watch?v=H0lau6o28xk

Dobrze, że jeszcze raz zapytałeś się o to samo, gdy nie uzyskałeś odpowiedzi, ale mogłeś odświeżyć temat pisząc coś w odpowiedziach.

Możesz zanimować sobie tarczę zegara np..

Gdyby coś nieprawidłowo działało, to pisz śmiało.

 

komentarz 31 marca 2019 przez program naczelny Gaduła (3,320 p.)

nie o to mi chodziło, upraszczając - od punktu środkowego chcę żeby linia obracała się w stronę myszki. To działa, kieruje się linia od środka do miejsca myszki które zaznaczyłem strzałką, lecz chcę żeby ta linia była stałej długości. (50px zaczynając od środka)

komentarz 31 marca 2019 przez program naczelny Gaduła (3,320 p.)

@Chess, super, dzięki! Aż mi głupio że sam nie pomyślałem o zwykłych proporcjach ;) ale już wszystko jasne problem rozwiązany.

komentarz 4 kwietnia 2019 przez program naczelny Gaduła (3,320 p.)

@Chess, Znalazłem lepsze rozwiązanie problemu, ponieważ umożliwia obracanie zdjęć, tworzenie animacji w trakcie obracania elementu:

 

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
canvas.width = 1000;
canvas.height = 1000;
canvas.style.border = '1px solid black';
var szukane, stosunek, angle, x, y, bounding;
 
canvas.addEventListener('mousemove', function(e) {
 
        bounding = this.getBoundingClientRect();
		x = e.clientX - bounding.left - canvas.width / 2;
        y = e.clientY - bounding.top - canvas.height / 2;

        szukane = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
		
		stosunek = y / szukane; //obliczanie sinusa
		angle = Math.asin(stosunek);
		console.log(angle , "fajny");
		
		ctx.save();
		ctx.clearRect(0, 0, canvas.width, canvas.height);
		ctx.translate (canvas.width / 2, canvas.height / 2);
		
		if(x >= 0)ctx.rotate(angle);
		else {ctx.rotate(Math.PI - angle );}
		
		ctx.fillRect(0, -10, 100, 20);
        ctx.restore();
		
		ctx.beginPath();
		ctx.moveTo(canvas.width / 2,canvas.height / 2);
		ctx.lineTo(x + (canvas.width / 2), y + (canvas.height / 2));
		ctx.stroke();
		ctx.closePath();
}, false);

Mimo że trochę metodą prób i błędów, doszedłem do dobrego rozwiązania :) 
Musiałem zrozumieć o prostu czym są radiany i z czym to się je.

Podobne pytania

0 głosów
0 odpowiedzi 244 wizyt
0 głosów
0 odpowiedzi 88 wizyt
0 głosów
1 odpowiedź 323 wizyt
pytanie zadane 22 listopada 2018 w HTML i CSS przez Daichi Obywatel (1,250 p.)

92,572 zapytań

141,423 odpowiedzi

319,645 komentarzy

61,959 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...