Programing

HTML5 캔버스에 회전 된 텍스트 그리기

lottogame 2020. 12. 10. 08:27
반응형

HTML5 캔버스에 회전 된 텍스트 그리기


개발중인 웹 응용 프로그램의 일부에서는 다양한 정보를 표시하는 막대 그래프를 만들어야합니다. 사용자의 브라우저가 가능하다면 HTML5 캔버스 요소를 사용하여 그릴 것이라고 생각했습니다. 그래프에 선과 막대를 그리는 데 문제가 없지만 축, 막대 또는 선에 레이블을 지정할 때 걸림돌이 발생했습니다. 회전 된 텍스트를 캔버스 요소에 그려 레이블이 지정되는 항목과 정렬되도록하려면 어떻게합니까? 몇 가지 예는 다음과 같습니다.

  • 텍스트를 시계 반대 방향으로 90도 회전하여 y 축에 레이블 지정
  • 텍스트를 시계 반대 방향으로 90도 회전하여 수직 막대 그래프의 막대에 레이블을 지정합니다.
  • 선 그래프의 레이블 선에 텍스트를 임의의 양만큼 회전

모든 포인터를 주시면 감사하겠습니다.


다른 사람들이 언급했듯이 기존 그래프 솔루션을 재사용하고 싶을 수 있지만 텍스트 회전은 그리 어렵지 않습니다. (나에게) 다소 혼란스러운 부분은 전체 컨텍스트를 회전 한 다음 그 위에 그리는 것입니다.

ctx.rotate(Math.PI*2/(i*6));

각도는 라디안이다 . 이 코드는 MDC 캔버스 자습서변환 부분을 위해 만들어진 이 예제에서 가져온 것입니다 .

보다 완전한 솔루션은 아래 답변을 참조하십시오 .


유사한 문제를 가진 다른 사람들을 돕기 위해 이것을 게시합니다. 컨텍스트를 저장하고, 컨텍스트를 번역하고, 컨텍스트를 회전하고, 텍스트를 그린 다음 컨텍스트를 저장된 상태로 복원하는 5 단계 접근 방식으로이 문제를 해결했습니다.

캔버스에 겹쳐진 좌표 그리드를 조작하는 것으로 번역과 컨텍스트 변환을 생각합니다. 기본적으로 원점 (0,0)은 캔버스의 왼쪽 상단 모서리에서 시작됩니다. X는 왼쪽에서 오른쪽으로 증가하고 Y는 위에서 아래로 증가합니다. 검지와 엄지 손가락으로 왼손으로 "L"을 만들고 엄지 손가락을 아래로 내린 상태에서 앞쪽으로 뻗으면 엄지 손가락은 Y가 증가하는 방향을 가리키고 검지 손가락은 방향을 가리 킵니다. X를 증가시키는 것입니다. 초급이라는 것을 알고 있지만, 변환과 회전에 대해 생각할 때 도움이됩니다. 그 이유는 다음과 같습니다.

컨텍스트를 변환 할 때 좌표 그리드의 원점을 캔버스의 새 위치로 이동합니다. 컨텍스트를 회전 할 때 왼손으로 만든 "L"을 원점에 대한 라디안으로 지정한 각도로 표시된 양만큼 시계 방향으로 회전하는 것을 생각해보십시오. strokeText 또는 fillText를 사용할 때 새로 정렬 된 축을 기준으로 좌표를 지정합니다. 아래에서 위로 읽을 수 있도록 텍스트의 방향을 지정하려면 레이블을 시작하려는 위치 아래로 변환하고 -90도 회전하고 채우기 또는 strokeText를 사용하여 회전 된 x 축을 따라 각 레이블을 오프셋합니다. 다음과 같이 작동합니다.

 context.save();
 context.translate(newx, newy);
 context.rotate(-Math.PI/2);
 context.textAlign = "center";
 context.fillText("Your Label Here", labelXposition, 0);
 context.restore();

.restore ()는 .save ()를 호출했을 때의 상태로 컨텍스트를 다시 재설정합니다. 즉, "정상"으로 되 돌리는 데 편리합니다.



이것은 이전 답변에 대한 일종의 후속 조치이지만 약간 (희망적으로) 추가됩니다.

주로 제가 명확히하고 싶은 것은 보통 우리가 draw a rectangle at 10, 3.

따라서 move origin to 10, 3다음 과 같이 생각하면 , draw rectangle at 0, 0. 그런 다음 우리가해야 할 일은 그 사이에 회전을 추가하는 것입니다.

또 다른 중요한 점은 텍스트 정렬입니다. 0, 0에 텍스트를 그리는 것이 가장 쉽기 때문에 올바른 정렬을 사용하면 텍스트 너비를 측정하지 않고도 그렇게 할 수 있습니다.

우리는 여전히 텍스트를 세로로 중앙에 맞추기 위해 양만큼 움직여야하며, 안타깝게도 캔버스는 줄 높이를 크게 지원하지 않으므로 추측하고 확인하는 것입니다 (더 나은 것이 있으면 수정하십시오).

필자는 화면의 실제 지점이 글꼴이 이동하는 위치를 보여주기 위해 3 개의 정렬로 포인트와 텍스트를 제공하는 3 개의 예제를 만들었습니다.

여기에 이미지 설명 입력

var font, lineHeight, x, y;

x = 100;
y = 100;
font = 20;
lineHeight = 15; // this is guess and check as far as I know
this.context.font = font + 'px Arial';


// Right Aligned
this.context.save();
this.context.translate(x, y);
this.context.rotate(-Math.PI / 4);

this.context.textAlign = 'right';
this.context.fillText('right', 0, lineHeight / 2);

this.context.restore();

this.context.fillStyle = 'red';
this.context.fillRect(x, y, 2, 2);


// Center
this.context.fillStyle = 'black';
x = 150;
y = 100;

this.context.save();
this.context.translate(x, y);
this.context.rotate(-Math.PI / 4);

this.context.textAlign = 'center';
this.context.fillText('center', 0, lineHeight / 2);

this.context.restore();

this.context.fillStyle = 'red';
this.context.fillRect(x, y, 2, 2);


// Left
this.context.fillStyle = 'black';
x = 200;
y = 100;

this.context.save();
this.context.translate(x, y);
this.context.rotate(-Math.PI / 4);

this.context.textAlign = 'left';
this.context.fillText('left', 0, lineHeight / 2);

this.context.restore();

this.context.fillStyle = 'red';
this.context.fillRect(x, y, 2, 2);

this.context.fillText('right', 0, lineHeight / 2);은 기본적으로 0, 0이지만 텍스트가 점 근처에 중앙에 오도록 약간 이동하는 것을 제외하고


다음은 homebrew에 대한 HTML5 대안입니다. http://www.rgraph.net/ 당신은 그들의 방법을 리버스 엔지니어링 할 수 있습니다 ....

Flot ( http://code.google.com/p/flot/ ) 또는 GCharts ( http://www.maxb.net/scripts/jgcharts/include/demo/#1 ) 와 같은 것을 고려할 수도 있습니다 . 꽤 멋지지만 완전히 이전 버전과 호환되며 구현하기가 무섭습니다.


Funkodebat posted a great solution which I have referenced many times. Still, I find myself writing my own working model each time I need this. So, here is my working model... with some added clarity.

First of all, the height of the text is equal to the pixel font size. Now, this was something I read a while ago, and it has worked out in my calculations. I'm not sure if this works with all fonts, but it seems to work with Arial, sans-serif.

Also, to make sure that you fit all of the text in your canvas (and don't trim the tails off of your "p"'s) you need to set context.textBaseline*.

You will see in the code that we are rotating the text about its center. To do this, we need to set context.textAlign = "center" and the context.textBaseline to bottom, otherwise, we trim off parts of our text.

Why resize the canvas? I usually have a canvas that isn't appended to the page. I use it to draw all of my rotated text, then I draw it onto another canvas which I display. For example, you can use this canvas to draw all of the labels for a chart (one by one) and draw the hidden canvas onto the chart canvas where you need the label (context.drawImage(hiddenCanvas, 0, 0);).

중요 사항 : 텍스트를 측정하기 전에 글꼴을 설정하고 캔버스 크기를 조정 한 후 모든 스타일을 컨텍스트에 다시 적용하십시오. 캔버스의 크기가 조정되면 캔버스의 컨텍스트가 완전히 재설정됩니다.

도움이 되었기를 바랍니다!

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var font, text, x, y;

text = "Mississippi";

//Set font size before measuring
font = 20;
ctx.font = font + 'px Arial, sans-serif';
//Get width of text
var metrics = ctx.measureText(text);
//Set canvas dimensions
c.width = font;//The height of the text. The text will be sideways.
c.height = metrics.width;//The measured width of the text
//After a canvas resize, the context is reset. Set the font size again
ctx.font = font + 'px Arial';
//Set the drawing coordinates
x = font/2;
y = metrics.width/2;
//Style
ctx.fillStyle = 'black';
ctx.textAlign = 'center';
ctx.textBaseline = "bottom";
//Rotate the canvas and draw the text
ctx.save();
ctx.translate(x, y);
ctx.rotate(-Math.PI / 2);
ctx.fillText(text, 0, font / 2);
ctx.restore();
<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;">

참고 URL : https://stackoverflow.com/questions/3167928/drawing-rotated-text-on-a-html5-canvas

반응형