Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 13.06.2021, 11:23
Аспирант
Отправить личное сообщение для Olga27 Посмотреть профиль Найти все сообщения от Olga27
 
Регистрация: 10.06.2021
Сообщений: 49

Как закрасить грань трехмерного куба?
У меня есть код с 3d объектами которые перемещаются в пространстве, с помощью TweenMax, мне нужно сделать заливку поверхностей, но не получается. Я убрала часть граней и оставила только квадрат (чтобы посмотреть как работает заливка), для этого я просто ограничила цикл с 12 до 4. Заливка не работает. Я решила попробовать просто начертить квадрат (moveTo и lineTo) и применить на нем заливку в этом случае работает, а когда пытаешься применить графику на 3d объекте сгенерированном в цикле то заливка не работает. В чем может быть проблема?
<!DOCTYPE HTML>
<html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>Tween</title>
    <script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
      <script src='./TweenMax.min.js'></script>
<style>
body {
  margin: 0;
  overflow: hidden;
}
canvas {
  width:100vw;
  height:100vh;
}
</style>
</head>
    <body>
<canvas id="scene"></canvas>
<script>
console.clear();
 
// Get the canvas element from the DOM
const canvas = document.querySelector('#scene');
canvas.width = canvas.clientWidth;
canvas.height = canvas.clientHeight;
// Store the 2D context
const ctx = canvas.getContext('2d');
 
if (window.devicePixelRatio > 1) {
  canvas.width = canvas.clientWidth * 2;
  canvas.height = canvas.clientHeight * 2;
  ctx.scale(2, 2);
}
 
/* ====================== */
/* ====== VARIABLES ===== */
/* ====================== */
let width = canvas.clientWidth; // Width of the canvas
let height = canvas.clientHeight; // Height of the canvas
const dots = []; // Every dots in an array
 
/* ====================== */
/* ====== CONSTANTS ===== */
/* ====================== */
/* Some of those constants may change if the user resizes their screen but I still strongly believe they belong to the Constants part of the variables */
const DOTS_AMOUNT = 1000; // Amount of dots on the screen
const DOT_RADIUS = 2; // Radius of the dots
let PROJECTION_CENTER_X = width / 2; // X center of the canvas HTML
let PROJECTION_CENTER_Y = height / 2; // Y center of the canvas HTML
let FIELD_OF_VIEW = width * 0.8;
const CUBE_LINES = [[0, 1], [1, 3], [3, 2], [2, 0], [2, 6], [3, 7], [0, 4], [1, 5], [6, 7], [6, 4], [7, 5], [4, 5]];
const CUBE_VERTICES = [[-1, -1, -1],[1, -1, -1],[-1, 1, -1],[1, 1, -1],[-1, -1, 1],[1, -1, 1],[-1, 1, 1],[1, 1, 1]];
 var test1 = [[-1, -1, -1],[1, -1, -1],[-1, 1, -1],[1, 1, -1],[-1, -1, 1],[1, -1, 1],[-1, 1, 1],[1, 1, 1]];
 var xPos = 140;
var yPos = 50;
 //{x:20,y:10,x:20,y:10,x:33,y:11,x:22,y:44,x:22,y:55,x:100,y:200};
 
class Cube {
  constructor(x, y, z) {
    this.x = (Math.random() - 0.5) * width;
    this.y = (Math.random() - 0.5) * width;
    this.z = (Math.random() - 0.5) * width;
    this.radius = Math.floor(Math.random() * 12 +  10);
    
    //TweenMax.to(this, Math.random() * 20 + 15, {
    //  x: (Math.random() - 0.5) * (width * 0.5),
    //  y: (Math.random() - 0.5) * (width * 0.5),
    //  z: (Math.random() - 0.5) * width,
    //  repeat: -1,
    //  yoyo: true,
    //  ease: Power2.EaseOut,
    //  delay: Math.random() * -35
    //});
  }
  // Do some math to project the 3D position into the 2D canvas
  project(x, y, z) {
    const sizeProjection = FIELD_OF_VIEW / (FIELD_OF_VIEW + z);
    const xProject = (x * sizeProjection) + PROJECTION_CENTER_X;
    const yProject = (y * sizeProjection) + PROJECTION_CENTER_Y;
    return {
      size: sizeProjection,
      x: xProject,
      y: yProject
    }
  }
  
 
  // Draw the dot on the canvas
  draw() {
    // Do not render a cube that is in front of the camera
    if (this.z < -FIELD_OF_VIEW + this.radius) {
      return;
    }
    //CUBE_LINES.length
    for (let i = 0; i < 4; i++) {
      const v1 = {
        x: this.x + (this.radius * CUBE_VERTICES[CUBE_LINES[i][0]][0]),
        y: this.y + (this.radius * CUBE_VERTICES[CUBE_LINES[i][0]][1]),
        z: this.z + (this.radius * CUBE_VERTICES[CUBE_LINES[i][0]][2])
      };
      const v2 = {
        x: this.x + (this.radius * CUBE_VERTICES[CUBE_LINES[i][1]][0]),
        y: this.y + (this.radius * CUBE_VERTICES[CUBE_LINES[i][1]][1]),
        z: this.z + (this.radius * CUBE_VERTICES[CUBE_LINES[i][1]][2])
      };
      const v1Project = this.project(v1.x, v1.y, v1.z);
      const v2Project = this.project(v2.x, v2.y, v2.z);
      
      
     // ctx.beginPath();
     // ctx.lineWidth = 2;
     // ctx.moveTo(v1Project.x, v1Project.y);
      //ctx.lineTo(v2Project.x, v2Project.y);
     // ctx.fillStyle = "#cc6666";
  //console.log(test1[i][1][0]);
      
    //  ctx.stroke();
      
    //  ctx.fill();
     // console.log(CUBE_LINES.length);
     // console.log(test1.x);
    //  ctx.save();
    //  ctx.lineWidth = 2;
    //  ctx.fillStyle = ctx.strokeStyle = "#cc6666";
    //  ctx.beginPath();
   ///   ctx.moveTo(v1Project.x, v1Project.y);
    //  ctx.lineTo(v2Project.x, v2Project.y);
      //ctx.closePath();
      
    //   ctx.stroke();
     //  ctx.fill();
     //  ctx.restore();
     
      ctx.beginPath();
      ctx.fillStyle = ctx.strokeStyle = "#6666cc";
      //utils.colorToRGB(this.color, this.alpha);
      //*************************************
      //Не работает заливка
       //*************************************
      ctx.moveTo(v1Project.x,v1Project.y);
      ctx.lineTo(v2Project.x,v2Project.y);
       //*************************************
      //Работает заливка
       //*************************************
       ctx.moveTo(xPos,50+yPos);
      ctx.lineTo(xPos+50,50+yPos);
      ctx.lineTo(xPos+50,100+yPos);
      ctx.lineTo(xPos,100+yPos);
      ctx.lineTo(xPos,50+yPos);
       ctx.fill();
      ctx.stroke(); 
     
    
    }
    
    // ctx.globalAlpha = Math.abs(this.z / (width * 0.5));
  }
}
 
function createDots() {
  // Empty the array of dots
  dots.length = 0;
  
  // Create a new dot based on the amount needed
  for (let i = 0; i < 100; i++) {
    dots.push(new Cube());
  }
}
 
/* ====================== */
/* ======== RENDER ====== */
/* ====================== */
function render() {
  // Clear the scene
  ctx.clearRect(0, 0, width, height);
  
  // Loop through the dots array and draw every dot
  for (var i = 0; i < dots.length; i++) {
    dots[i].draw();
  }
  
  window.requestAnimationFrame(render);
}
 
 
// Function called after the user resized its screen
function afterResize () {
  width = canvas.offsetWidth;
  height = canvas.offsetHeight;
  if (window.devicePixelRatio > 1) {
    canvas.width = canvas.clientWidth * 2;
    canvas.height = canvas.clientHeight * 2;
    ctx.scale(2, 2);
  } else {
    canvas.width = width;
    canvas.height = height;
  }
  PROJECTION_CENTER_X = width / 2;
  PROJECTION_CENTER_Y = height / 2;
  FIELD_OF_VIEW = width * 0.8;
  
  createDots(); // Reset all dots
}
 
// Variable used to store a timeout when user resized its screen
let resizeTimeout;
// Function called right after user resized its screen
function onResize () {
  // Clear the timeout variable
  resizeTimeout = window.clearTimeout(resizeTimeout);
  // Store a new timeout to avoid calling afterResize for every resize event
  resizeTimeout = window.setTimeout(afterResize, 500);
}
window.addEventListener('resize', onResize);
 
// Populate the dots array with random dots
createDots();
 
// Render the scene
window.requestAnimationFrame(render);
 
</script>  
</body>
</html>
Ответить с цитированием
  #2 (permalink)  
Старый 13.06.2021, 12:10
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,069

Olga27,
строка 144
if(!i) {
         let h = -(v1Project.x - v2Project.x);
         ctx.fillRect(v1Project.x,v1Project.y, h, h)
      }
Ответить с цитированием
  #3 (permalink)  
Старый 13.06.2021, 12:59
Аватар для MallSerg
Профессор
Отправить личное сообщение для MallSerg Посмотреть профиль Найти все сообщения от MallSerg
 
Регистрация: 07.03.2011
Сообщений: 1,127

>> Заливка не работает.
Заливка работает но не так как ты ожидаешь.
Заливка применяется между всеми вершинами которые образует последовательный вызов ctx.lineTo( .... )
Вызов ctx.moveTo ( .... ) разрывает группу вершин между которыми применяется заливка.
Т.е. в твоем случае когда после каждого вызова ctx.lineTo вызывается ctx.moveTo заливка применяется только под нарисованной линией и ее совсем не видно.

Отрисовка ну очень не оптимальна на каждом шаге анимации функция draw() вызывается в цикле внутри этой функции то же цикл в котором вызывается ctx.beginPath();
Ответить с цитированием
  #4 (permalink)  
Старый 13.06.2021, 13:07
Аспирант
Отправить личное сообщение для Olga27 Посмотреть профиль Найти все сообщения от Olga27
 
Регистрация: 10.06.2021
Сообщений: 49

рони, работает заливка, теперь я изменила цикл и увеличила до 12, чтобы все плоскости куба отображались, также я вернула tweenmax для перемещения по холсту. Как теперь остальным граням присвоить другие цвета? т.е. задняя плоскость не видна, остается еще четыре top, left,right и bottom, которые постепенно отображаются в зависимости перемещения объекта.
<!DOCTYPE HTML>
<html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>Tween</title>
    <script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
      <script src='https://cdnjs.cloudflare.com/ajax/libs/gsap/1.14.2/TweenMax.min.js'></script>
<style>
body {
  margin: 0;
  overflow: hidden;
}
canvas {
  width:100vw;
  height:100vh;
}
</style>
</head>
    <body>
<canvas id="scene"></canvas>
<script>
console.clear();
 
// Get the canvas element from the DOM
const canvas = document.querySelector('#scene');
canvas.width = canvas.clientWidth;
canvas.height = canvas.clientHeight;
// Store the 2D context
const ctx = canvas.getContext('2d');
 
if (window.devicePixelRatio > 1) {
  canvas.width = canvas.clientWidth * 2;
  canvas.height = canvas.clientHeight * 2;
  ctx.scale(2, 2);
}
 
/* ====================== */
/* ====== VARIABLES ===== */
/* ====================== */
let width = canvas.clientWidth; // Width of the canvas
let height = canvas.clientHeight; // Height of the canvas
const dots = []; // Every dots in an array
 
/* ====================== */
/* ====== CONSTANTS ===== */
/* ====================== */
/* Some of those constants may change if the user resizes their screen but I still strongly believe they belong to the Constants part of the variables */
const DOTS_AMOUNT = 1000; // Amount of dots on the screen
const DOT_RADIUS = 2; // Radius of the dots
let PROJECTION_CENTER_X = width / 2; // X center of the canvas HTML
let PROJECTION_CENTER_Y = height / 2; // Y center of the canvas HTML
let FIELD_OF_VIEW = width * 0.8;
const CUBE_LINES = [[0, 1], [1, 3], [3, 2], [2, 0], [2, 6], [3, 7], [0, 4], [1, 5], [6, 7], [6, 4], [7, 5], [4, 5]];
const CUBE_VERTICES = [[-1, -1, -1],[1, -1, -1],[-1, 1, -1],[1, 1, -1],[-1, -1, 1],[1, -1, 1],[-1, 1, 1],[1, 1, 1]];
 var test1 = [[-1, -1, -1],[1, -1, -1],[-1, 1, -1],[1, 1, -1],[-1, -1, 1],[1, -1, 1],[-1, 1, 1],[1, 1, 1]];
 var xPos = 140;
var yPos = 50;
 //{x:20,y:10,x:20,y:10,x:33,y:11,x:22,y:44,x:22,y:55,x:100,y:200};
 
class Cube {
  constructor(x, y, z) {
    this.x = (Math.random() - 0.5) * width;
    this.y = (Math.random() - 0.5) * width;
    this.z = (Math.random() - 0.5) * width;
    this.radius = Math.floor(Math.random() * 12 +  10);
    
    TweenMax.to(this, Math.random() * 20 + 15, {
      x: (Math.random() - 0.5) * (width * 0.5),
      y: (Math.random() - 0.5) * (width * 0.5),
      z: (Math.random() - 0.5) * width,
      repeat: -1,
      yoyo: true,
      ease: Power2.EaseOut,
      delay: Math.random() * -35
    });
  }
  // Do some math to project the 3D position into the 2D canvas
  project(x, y, z) {
    const sizeProjection = FIELD_OF_VIEW / (FIELD_OF_VIEW + z);
    const xProject = (x * sizeProjection) + PROJECTION_CENTER_X;
    const yProject = (y * sizeProjection) + PROJECTION_CENTER_Y;
    return {
      size: sizeProjection,
      x: xProject,
      y: yProject
    }
  }
  
 
  // Draw the dot on the canvas
  draw() {
    // Do not render a cube that is in front of the camera
    if (this.z < -FIELD_OF_VIEW + this.radius) {
      return;
    }
    //CUBE_LINES.length
    for (let i = 0; i < 12; i++) {
      const v1 = {
        x: this.x + (this.radius * CUBE_VERTICES[CUBE_LINES[i][0]][0]),
        y: this.y + (this.radius * CUBE_VERTICES[CUBE_LINES[i][0]][1]),
        z: this.z + (this.radius * CUBE_VERTICES[CUBE_LINES[i][0]][2])
      };
      const v2 = {
        x: this.x + (this.radius * CUBE_VERTICES[CUBE_LINES[i][1]][0]),
        y: this.y + (this.radius * CUBE_VERTICES[CUBE_LINES[i][1]][1]),
        z: this.z + (this.radius * CUBE_VERTICES[CUBE_LINES[i][1]][2])
      };
      const v1Project = this.project(v1.x, v1.y, v1.z);
      const v2Project = this.project(v2.x, v2.y, v2.z);
      
      
     // ctx.beginPath();
     // ctx.lineWidth = 2;
     // ctx.moveTo(v1Project.x, v1Project.y);
      //ctx.lineTo(v2Project.x, v2Project.y);
     // ctx.fillStyle = "#cc6666";
  //console.log(test1[i][1][0]);
      
    //  ctx.stroke();
      
    //  ctx.fill();
     // console.log(CUBE_LINES.length);
     // console.log(test1.x);
    //  ctx.save();
    //  ctx.lineWidth = 2;
    //  ctx.fillStyle = ctx.strokeStyle = "#cc6666";
    //  ctx.beginPath();
   ///   ctx.moveTo(v1Project.x, v1Project.y);
    //  ctx.lineTo(v2Project.x, v2Project.y);
      //ctx.closePath();
      
    //   ctx.stroke();
     //  ctx.fill();
     //  ctx.restore();
     
      ctx.beginPath();
      ctx.fillStyle = ctx.strokeStyle = "#6666cc";
      //utils.colorToRGB(this.color, this.alpha);
      //*************************************
      //Не работает заливка
       //*************************************
      ctx.moveTo(v1Project.x,v1Project.y);
      ctx.lineTo(v2Project.x,v2Project.y);
      if(!i) {
         let h = -(v1Project.x - v2Project.x);
         ctx.fillRect(v1Project.x,v1Project.y, h, h)
      }

      ctx.stroke(); 
     
    
    }
    
    // ctx.globalAlpha = Math.abs(this.z / (width * 0.5));
  }
}
 
function createDots() {
  // Empty the array of dots
  dots.length = 0;
  
  // Create a new dot based on the amount needed
  for (let i = 0; i < 100; i++) {
    dots.push(new Cube());
  }
}
 
/* ====================== */
/* ======== RENDER ====== */
/* ====================== */
function render() {
  // Clear the scene
  ctx.clearRect(0, 0, width, height);
  
  // Loop through the dots array and draw every dot
  for (var i = 0; i < dots.length; i++) {
    dots[i].draw();
  }
  
  window.requestAnimationFrame(render);
}
 
 
// Function called after the user resized its screen
function afterResize () {
  width = canvas.offsetWidth;
  height = canvas.offsetHeight;
  if (window.devicePixelRatio > 1) {
    canvas.width = canvas.clientWidth * 2;
    canvas.height = canvas.clientHeight * 2;
    ctx.scale(2, 2);
  } else {
    canvas.width = width;
    canvas.height = height;
  }
  PROJECTION_CENTER_X = width / 2;
  PROJECTION_CENTER_Y = height / 2;
  FIELD_OF_VIEW = width * 0.8;
  
  createDots(); // Reset all dots
}
 
// Variable used to store a timeout when user resized its screen
let resizeTimeout;
// Function called right after user resized its screen
function onResize () {
  // Clear the timeout variable
  resizeTimeout = window.clearTimeout(resizeTimeout);
  // Store a new timeout to avoid calling afterResize for every resize event
  resizeTimeout = window.setTimeout(afterResize, 500);
}
window.addEventListener('resize', onResize);
 
// Populate the dots array with random dots
createDots();
 
// Render the scene
window.requestAnimationFrame(render);
 
</script>  
</body>
</html>

Последний раз редактировалось Olga27, 13.06.2021 в 13:12.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Открытие div блока при первом визите на сайт Nushaba Общие вопросы Javascript 28 20.12.2013 21:24
Решение проблемы кодировок для AJAX и PHP без iconv (cp1251 в AJAX) Serge Ageyev AJAX и COMET 10 24.04.2013 20:48
Как организовать RichEdit arma Элементы интерфейса 2 18.02.2010 14:57
О наследовании событий, или как корректно его отменить. JCShen Events/DOM/Window 8 09.02.2010 00:00
Как правильно послать XML в POST запросе LowCoder AJAX и COMET 10 15.07.2009 23:20