Как нарисовать фигуру, а затем объявить ее переменной? - PullRequest
0 голосов
/ 16 января 2020
<!DOCTYPE html>
<html>
<body>

<canvas id="myCanvas" width="350" height="300"
style="border:6px solid black;">
</canvas>

<script>
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");

ctx.strokeStyle = 'gold';
ctx.strokeRect(20, 10, 160, 100);
</script>

</body>
</html>

Теперь я хочу go вперед и повернуть этот нарисованный прямоугольник:

ctx.strokeStyle = 'gold';
ctx.strokeRect(20, 10, 160, 100);

В переменную, которую я могу просто назвать "Прямоугольник", я могу легко изменить и вызвать его на протяжении всего моего проекта. Как я могу это сделать? спасибо!

Ответы [ 2 ]

1 голос
/ 17 января 2020

Вы можете использовать Path2D

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

Лучше всего создавать дополнительные пути вокруг начала координат (0,0), чтобы их можно было легко перемещать, вращать и масштабировать. при необходимости.

Пример создания нескольких путей с различным содержимым

function createRect() {
    const path = new Path2D();
    path.rect(-70, -45, 140, 90);  // add the sub path;
    return path;
}
function createCircle() {
    const path = new Path2D();
    path.arc(0, 0, 50, 0, Math.PI * 2);  // add the sub path;
    return path;
}
function createRandLines() {
    const path = new Path2D();
    var i = 10;
    while(i--) {
        path.moveTo(Math.random() * 20 - 10, Math.random() * 20 - 10);
        path.lineTo(Math.random() * 20 - 10, Math.random() * 20 - 10);
    }
    return path;
}

Чтобы создать пути

const myCircle = createCircle();
const myRect = createCircle();
const myLines1 = createRandLines();
const myLines2 = createRandLines();

Затем можно отобразить любой из путей с помощью одной функции .

function strokePath(path, x, y, lineWidth = ctx.lineWidth, color = ctx.strokeStyle) { // defaults to current style
    ctx.setTransform(1, 0, 0, 1, x, y);  // position the path so its (0,0) origin is at x,y
    ctx.lineWidth = lineWidth;
    ctx.strokeStyle = color;
    ctx.stroke(path);
}

Передача стиля положения и ширины линии для рисования пути.

const W = ctx.canvas.width;
const H = ctx.canvas.height;
strokePath(myCircle, Math.random() * W, Math.random() * H); 
strokePath(myRect, Math.random() * W, Math.random() * H);   
strokePath(myLines1, Math.random() * W, Math.random() * H); 
strokePath(myLines2, Math.random() * W, Math.random() * H); 

Пример

Более подробная функция рисования и некоторая организация в отношении функции создания пути.

В примере создается 4 пути один раз, а затем выполняется многократное использование aws их: случайное расположение, вращение, масштабирование, альфа-затухание, цвет и заполнение.

const W = canvas.width;
const H = canvas.height;
const ctx = canvas.getContext("2d");
ctx.lineCap = ctx.lineJoin = "round";
// Some math utils
Math.TAU = Math.PI * 2;
Math.rand = (m = 0, M = 1) => Math.random() * (M - m) + m;
Math.randItem = array => array[Math.random() * array.length | 0];

const FACE = [[-3,-38,-34,-32,-47,-16,-48,15,-36,34,-5,43,32,38,47,12,47,-21,25,-35],[-31,-19,-42,-6,-32,1,-9,-6,-6,-24],[5,-24,3,-6,29,2,40,-5,33,-19],[-30,15,-14,32,12,31,29,15,15,15,-2,23,-17,16],[-28,-14,-29,-6,-18,-9,-17,-15],[11,-17,12,-8,20,-6,22,-13,18,-16],[2,-39,0,-53,-9,-60],[-14,17,-16,26,-7,28,-5,22],[2,21,1,28,11,27,13,16]];

// Object to hold path types
const paths = {
  rect() {
    const path = new Path2D();
    path.rect(-20, -10, 40, 20); // add the sub path;
    return path;
  },
  ellipse() {
    const path = new Path2D();
    path.ellipse(0, 0, 20, 10, 0, 0, Math.TAU); // add the sub path;
    return path;
  },
  randLines() {
    const path = new Path2D();
    var i = 10;
    while (i--) {
      path.moveTo(Math.rand(-20, 20), Math.rand(-20, 20));
      path.lineTo(Math.rand(-20, 20), Math.rand(-20, 20));
    }
    return path;
  },
  face() {
    const path = new Path2D();
    FACE .forEach(sub => { // each sub path
      let i = 0;
      path.moveTo(sub[i++] / 3, sub[i++] / 3);
      while (i < sub.length) { path.lineTo(sub[i++] / 3, sub[i++] / 3) }
      path.closePath();
    });
    return path;
  }
};

// Function to draw scaled, rotated, faded, linewidth, colored path		
function strokePath(path, x, y, scale, rotate, alpha, lineWidth, color, fillColor) { 
  ctx.lineWidth = lineWidth * (1 / scale);  //Scale line width  by inverse scale to ensure the pixel size is constant
  ctx.setTransform(scale, 0, 0, scale, x, y); // position the path so its (0,0) origin is at x,y
  ctx.rotate(rotate);
  if (fillColor) {
    ctx.globalAlpha = 1;
    ctx.fillStyle = fillColor;
    ctx.fill(path, "evenodd");
  }
  ctx.globalAlpha = alpha;
  ctx.strokeStyle = color;
  ctx.stroke(path);
}

// create some paths and colors
const pathArray = [paths.ellipse(), paths.rect(), paths.randLines(), paths.face()];
const colors = "#F00,#FA0,#0B0,#0AF,#00F,#F0A,#000,#888".split(",");

drawRandomPath();

function drawRandomPath() {
  strokePath(
    Math.randItem(pathArray),         // random path
    Math.rand(0, W), Math.rand(0, H), // random pos
    Math.rand(0.25, 1),               // random scale
    Math.rand(0, Math.TAU),           // random rotate
    Math.rand(0.5, 1),                // random alpha
    1,                                // constant lineWidth
    Math.randItem(colors),            // random color
    Math.rand() < 0.2 ? "#EED" : undefined, // Fill 1 in 5 with white
  );
  setTimeout(drawRandomPath, 250); // draw another path every quarter second.
}
* {margin:0px}
canvas {border:1px solid}
<canvas id="canvas" width="600" height="190"></canvas>
1 голос
/ 16 января 2020

Вы не можете сделать это с текущими стандартами, к сожалению, вам придется перерисовать фигуру, вы можете сделать что-то вроде:

var shape = x:10,y:20,width:20,height:40

очистить холст и перерисовать с созданной переменной:

shape.width = 100;
ctx.rect(shape.x,shape.y,shape.width,shape.height);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...