P5.JS-使用对象、其属性和函数,用预加载的图像填充形状



我正在尝试创建一个对象,并使其具有一个形状(椭圆(、一个图像和一个函数,该函数以某种方式用预加载的图像填充该形状。

我已经找到了这篇文章,但如果我想把它整理整齐并放在一个物体里,我就无法让它发挥作用。

需要明确的是,这就是它的样子:

let image;
let hypotheticalObject
function preload()
{
   image = loadImage('Assets/randomimage.jpeg');
}

function setup()
{
    hypotheticalObject = {
        objectImage: image,
        graphicsBuffer: createGraphics(100, 100),
        xPos: width / 2,
        yPos: height / 2,
        size: 50,
        colour: color(255, 255, 255),
        shape: function()
        {
            fill(this.colour),
            ellipse(this.xPos, this.yPos, this.size);
        },
        
        mask: function()
        {
            this.graphicsBuffer.shape();
        },
        render: function()
        {
            something something
        }
        
}
function draw()
{
    hypotheticalObject.render();
}

这就是我能走多远,因为我不知道如何继续。

您的代码有几个问题,即:

shape: function() {
  // ...
},
mask: function() {
  this.graphicsBuffer.shape();
},

您在hypotheticalObject上声明了shape(),但随后尝试在graphicsBuffer上调用它?javascript不是这样工作的。你可以这样做:

hypotheticalObject.graphicsBuffer.shape = function() {
  // When graphicsBuffer.shape() is called, the this keyword will be bound to graphicsBuffer
  // Unfortunately we need a to access members from hypotheticalObject as well, so that is inconvenient:
  this.fill(hypotheticalObject.colour),
  this.ellipse(hypotheticalObject.xPos, hypotheticalObject.yPos, hypotheticalObject.size);
}

然而,我也不认为这是最惯用的方法。这里有一个有效的解决方案,试图保持接近你的代码:

let img;
let hypotheticalObject;
function preload() {
  img = loadImage('https://www.paulwheeler.us/files/windows-95-desktop-background.jpg');
}
function setup() {
  createCanvas(windowWidth, windowHeight);
  
  hypotheticalObject = {
    objectImage: img,
    // The graphics you're using for the mask need to be the size of the image
    graphicsBuffer: createGraphics(img.width, img.height),
    xPos: width / 2,
    yPos: height / 2,
    size: 50,
    
    init: function() {
      this.maskedImage = createImage(this.objectImage.width, this.objectImage.height);
    },
    updateShape: function() {
      this.graphicsBuffer.clear();
      // The fill color is irrelevant so long as it is opaque
      this.graphicsBuffer.fill(0);
      // These drawing instructions need to happen on the p5.Graphics object
      this.graphicsBuffer.ellipse(this.xPos, this.yPos, this.size);
    },
    render: function() {
      this.updateShape();
      // When you call mask on an image it changes the image so we need to make a copy
      this.maskedImage.copy(
        this.objectImage,
        0, 0, this.objectImage.width, this.objectImage.height,
        0, 0, this.objectImage.width, this.objectImage.height
      );
      this.maskedImage.mask(this.graphicsBuffer);
      // Always draw the image at 0, 0 since the masked portion is already offset
      image(this.maskedImage, 0, 0);
    }
  }
  hypotheticalObject.init();
}
let xv = 2;
let yv = 2;
function draw() {
  background(255);
  
  hypotheticalObject.xPos += xv;
  hypotheticalObject.yPos += yv;
  
  if (hypotheticalObject.xPos > width) {
    hypotheticalObject.xPos = width;
    xv *= -1;
  } else if (hypotheticalObject.xPos < 0) {
    hypotheticalObject.xPos = 0;
    xv *= -1;
  }
  if (hypotheticalObject.yPos > height) {
    hypotheticalObject.yPos = height;
    yv *= -1;
  } else if (hypotheticalObject.yPos < 0) {
    hypotheticalObject.yPos = 0;
    yv *= -1;
  }
  
  hypotheticalObject.render();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>

更新:动画Gifs

如果你想让它与动画gif一起使用,你必须处理p5.js的一个特性:它只有在使用image()函数或texture()函数渲染gif图像时才会更新gif图像。并且该渲染代码取决于具有定时信息的绘图上下文,因此不与屏幕外p5.Graphics缓冲器一起工作。这里有一个例子:

let img;
let hypotheticalObject;
function preload() {
  img = loadImage('https://www.paulwheeler.us/files/Clouds.gif');
}
function setup() {
  createCanvas(img.width, img.height);
  hypotheticalObject = {
    objectImage: img,
    // The graphics you're using for the mask need to be the size of the image
    graphicsBuffer: createGraphics(img.width, img.height),
    xPos: width / 2,
    yPos: height / 2,
    size: 100,
    init: function() {
      this.maskedImage = createImage(this.objectImage.width, this.objectImage.height);
    },
    updateShape: function() {
      this.graphicsBuffer.clear();
      // The fill color is irrelevant so long as it is opaque
      this.graphicsBuffer.fill(0);
      // These drawing instructions need to happen on the p5.Graphics object
      this.graphicsBuffer.ellipse(this.xPos, this.yPos, this.size);
    },
    render: function() {
      this.updateShape();
      // When you call mask on an image it changes the image so we need to make a copy
      this.maskedImage.copy(
        this.objectImage,
        0, 0, this.objectImage.width, this.objectImage.height,
        0, 0, this.objectImage.width, this.objectImage.height
      );
      this.maskedImage.mask(this.graphicsBuffer);
      // Always draw the image at 0, 0 since the masked portion is already offset
      image(this.maskedImage, 0, 0);
    }
  }
  hypotheticalObject.init();
}
let xv = 2;
let yv = 2;
function draw() {
  // In order to get a gif to animate it needs to be passed to either the image() function or the texture() function. And unfortunately it must be the global one, not the version on an off-screen p5.Graphics
  // However we don't actually want to display this
  image(img, width, height);
  background(255);
  hypotheticalObject.xPos += xv;
  hypotheticalObject.yPos += yv;
  if (hypotheticalObject.xPos > width) {
    hypotheticalObject.xPos = width;
    xv *= -1;
  } else if (hypotheticalObject.xPos < 0) {
    hypotheticalObject.xPos = 0;
    xv *= -1;
  }
  if (hypotheticalObject.yPos > height) {
    hypotheticalObject.yPos = height;
    yv *= -1;
  } else if (hypotheticalObject.yPos < 0) {
    hypotheticalObject.yPos = 0;
    yv *= -1;
  }
  hypotheticalObject.render();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>

最新更新