Skip to main content
Adding gif example
Source Link
DMGregory
  • 136.4k
  • 22
  • 248
  • 374

For a smooth loop like this, we want to scale the camera viewport from 1 x at the start to \$r\$ x at the end of the first loop (where \$r\$ is the ratio between the inner image size and the outer image), then \$r^2\$ x at the end of the second loop, \$r^3\$ at the end of the third loop, etc.

A function whose value compounds by some ratio each time we move a fixed distance along its domain is an exponential function. Specifically, if \$t = \frac {\text{time}} {\text{loop period}}\$, then \$\text{scale} = a \cdot r^t\$

scale = initialScale * Pow(ratio, t)

To avoid any visible variation in our movement speed or direction, the rate of travel of the center point across the image should stay in fixed proportion to the current size of the viewport. So that means that our derivative is a multiple of the formula above, and we can integrate it to get an expression for our absolute position. (Here I'm leaving off the coefficient, since we just need proportionality)

$$\int_0^t {r^x}dx\\ = \frac {r^t - 1} {\ln r}$$

At \$t = 0\$ that's 0, and at \$t = 1\$ it's \$\frac {r - 1} {\ln r}\$, so we can multiply by the reciprocal to scale it into an interpolation weight between 0 and 1:

positionInterpolation = (Pow(ratio, t) - 1)/(ratio - 1)

Now you can use this weight as the input to a lerp between your start and end positions., getting a result like this:

Looping zoom

For a smooth loop like this, we want to scale the camera viewport from 1 x at the start to \$r\$ x at the end of the first loop (where \$r\$ is the ratio between the inner image size and the outer image), then \$r^2\$ x at the end of the second loop, \$r^3\$ at the end of the third loop, etc.

A function whose value compounds by some ratio each time we move a fixed distance along its domain is an exponential function. Specifically, if \$t = \frac {\text{time}} {\text{loop period}}\$, then \$\text{scale} = a \cdot r^t\$

scale = initialScale * Pow(ratio, t)

To avoid any visible variation in our movement speed or direction, the rate of travel of the center point across the image should stay in fixed proportion to the current size of the viewport. So that means that our derivative is a multiple of the formula above, and we can integrate it to get an expression for our absolute position. (Here I'm leaving off the coefficient, since we just need proportionality)

$$\int_0^t {r^x}dx\\ = \frac {r^t - 1} {\ln r}$$

At \$t = 0\$ that's 0, and at \$t = 1\$ it's \$\frac {r - 1} {\ln r}\$, so we can multiply by the reciprocal to scale it into an interpolation weight between 0 and 1:

positionInterpolation = (Pow(ratio, t) - 1)/(ratio - 1)

Now you can use this weight as the input to a lerp between your start and end positions.

For a smooth loop like this, we want to scale the camera viewport from 1 x at the start to \$r\$ x at the end of the first loop (where \$r\$ is the ratio between the inner image size and the outer image), then \$r^2\$ x at the end of the second loop, \$r^3\$ at the end of the third loop, etc.

A function whose value compounds by some ratio each time we move a fixed distance along its domain is an exponential function. Specifically, if \$t = \frac {\text{time}} {\text{loop period}}\$, then \$\text{scale} = a \cdot r^t\$

scale = initialScale * Pow(ratio, t)

To avoid any visible variation in our movement speed or direction, the rate of travel of the center point across the image should stay in fixed proportion to the current size of the viewport. So that means that our derivative is a multiple of the formula above, and we can integrate it to get an expression for our absolute position. (Here I'm leaving off the coefficient, since we just need proportionality)

$$\int_0^t {r^x}dx\\ = \frac {r^t - 1} {\ln r}$$

At \$t = 0\$ that's 0, and at \$t = 1\$ it's \$\frac {r - 1} {\ln r}\$, so we can multiply by the reciprocal to scale it into an interpolation weight between 0 and 1:

positionInterpolation = (Pow(ratio, t) - 1)/(ratio - 1)

Now you can use this weight as the input to a lerp between your start and end positions, getting a result like this:

Looping zoom

Source Link
DMGregory
  • 136.4k
  • 22
  • 248
  • 374

For a smooth loop like this, we want to scale the camera viewport from 1 x at the start to \$r\$ x at the end of the first loop (where \$r\$ is the ratio between the inner image size and the outer image), then \$r^2\$ x at the end of the second loop, \$r^3\$ at the end of the third loop, etc.

A function whose value compounds by some ratio each time we move a fixed distance along its domain is an exponential function. Specifically, if \$t = \frac {\text{time}} {\text{loop period}}\$, then \$\text{scale} = a \cdot r^t\$

scale = initialScale * Pow(ratio, t)

To avoid any visible variation in our movement speed or direction, the rate of travel of the center point across the image should stay in fixed proportion to the current size of the viewport. So that means that our derivative is a multiple of the formula above, and we can integrate it to get an expression for our absolute position. (Here I'm leaving off the coefficient, since we just need proportionality)

$$\int_0^t {r^x}dx\\ = \frac {r^t - 1} {\ln r}$$

At \$t = 0\$ that's 0, and at \$t = 1\$ it's \$\frac {r - 1} {\ln r}\$, so we can multiply by the reciprocal to scale it into an interpolation weight between 0 and 1:

positionInterpolation = (Pow(ratio, t) - 1)/(ratio - 1)

Now you can use this weight as the input to a lerp between your start and end positions.