let canvas = document.getElementById("canvas");

let context = canvas.getContext("2d");
// for canvas size
var window_width = window.innerWidth;
var window_height = window.innerHeight;

canvas.width = window_width;
canvas.height = window_height;



let hit_counter=0;
let speedinc=2;




// object is created using class
class Circle {
    constructor(xpos, ypos, radius, speed, color, text) {

        this.position_x = xpos;
        this.position_y = ypos;

        this.radius = radius;

        this.speed = speed;

        this.dx = 1 * this.speed;
        this.dy = 1 * this.speed;

        this.text = text;

        this.color = color;
    }

// creating circle
    draw(context) {
        context.beginPath();
        context.strokeStyle = this.color;



        context.fillText(this.text, this.position_x, this.position_y);


        context.textAlign = "center";
        context.textBaseline = "middle"
        context.font = "20px Arial";
        context.lineWidth = 5;
        context.arc(this.position_x, this.position_y, this.radius, 0, Math.PI * 2);
        context.stroke();
        context.closePath();
    }


    update() {



        this.text=hit_counter;




        context.clearRect(0,0,window_width,window_height)

        this.draw(context);

        if ( (this.position_x + this.radius) > window_width ) {
            this.dx = -this.dx;  
            hit_counter++;  
        }

        if ( (this.position_x - this.radius) < 0 ) {
            this.dx = -this.dx;
            hit_counter++;  
        }

        if ( (this.position_y - this.radius) < 0 ) {
            this.dy = -this.dy;
            hit_counter++;  
        }

        if ( (this.position_y + this.radius) > window_height ) {
            this.dy = -this.dy;
            hit_counter++;  


        }

        this.position_x += this.dx;
        this.position_y += this.dy; 


    }
}







let my_circle = new Circle(100, 100, 50, speedinc , 'Black', hit_counter);




let updateCircle = function() {
  requestAnimationFrame(updateCircle);
 my_circle.update();

}

updateCircle();
<select name="shapes">
        <option value="square">SQUARE</option>
        <option value="rectangle">RECTANGLE</option>
        <option value="triangle">TRIANGLE</option>

        </select>
<canvas id="canvas"></canvas>

JS Я хочу изменить форму объекта, движущегося с номером, например, прямоугольник, треугольник, квадрат. Я уже создал круг, я пытался создать другие фигуры НА ТОЙ ЖЕ СТРАНИЦЕ, но у меня это не сработало. КАК ЭТО СДЕЛАТЬ?

let canvas = document.getElementById("canvas");

let context = canvas.getContext("2d");
// for canvas size
var window_width = window.innerWidth;
var window_height = window.innerHeight;

canvas.width = window_width;
canvas.height = window_height;



let hit_counter=0;
let speedinc=2;




// object is created using class
class Circle {
    constructor(xpos, ypos, radius, speed, color, text) {

        this.position_x = xpos;
        this.position_y = ypos;

        this.radius = radius;

        this.speed = speed;

        this.dx = 1 * this.speed;
        this.dy = 1 * this.speed;

        this.text = text;

        this.color = color;
    }
   
// creating circle
    draw(context) {
        context.beginPath();
        context.strokeStyle = this.color;
        
        
       
        context.fillText(this.text, this.position_x, this.position_y);
        
        
        context.textAlign = "center";
        context.textBaseline = "middle"
        context.font = "20px Arial";
        context.lineWidth = 5;
        context.arc(this.position_x, this.position_y, this.radius, 0, Math.PI * 2);
        context.stroke();
        context.closePath();
    }

    
    update() {
        

        
        this.text=hit_counter;

        
         
       
        context.clearRect(0,0,window_width,window_height)

        this.draw(context);

        if ( (this.position_x + this.radius) > window_width ) {
            this.dx = -this.dx;  
            hit_counter++;  
        }
        
        if ( (this.position_x - this.radius) < 0 ) {
            this.dx = -this.dx;
            hit_counter++;  
        }

        if ( (this.position_y - this.radius) < 0 ) {
            this.dy = -this.dy;
            hit_counter++;  
        }

        if ( (this.position_y + this.radius) > window_height ) {
            this.dy = -this.dy;
            hit_counter++;  
            
           
        }

        this.position_x += this.dx;
        this.position_y += this.dy; 
        
     
    }
}



  



let my_circle = new Circle(100, 100, 50, speedinc , 'Black', hit_counter);




let updateCircle = function() {
  requestAnimationFrame(updateCircle);
 my_circle.update();
 
}

updateCircle();




//for color

function changeColor(event)
{
    var coloor = event.value;
    canvas.style.background =coloor;
    
 }

HTML Я хочу изменить форму объекта, движущегося с номером, например, прямоугольник, треугольник, квадрат. Я уже создал круг, я пытался создать другие фигуры НА ТОЙ ЖЕ СТРАНИЦЕ, но у меня это не сработало. КАК ЭТО СДЕЛАТЬ?

<select name="shapes">
        <option value="square">SQUARE</option>
        <option value="rectangle">RECTANGLE</option>
        <option value="triangle">TRIANGLE</option>
       
        </select>
<canvas id="canvas"></canvas>
1
tt pp 3 Фев 2022 в 20:36
С svg, а не с холстом
 – 
Mister Jojo
3 Фев 2022 в 20:39
Как это сделать с помощью svg??
 – 
tt pp
3 Фев 2022 в 20:48
Путем изменения значений пути, используя векторные переводы по точкам и значениям касательных
 – 
Mister Jojo
3 Фев 2022 в 20:51
 – 
Mister Jojo
3 Фев 2022 в 20:53
Добро пожаловать в Stack Overflow. Если вы хотите использовать Canvas, загляните на paperjs.org. примеры и могут быть действительно полезными.
 – 
Twisty
3 Фев 2022 в 21:09

2 ответа

Вот не так базовый пример , который использует Paper.js:

<script src="https://cdnjs.cloudflare.com/ajax/libs/paper.js/0.12.15/paper-full.min.js" integrity="sha512-ovjLI1ZcZe6bw+ImQ21r+sv8q/Vwob2kq7tFidK6E1LWfi0T4uobbmpfEU1//a9h9o5Kkt+MnMWf6rWlg0EiMw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script type="text/paperscript" canvas="myCanvas">
var defaults = {
    item: "circle",
    center: new Point(100, 100),
    size: 50,
    color: "black",
    width: 5,
    font: {
        family: "Arial",
        size: "20px",
        just: "center"
    },
    speed: 2
};

var hit_count = 0;

function makeItem(name, center, size) {
    var item;
    defaults.dx = 1 * defaults.speed;
    defaults.dy = 1 * defaults.speed;
    if(name == undefined){
        name = defaults.item;
    }
    if(center == undefined){
        center = defaults.center;
    }
    if(size == undefined){
        size = defaults.size;
    }
    switch(name){
        case "circle":
            item = new Path.Circle({
                center: center,
                radius: size,
            });
            break;
        case "rectangle":
            item = new Path.Rectangle({
                point: center,
                size: size
            });
            break;
        case "triangle":
            item = new Path.RegularPolygon({
                center: center,
                sides: 3,
                radius: size,
            });
            break;
    }
    item.strokeColor = defaults.color;
    item.strokeWidth = defaults.width;
    console.log("Making New Item", name, center, size);
    var text = new PointText(item.bounds.center);
    text.bounds.center = item.bounds.center;
    text.fillColor = defaults.color;
    text.content = hit_count;
    text.fontFamily = defaults.font.family;
    text.fontSize = defaults.font.size;
    text.justification = defaults.font.just;
    text.name = "hitCount";
    console.log("Adding Text", item.bounds.center);
    return new Group([item, text]);
}

function changeItem(name, center, size){
    if(center == undefined){
        center = myItem.bounds.center;
    }
    if(size == undefined){
        size = defaults.size;
    }
    if(name == "square"){
        name = "rectangle";
        size = [size * 2, size * 2];
    } else if(name == "rectangle"){
        size = [size * 3, size * 2];
    }
    project.activeLayer.removeChildren();
    console.log("Changing to " + name, center, size);
    return makeItem(name, center, size);
}

var myItem = makeItem();

function onFrame(event) {
    var destination = new Point(myItem.position.x + defaults.dx, myItem.position.y + defaults.dy);
    var vector = destination - myItem.position;
    myItem.position += vector;
    if(myItem.bounds.right >= view.size.width){
        defaults.dx = -defaults.dx;
        hit_count++;
    }
    if(myItem.bounds.left < 0){
        defaults.dx = -defaults.dx;
        hit_count++;
    }
    if(myItem.bounds.top < 0){
        defaults.dy = -defaults.dy;
        hit_count++;
    }
    if(myItem.bounds.bottom > view.size.height){
        defaults.dy = -defaults.dy;
        hit_count++;
    }
    
    myItem.children['hitCount'].content = hit_count;
}

document.getElementById("shapes").onchange = function(event){
  myItem = changeItem(this.value);
};
</script>

<div>
  <select id="shapes">
    <option value="circle">CIRCLE</option>
    <option value="square">SQUARE</option>
    <option value="rectangle">RECTANGLE</option>
    <option value="triangle">TRIANGLE</option>
  </select>
</div>
<div style="width: 480px;">
  <canvas id="myCanvas" width="640px" height="340px"></canvas>
</div>

Узнать больше:

0
Twisty 4 Фев 2022 в 03:05
Он не работает должным образом....Код работает неправильно..
 – 
tt pp
4 Фев 2022 в 08:41

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

На самом базовом уровне это может быть что-то вроде

const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
// we define all our "tracing" methods
// they all are completely position agnostic
// note how they have their "center" set to the coordinates (0, 0)
const trace = [
  () => ctx.arc(0, 0, 50, 0, Math.PI * 2), // circle
  () => {
    [[0, -35], [35, 25], [-35, 25]]
      .forEach(([x, y]) => ctx.lineTo(x, y));
    ctx.closePath();
  }, // triangle
  () => ctx.rect(-25, -25, 50, 50) // rect
];
let activeShape = Math.floor(Math.random() * trace.length);
ctx.font = "30px sans-serif";
ctx.textBaseline = "middle";
ctx.textAlign = "center";

setInterval(() => activeShape = Math.floor(Math.random() * trace.length), 1000);

document.onmousemove = ({ clientX, clientY }) => {
  const { left, top } = canvas.getBoundingClientRect();
  draw(clientX - left, clientY - top);
};

function draw(x, y) {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  // we move the drawing by changing the context's transform matrix
  ctx.translate(x, y);
  ctx.beginPath();
  // this is position agnostic
  trace[ activeShape ]();
  ctx.stroke();
  // this is also position agnostic
  ctx.fillText("A", 0, 0);
  // reset the transformation matrix for next frame
  ctx.setTransform(1, 0, 0, 1, 0, 0);
}
<canvas width="500" height="500"></canvas>

Теперь, благодаря API Path2D, мы можем даже просто сохранять объект пути:

const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
// we define all our "tracing" methods
// they all are completely position agnostic
const circle = new Path2D();
circle.arc(0, 0, 50, 0, Math.PI * 2);
const triangle = new Path2D("M0,-35 35,25 -35,25Z");
const rect = new Path2D();
rect.rect(-25, -25, 50, 50)
const shapes = [circle, triangle, rect];
let activeShape = Math.floor(Math.random() * shapes.length);
ctx.font = "30px sans-serif";
ctx.textBaseline = "middle";
ctx.textAlign = "center";

setInterval(() => activeShape = Math.floor(Math.random() * shapes.length), 1000);

document.onmousemove = ({ clientX, clientY }) => {
  const { left, top } = canvas.getBoundingClientRect();
  draw(clientX - left, clientY - top);
};

function draw(x, y) {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  // we move the drawing by changing the context's transform matrix
  ctx.translate(x, y);
  ctx.beginPath();
  ctx.stroke(shapes[ activeShape ]);
  // this is also position agnostic
  ctx.fillText("A", 0, 0);
  // reset the transformation matrix for next frame
  ctx.setTransform(1, 0, 0, 1, 0, 0);
}
<canvas width="500" height="500"></canvas>

С вашим кодом, который может дать что-то вроде:

const canvas = document.getElementById("canvas");

const context = canvas.getContext("2d");
// for canvas size
let window_width = window.innerWidth;
let window_height = window.innerHeight;

canvas.width = window_width;
canvas.height = window_height;

let hit_counter = 0;
let speedinc = 2;

// object is created using class
class Shape {
  #shapes
  constructor(xpos, ypos, radius, speed, color, text) {

    this.position_x = xpos;
    this.position_y = ypos;

    this.radius = radius;

    this.speed = speed;

    this.dx = 1 * this.speed;
    this.dy = 1 * this.speed;

    this.text = text;
    this.color = color;

    // store all the drawable shapes
    const circle = new Path2D();
    circle.arc(0, 0, radius, 0, Math.PI * 2);
    const hypot = Math.hypot(radius, radius);
    const triangle = new Path2D();
    triangle.lineTo(0, -hypot);
    triangle.lineTo(hypot, radius);
    triangle.lineTo(-hypot, radius);
    triangle.closePath();
    const square = new Path2D();
    square.rect(-radius, -radius, radius * 2, radius * 2);
    this.#shapes = { circle, triangle, square };
    this.activeShape = "square";
  }
  draw(context) {
    context.beginPath();
    context.strokeStyle = this.color;
    context.translate(this.position_x, this.position_y);
    // remember to set all the context properties
    // before they're used
    context.textAlign = "center";
    context.textBaseline = "middle"
    context.font = "20px Arial";
    context.fillText(this.text, 0, 0);
    context.lineWidth = 5;
    context.stroke(this.#shapes[this.activeShape]);
    context.setTransform(1, 0, 0, 1, 0, 0);
  }
  update() {
    this.text = hit_counter;
    context.clearRect(0, 0, window_width, window_height)
    this.draw(context);
    // doing the update here means we're drawing one frame late
    if ((this.position_x + this.radius) > window_width) {
      this.dx = -this.dx;
      hit_counter++;
    }

    if ((this.position_x - this.radius) < 0) {
      this.dx = -this.dx;
      hit_counter++;
    }

    if ((this.position_y - this.radius) < 0) {
      this.dy = -this.dy;
      hit_counter++;
    }

    if ((this.position_y + this.radius) > window_height) {
      this.dy = -this.dy;
      hit_counter++;
    }
    
    this.position_x += this.dx;
    this.position_y += this.dy;

  }
}
const my_shape = new Shape(100, 100, 50, speedinc, 'Black', hit_counter);

document.querySelector("select").addEventListener("change", (evt) => {
  my_shape.activeShape = evt.target.value;
});

const updateCircle = function() {
  requestAnimationFrame(updateCircle);
  my_shape.update();
}

updateCircle();
<select name="shapes">
  <option value="square">SQUARE</option>
  <option value="circle">CIRCLE</option>
  <option value="triangle">TRIANGLE</option>

</select>
<canvas id="canvas"></canvas>

Но, очевидно, есть много способов написать это по-разному.

0
Kaiido 4 Фев 2022 в 09:21