Поверните «примечание» на холсте, чтобы всегда касаться верхнего левого угла - PullRequest
3 голосов
/ 05 апреля 2011

Последний код, который работал для меня, был:

    <canvas id="bg-admin-canvas" width="500" height="500" style="margin:15px; background:#09F;"></canvas>
    <script>
        var postit = function(width,height,angle){
            var canvas = document.getElementById("bg-admin-canvas");
            var ctx = canvas.getContext("2d");

            var radians = angle * Math.PI / 180;                
            var move = width*Math.sin(radians);
            if(angle < 0 ){ ctx.translate(0,-move); }else{ ctx.translate(move,0); }
            ctx.rotate(radians);

            var gradient = ctx.createLinearGradient(0,height,width/2,height/2);
            gradient.addColorStop(0.05,"rgba(0,0,0,0)");
            gradient.addColorStop(0.5,"rgba(0,0,0,0.3)");
            ctx.fillStyle = gradient;
            ctx.fillRect(0,0,width,height);

            ctx.beginPath();
            ctx.moveTo(0,0);
            ctx.lineTo(width, 0);
            ctx.lineTo(width,height);
            ctx.lineTo(width-width*.8,height-height*.02);
            ctx.quadraticCurveTo(0+width*.02,height-height*.02,0+width*.02,(height - height*.2));
            ctx.closePath();
            var gradient = ctx.createLinearGradient(0,height,width/2,height/2);
            gradient.addColorStop(0,'#f7f8b9');
            gradient.addColorStop(1,'#feffcf');
            ctx.fillStyle = gradient;
            ctx.fill();

            ctx.beginPath();
            ctx.moveTo(width-width*.8,height-height*.02);
            ctx.quadraticCurveTo(0+width*.02,height-height*.02,0+width*.02,(height - height*.2));
            ctx.quadraticCurveTo(width*.05,height-height*.05,width*.1,height-height*.1);
            ctx.quadraticCurveTo(width*.1,height-height*.07,width-width*.8,height-height*.02);
            ctx.closePath();
            ctx.fillStyle = '#ffffff';
            ctx.fill();
            var gradient = ctx.createLinearGradient(0,height,width*.1,height-height*.1);
            gradient.addColorStop(0,"rgba(222,222,163,0.8)");
            gradient.addColorStop(1,'#feffcf');
            ctx.fillStyle = gradient;
            ctx.fill();

        }
        postit(300, 300, 10);
    </script>

Привет,

Я сделал быструю и грязную заметку "после нее" с помощью холста html5 и некоторых js.

Я хочу иметь возможность вращать их в любом случае, поэтому я попытался использовать перевод.В приведенном ниже примере у меня есть перевод 0,250, чтобы вы могли увидеть все целиком.

В идеале, я знаю, если бы мой холст был 300,300, тогда я бы ctx.translate (150,150);ctx.rotate (-30);ctx.translate (-150, -150);

Конечно, поскольку я вращаю квадрат, он обрезается.

Как мне повернуть квадрат и переместить его на холст так,все это показывается, но в самом верхнем левом краю холста?

Я добавил изображение, думая о том, чтобы просто получить высоту треугольника и переместить его так сильно, но при переводе это не так.Похоже, что это работает правильно.

Я вставлю всю свою функцию, чтобы вы могли посмотреть на нее, но если у вас есть какие-либо идеи, я был бы признателен.Это не важно, просто возиться сегодня.

var postit = function(width,height,angle){
            var canvas = jQuery("#bg-admin-canvas").get(0);
            var ctx = canvas.getContext("2d");

            /*var area = (width*width*Math.sin(angle))/2;
            var h = (area*2) / width + 30;
            ctx.translate(0,h);
            */
            //ctx.translate(150,150);
            ctx.translate(0,250);
            ctx.rotate(angle*Math.PI / 180);
            //ctx.translate(-150,-150);

            var gradient = ctx.createLinearGradient(0,height,width/2,height/2);
            gradient.addColorStop(0.05,"rgba(0,0,0,0)");
            gradient.addColorStop(0.5,"rgba(0,0,0,0.3)");
            ctx.fillStyle = gradient;
            ctx.fillRect(0,0,width,height);

            ctx.beginPath();
            ctx.moveTo(0,0);
            ctx.lineTo(width, 0);
            ctx.lineTo(width,height);
            ctx.lineTo(width-width*.8,height-height*.02);
            ctx.quadraticCurveTo(0+width*.02,height-height*.02,0+width*.02,(height - height*.2));
            ctx.closePath();
            var gradient = ctx.createLinearGradient(0,height,width/2,height/2);
            gradient.addColorStop(0,'#f7f8b9');
            gradient.addColorStop(1,'#feffcf');
            ctx.fillStyle = gradient;
            ctx.fill();

            ctx.beginPath();
            ctx.moveTo(width-width*.8,height-height*.02);
            ctx.quadraticCurveTo(0+width*.02,height-height*.02,0+width*.02,(height - height*.2));
            ctx.quadraticCurveTo(width*.05,height-height*.05,width*.1,height-height*.1);
            ctx.quadraticCurveTo(width*.1,height-height*.07,width-width*.8,height-height*.02);
            ctx.closePath();
            ctx.fillStyle = '#ffffff';
            ctx.fill();
            var gradient = ctx.createLinearGradient(0,height,width*.1,height-height*.1);
            gradient.addColorStop(0,"rgba(222,222,163,0.8)");
            gradient.addColorStop(1,'#feffcf');
            ctx.fillStyle = gradient;
            ctx.fill();
        }
        postit(300, 300, -35);

Postit from HTML5 Canvas


ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ

Лягушка, я думаю, ты знаешь, кто япытаюсь сделать.На этом изображении показано, что я хочу сделать: enter image description here Теперь единственное, что я хочу, - иметь возможность передавать любую ширину, высоту и угол и выполнять настройку на лету.

В качестве примерасо следующим кодом:

var canvas = document.getElementById("bg-admin-canvas");
var ctx = canvas.getContext("2d");
ctx.arc(0,0,3,0,360,true); ctx.fill();
ctx.translate(50, 50);
ctx.arc(0,0,3,0,360,true); ctx.fill();
ctx.translate(-25, -25);
ctx.arc(0,0,3,0,360,true); ctx.fill();

Я получаю следующее изображение: enter image description here Теперь, если я добавлю вращение, вот так:

var canvas = document.getElementById("bg-admin-canvas");
var ctx = canvas.getContext("2d");
ctx.arc(0,0,3,0,360,true); ctx.fill();
ctx.translate(50, 50);
ctx.arc(0,0,3,0,360,true); ctx.fill();
ctx.rotate(30*Math.PI/180);
ctx.translate(-25, -25);
ctx.arc(0,0,3,0,360,true); ctx.fill();

Теперь у меня есть наклонные координатыв результате получается: enter image description here

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

Итак, с этой повернутой структурой координат я не могу понятькак переместить мой квадрат (который может быть любого размера и повернут под любым углом) назад влево и вверх (чтобы он помещался как можно меньше места)

Имеет ли это смысл?

Ответы [ 2 ]

4 голосов
/ 05 апреля 2011

Короче говоря:

  • Переведите контекст в направлении Y только, чтобы поместить угол, где он должен быть.
  • Поверните контекст вокруг этой точки смещения.
  • Нарисуйте свой объект в 0,0.

Вот интерактивный, рабочий пример, который вы можете увидеть онлайн здесь:
http://phrogz.net/tmp/canvas_rotate_square_in_corner.html

<!DOCTYPE HTML> 
<html lang="en"><head> 
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 
  <title>HTML5 Canvas Rotate Square in Corner</title> 
  <style type="text/css" media="screen"> 
    body { background:#eee; margin:2em; text-align:center }
    canvas { display:block; margin:auto; background:#fff; border:1px solid #ccc }
  </style> 
</head><body> 
<canvas width="250" height="200"></canvas>
<script type="text/javascript" charset="utf-8"> 
  var can = document.getElementsByTagName('canvas')[0];
  var ctx = can.getContext('2d');
  ctx.strokeStyle = '#600'; ctx.lineWidth = 2; ctx.lineJoin = 'round';
  ctx.fillStyle = '#ff0'
  document.body.onmousemove = function(evt){
    var w=140, h=120;
    var angle = evt ? (evt.pageX - can.offsetLeft)/100 : 0;
    angle = Math.max(Math.min(Math.PI/2,angle),0);
    ctx.clearRect(0,0,can.width,can.height); ctx.beginPath();
    ctx.save();
    ctx.translate(1,w*Math.sin(angle)+1);
    ctx.rotate(-angle);
    ctx.fillRect(0,0,w,h);
    ctx.strokeRect(0,0,w,h);
    ctx.restore();
  };
  document.body.onmousemove();
</script> 
</body></html>

Анализ

Diagram showing a rectangle rotated counter-clockwise, with corner A on the Y axis at 0,12 and corner B on the X axis at 20,0; construction D is at 20,12, and the angle DAB is labeled with a lowercase 'a'

На приведенной выше диаграмме точка A - это верхний левый угол нашей заметки, а точка B - этоверхний правый угол.Мы повернули post-it note -a радианы от нормального угла (вращения по часовой стрелке положительные, против часовой стрелки отрицательные).

Мы видим, что точка A остается на оси y при вращении пост-it, поэтому нам нужно только вычислить, как далеко вниз по оси y , чтобы переместить его.Это расстояние выражено на диаграмме как BD .Из тригонометрии мы знаем, что
sin (a) = BD / AB

Изменение этой формулы дает нам
BD = ** AB *** sin (a)

Мы знаем, что AB - ширина нашей заметки после публикации.Несколько деталей:

  1. Поскольку наш угол будет выражаться как отрицательное число, а sin отрицательного числа дает отрицательный результат, а потому что мы хотимположительный результат, мы должны либо отменить результат
    BD = - AB *** sin (-a)
    , либо просто «обмануть» и использоватьположительный угол:
    ** BD = ** AB *** sin (a)

  2. Нам нужно помнить, чтобы перевести наш контекст до мы вращаем его, поэтому сначала мы перемещаемся непосредственно вниз по оси, чтобы установить свое начало в правильном месте.

  3. Помните, что при вращении в HTML5 Canvas используются радианы (неград).Если вы хотите повернуть на 20 градусов, вам нужно преобразовать его в радианы, умножив на Math.PI/180:

    ctx.rotate( 20*Math.PI/180 );

Это также относится к команде arc;ты должен делать ctx.arc(x,y,r,0,Math.PI*2,false);за полный круг.

2 голосов
/ 05 апреля 2011

Вы должны создать свой элемент canvas, а затем повернуть его с помощью CSS. Это сохранит ваш холст в целости и будет вращать только сам элемент.

Вот несколько примеров правил CSS:

-webkit-transform: rotate(-30deg); 
-moz-transform: rotate(-30deg);

См. http://snook.ca/archives/html_and_css/css-text-rotation

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...