Skip to content

Commit 7a4a1df

Browse files
author
Sepand Parhami
committed
Reorganize files, update code documentation a bit.
1 parent 7c792e9 commit 7a4a1df

16 files changed

+90
-21
lines changed

index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export {prepareImageAnimation} from './src/transform-img/index.js';

src/img-dimensions.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,18 @@
1515
*/
1616

1717
/**
18-
* @fileoverview Provides a function the dimensions of the rendered image
19-
* inside of an <img> tag.
20-
*
18+
* @fileoverview Provides a function to calculate the dimensions of the
19+
* rendered image inside of an `<img>` Element. For example, if you have an
20+
* `<img>` with `object-fit: contain` and an image that is portrait inside of
21+
* an `<img>` with landscape dimensions, you will have something looks like:
22+
* _____________
23+
* | | | |
24+
* | i | r | i |
25+
* |___|_____|___|
26+
*
27+
* Where the area denoted by `r` is the rendered image and the areas denoted
28+
* by `i` are extra spacing on either side of the rendered image to center it
29+
* within the containing `<img>` Element.
2130
* @see https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit
2231
*/
2332

src/replacement-img.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import {getRenderedDimensions} from './img-dimensions.js';
2020
* Creates a replacement for a given img, which should render the same as the
2121
* source img, but implemented with a cropping container and and img using
2222
* `object-fit: fill`. This can be used to implement a transition of the image.
23-
* The crop can be transitioned by scaling up the container while scaping down
23+
* The crop can be transitioned by scaling up the container while scaling down
2424
* the image by the inverse amount.
2525
* @param srcImg
2626
* @param srcImgRect

src/test-img-dimensions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*/
1616

1717
import {getRenderedDimensions} from './img-dimensions';
18-
import {imgLoadPromise} from './utils';
18+
import {imgLoadPromise} from './testing/utils';
1919

2020
const {expect} = chai;
2121
const fourByThreeUri = 'data:image/gif;base64,R0lGODdhBAADAIAAAP///////ywAAAAABAADAAACA4SPVgA7';

src/test-replacement-img.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*/
1616

1717
import {createReplacement} from './replacement-img';
18-
import {imgLoadPromise} from './utils';
18+
import {imgLoadPromise} from './testing/utils';
1919

2020
const {expect} = chai;
2121
const fourByThreeUri = 'data:image/gif;base64,R0lGODdhBAADAIAAAP///////ywAAAAABAADAAACA4SPVgA7';
File renamed without changes.

src/transform-img/README.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Transform Img
2+
3+
## Overview
4+
5+
This directory contains logic for transforming an image from one location to
6+
another. The animation is comprised of 3 parts:
7+
8+
* Scaling up the image in the x and y directions to the final scale
9+
* Translating the image in the x and y directions to the final location
10+
* Changing the crop in the x and y directions to the final crop
11+
12+
Each of these are implemented in seprate file.
13+
14+
## Implementation
15+
16+
In order to have the animation perform well, including on older devices, only
17+
CPU accelrated animatable properties. As a result, the 'crop' portion of the
18+
animation is implemented by scaling up a cropping container (with
19+
`overflow: hidden`) and counteracting the scaling with an inverse scale on a
20+
child container.
21+
22+
The animations are implemented by taking the larger size and animating using
23+
that as a reference point for scaling. That is, when the transition is where
24+
the larger image is (whether that is the starting state or ending state), the
25+
scale values will all be `1.0`. This is done to avoid rounding errors from
26+
the various scale animations from having a user perceivable impact. The errors
27+
are much less or not at all noticable for the smaller image. When we are going
28+
from a small image to a large image (say scaling by 5x), we will animate the
29+
scale from `0.2` to `1.0`. If we were to run the reverse operation, we would
30+
scale from `1.0` to `0.2`.

src/crop-animation.ts renamed to src/transform-img/crop-animation.ts

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
import {Curve, getBezierCurveValue} from './bezier-curve-utils.js';
17+
import {Curve, getBezierCurveValue} from '../bezier-curve-utils.js';
1818

1919
interface Scale {
2020
x: number,
@@ -60,9 +60,14 @@ function generateCropKeyframes({
6060
let scaleElementKeyframes = '';
6161
let counterScaleKeyframes = '';
6262

63-
// Generates one step for each frame. This is just a guide, the actual values
64-
// will be interoplated from these, but just to make sure we have enough
65-
// steps for the browser to work with to make it smooth.
63+
/*
64+
* Generates keyframes for the browser to interpolate from. We simply need to
65+
* make sure there are enough for this to be smooth. Note: we are generating
66+
* keyframes as a function of `t` in the Bezier curve formula and not time.
67+
* The keyframes generated will be more clustered when the output (y) value
68+
* is more rapidly changing, so we should not have too much error no matter
69+
* which two keyframes the browser interpolates between.
70+
*/
6671
for (let i = 0; i <= numSamples; i++) {
6772
const t = i * (1 / numSamples);
6873
// The progress through the animation at this point.
@@ -95,6 +100,14 @@ function generateCropKeyframes({
95100
`;
96101
}
97102

103+
/**
104+
* Prepares a crop animation. This is done by scaling up the croping container
105+
* while scaling down a nested container to preserve the scale of the inner
106+
* content. This function sets up the animation by setting the appropriate
107+
* style properties on the desired Elements. The returned style text needs
108+
* to be inserted for the animation to run.
109+
* @return CSS style text to perform the aniamtion.
110+
*/
98111
export function prepareCropAnimation({
99112
scaleElement,
100113
counterScaleElement,

0 commit comments

Comments
 (0)