在 p5js 上更流畅 "image brush"

smoother "image brush" on p5js

我编写了简单的代码,在使用 p5.js 按下鼠标时在屏幕周围绘制图像。

我注意到创建图像的流程并不是很流畅,尤其是当鼠标移动得更快时,它看起来不像是统一的画笔,而是许多分离的图像。即使鼠标移动较慢,仍然可以看到所有不同的图片。

是否可以使用 p5.js 使此效果更平滑,或者我应该尝试其他方法来实现此效果?

let image1;

function setup() {
  createCanvas(windowWidth, windowHeight);
  background(220);
  image1 = loadImage('https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg');
};

function mouseDragged() {
  let number = 5;
  image( image1, mouseX - ((image1.width/number) / 2), mouseY - ((image1.height/number) / 2), image1.width / number, image1.height / number);
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.3.1/p5.min.js"></script>

我可以想到两种方法来解决这个问题,第一种是增加帧速率,这意味着每秒会有更多的帧,从而创建更多的图像,其工作方式如下:

let image1;
function setup() {
  createCanvas(windowWidth, windowHeight);
  background(220);
  image1 = loadImage(
    "https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg"
  );
  frameRate(190);
}

function mouseDragged() {
  let number = 5;
  image(
    image1,
    mouseX - image1.width / number / 2,
    mouseY - image1.height / number / 2,
    image1.width / number,
    image1.height / number
  );
}

另一种方法是为每一帧创建一个 for 循环,因此每一帧,无论发生什么,都会重复 X 时间

let image1;
function setup() {
  createCanvas(windowWidth, windowHeight);
  background(220);
  image1 = loadImage(
    "https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg"
  );
}

function mouseDragged() {
  for(var i = 0; i<2;i++)
    {
  let number = 5;
  image(
    image1,
    mouseX - image1.width / number / 2,
    mouseY - image1.height / number / 2,
    image1.width / number,
    image1.height / number
  );
    }
}

我会推荐第一种方法,因为您可以将数字“190”设置为非常高的值 (1,000),然后它将达到一流的性能,显然不是每秒 1,000 帧,而是最高它可以做到。如果把第二种方法中的数值改的很大,不但不会变快,反而会变的很慢。

最终我找到了解决问题的方法。 基本上对于每次鼠标移动,我都会使用相同的图像绘制 50 个中间步骤。这个数字当然可以增加,但我注意到如果这些数字太高,浏览器性能会下降,大约 50-200 对我来说很好。

let image1;
var firstDrag = true;
var dx;
var dy;
var posx;
var posy;

function setup() {
  createCanvas(windowWidth, windowHeight);
  background(220);
  image1 = loadImage('https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg');
};

function mouseDragged() {
  let number = 5;
  
  //check if it is the first dragging
  //so there's no previous position
  if(firstDrag){
    firstDrag = false;
    prevX = mouseX;
    prevY = mouseY;
  }
  //create 50 intermediates step
  //between previous and current mouse position
  //store in dx and dy the increments to add for each step
  dx = ((mouseX - prevX) / 50);
  dy = ((mouseY - prevY) / 50);
  dxVar = prevX;
  dyVar = prevY;
  
  //drawing a pictures for each intermediate coordinates
  for (let i = 0; i < 49; i++) {
  
    posx = dxVar - ((image1.width/ number) /2);
    posy = dyVar - ((image1.height/ number)/2);
    
    image( image1, posx, posy, image1.width / number, image1.height / number);
    dxVar = dxVar + dx;
    dyVar = dyVar + dy;
  }
  
  //updating the previous mouse position
  prevX = mouseX;
  prevY = mouseY;
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.min.js"></script>