Вот моя интерпретация того, о чем вы говорите. Мы храним логическое значение isClicked
для хранения состояния, увеличивать или нет. Когда мы собираемся нарисовать изображение, мы translate()
к мышке, затем мы scale()
, затем мы translate()
возвращаем ту же величину, что и раньше, но в противоположном направлении. Это делает масштабирование вокруг положения мыши.
Одна вещь, которую я не смог найти способ, как вы обновляете пиксели непосредственно из изображения и эффект фонарика. Вместо этого программа использует ваш метод для создания маскирующего изображения и применяет его к объекту PGraphics
. Еще одна вещь, которую я заметил, заключается в том, что при рендеринге прямо на экран наблюдается значительное отставание от масштабирования. Вместо этого я переместил рисунок на объект PGraphics
. Это повышает производительность.
В конце концов, для рендеринга программа рисует все на объекте PGraphics
, затем применяет маску к этому объекту, чтобы получить эффект фонарика.
Здесь это код, который у меня есть:
PImage ispy, distMask;
boolean isClicked = false;
PGraphics renderer;
void createDistanceMask(PImage distMask){ //Takes image and changes its pixels to "alpha" for the PGraphics renderer
distMask.loadPixels();
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
int loc = x+(height-y-1)*width;
float d = dist(mouseX, mouseY, x, y); //
int factor = int(map(d, 0, 200, 400, 0)); //Pixel data will be between 0 and 255, must scale down later.
if (factor > 255)
factor = 255;
distMask.pixels[loc] = color(factor,factor,factor);
}
}
distMask.updatePixels();
}
void setup () {
size(1024,768, P2D);
ispy = loadImage("ispy2.jpeg");
distMask = new PImage(width,height);
renderer = createGraphics(width,height,P2D);
mouseX = width/2; //Not necessary, but will have black screen until mouse is moved
mouseY = height/2;
}
void draw () {
background(0);
pushMatrix();
createDistanceMask(distMask);
renderer.beginDraw(); //Starts processing stuff into PGraphics object
renderer.background(0);
if(isClicked){ //This is to get the zoom effect
renderer.translate(mouseX, mouseY);
renderer.scale(2);
renderer.translate(-mouseX, -mouseY);
}
renderer.image(ispy,0,0); //Render Image
renderer.endDraw();
renderer.mask(distMask); //Apply Distance mask for flashlight effect
image(renderer,0,0); //Draw renderer result to screen
popMatrix();
}
void mouseClicked(){
isClicked = !isClicked;
}
В своем комментарии я спросил о том, чтобы экран двигался к мышке, что и делает. Если вы хотите «заморозить» экран в одной позиции, вы можете сохранить lastMouseClickPosition
PVector или просто целые числа. Затем при переводе переводите в позицию вместо PVector.
Вот код, который изменится:
PVector lastClickPos = new PVector(); //Make the position
if(isClicked){ //When Rendering
renderer.translate(lastClickPos.x, lastClickPos.y);
renderer.scale(scalingFactor);
renderer.translate(-lastClickPos.x, -lastClickPos.y);
}
void mouseClicked(){ //At the bottom
isClicked = !isClicked;
lastClickPos.set(mouseX, mouseY);
}