问题
I am working with Processing.js (version 1.4.8).
I have 5 white points, which coordinates I chose specifically. The black dot marks the center of the sketch! The red cross is an element outside the canvas that marks the center of the window, so that we can compare with the black dot and ensure that the map is being correctly centered. I want my sketch to occupy the whole window. I want to be able to translate and scale my sketch.
I use the Processing.js draw function. And I am keeping track of the translations and scales.
I want my zoom operations to recenter the map at the same location it was before. But it is not working.
Here is a CodePen.
The most important code is the one from the zoom functions.
var zoomIn = function() {
scale *= 2;
translateX += - centerX / scale;
translateY += - centerY / scale;
redraw();
};
var zoomOut = function() {
translateX += centerX / scale;
translateY += centerY / scale;
scale *= 0.5;
redraw();
};
And probably here, where I actually perform the transformations:
var draw = function () {
pjs.scale(scale, scale);
pjs.translate(translateX, translateY);
drawPoints();
drawCenter();
};
I show you an example of what I want below.
1) Open the CodePen and do some translations with the arrow buttons.
2) Zoom in! The center (black dot) is no more on the window center (red cross)...
I wanted THIS (see below) to happen on zoomIn!!!
Would you please help me fix this?
Thanks
回答1:
Like I said in your last question, you're making your life harder by not using Processing.js the way it was intended. Specifically, you should really have a Processing draw()
function (note that your draw()
function is not the one Processing is looking for) and use the idea of frames to handle stuff like scaling and translating. Even if you don't want it to be 60 fps, you should still use the draw()
function to draw everything instead of doing it in events like you're trying to do now.
But more generally, your problem is caused by the fact that scaling affects the translation, and both affect where stuff is drawn. So when you tell the circle to draw in the center, that position is affected by the scale and translation, which means that it draws somewhere other than the actual center. Your code is doing exactly what you told it to do, and it's behaving exactly how I would expect it to.
If you want everything to be relative to the center, then one option would be to move the origin to the center of the window, and then draw everything relative to that. So if your center is at 100, 100
and you wanted to draw something at 75, 75
, then you'd actually draw that at -25, -25
. Then when you do scaling and translating, they'll be relative to the center.
Here is an example of what I mean:
<script src="https://cdnjs.cloudflare.com/ajax/libs/processing.js/1.6.6/processing.min.js"></script>
<script type="application/processing">
float offsetX = 0;
float offsetY = 0;
float zoom = 1;
void setup(){
size(500, 500);
}
void draw(){
background(200);
translate(width/2, height/2);
fill(0, 255, 0);
ellipse(0, 0, 20, 20);
scale(zoom);
translate(offsetX, offsetY);
fill(255);
ellipse(-25, -25, 20, 20);
ellipse(25, -25, 20, 20);
ellipse(-25, 25, 20, 20);
ellipse(25, 25, 20, 20);
fill(255, 0, 0);
ellipse(0, 0, 20, 20);
}
void keyPressed(){
if(keyCode == UP){
offsetY -= 10;
}
else if(keyCode == DOWN){
offsetY += 10;
}
else if(keyCode == LEFT){
offsetX -= 10;
}
else if(keyCode == RIGHT){
offsetX += 10;
}
else if(key == 'r'){
offsetX = 0;
offsetY = 0;
zoom = 1;
}
}
void mouseDragged(){
zoom += (pmouseY - mouseY)/10;
}
</script>
<canvas> </canvas>
Use the arrow keys to move the circles, drag the mouse to change the zoom. Note that the green circle stays in the center, and the zoom is relative to that.
CodePen is here.
来源:https://stackoverflow.com/questions/45574552/how-to-recenter-after-a-zoom