Skip to content

Commit

Permalink
Flipping resize when orientation changes
Browse files Browse the repository at this point in the history
  • Loading branch information
jakearchibald committed Nov 19, 2018
1 parent b6e452d commit 7d96c80
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 76 deletions.
2 changes: 1 addition & 1 deletion src/codecs/resize/options.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ export default class ResizerOptions extends Component<Props, State> {
onChange={this.onChange}
>
<option value="stretch">Stretch</option>
<option value="cover">Cover</option>
<option value="contain">Contain</option>
</Select>
</label>
}
Expand Down
2 changes: 1 addition & 1 deletion src/codecs/resize/processor-meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export interface ResizeOptions {
width: number;
height: number;
method: 'vector' | BitmapResizeMethods;
fitMethod: 'stretch' | 'cover';
fitMethod: 'stretch' | 'contain';
}

export interface BitmapResizeOptions extends ResizeOptions {
Expand Down
10 changes: 5 additions & 5 deletions src/codecs/resize/processor.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { nativeResize, NativeResizeMethod, drawableToImageData } from '../../lib/util';
import { BitmapResizeOptions, VectorResizeOptions } from './processor-meta';

function getCoverOffsets(sw: number, sh: number, dw: number, dh: number) {
function getContainOffsets(sw: number, sh: number, dw: number, dh: number) {
const currentAspect = sw / sh;
const endAspect = dw / dh;

Expand All @@ -22,8 +22,8 @@ export function resize(data: ImageData, opts: BitmapResizeOptions): ImageData {
let sw = data.width;
let sh = data.height;

if (opts.fitMethod === 'cover') {
({ sx, sy, sw, sh } = getCoverOffsets(sw, sh, opts.width, opts.height));
if (opts.fitMethod === 'contain') {
({ sx, sy, sw, sh } = getContainOffsets(sw, sh, opts.width, opts.height));
}

return nativeResize(
Expand All @@ -38,8 +38,8 @@ export function vectorResize(data: HTMLImageElement, opts: VectorResizeOptions):
let sw = data.width;
let sh = data.height;

if (opts.fitMethod === 'cover') {
({ sx, sy, sw, sh } = getCoverOffsets(sw, sh, opts.width, opts.height));
if (opts.fitMethod === 'contain') {
({ sx, sy, sw, sh } = getContainOffsets(sw, sh, opts.width, opts.height));
}

return drawableToImageData(data, {
Expand Down
50 changes: 38 additions & 12 deletions src/components/Options/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ export default class Options extends Component<Props, State> {
}

@bind
onEncoderTypeChange(event: Event) {
private onEncoderTypeChange(event: Event) {
const el = event.currentTarget as HTMLSelectElement;

// The select element only has values matching encoder types,
Expand All @@ -93,34 +93,54 @@ export default class Options extends Component<Props, State> {
}

@bind
onPreprocessorEnabledChange(event: Event) {
private onPreprocessorEnabledChange(event: Event) {
const el = event.currentTarget as HTMLInputElement;
const preprocessor = el.name.split('.')[0] as keyof PreprocessorState;

this.props.onPreprocessorOptionsChange(
cleanSet(this.props.preprocessorState, `${preprocessor}.enabled`, el.checked),
);
let newState = this.props.preprocessorState;

// If orientation has changed, we should flip the resize values.
if (preprocessor === 'rotateFlip' && this.props.preprocessorState.rotateFlip.rotate % 180) {
newState = cleanMerge(newState, 'resize', {
width: this.props.preprocessorState.resize.height,
height: this.props.preprocessorState.resize.width,
});
}

newState = cleanSet(newState, `${preprocessor}.enabled`, el.checked);
this.props.onPreprocessorOptionsChange(newState);
}

@bind
onQuantizerOptionsChange(opts: QuantizeOptions) {
private onQuantizerOptionsChange(opts: QuantizeOptions) {
this.props.onPreprocessorOptionsChange(
cleanMerge(this.props.preprocessorState, 'quantizer', opts),
);
}

@bind
onResizeOptionsChange(opts: ResizeOptions) {
private onResizeOptionsChange(opts: ResizeOptions) {
this.props.onPreprocessorOptionsChange(
cleanMerge(this.props.preprocessorState, 'resize', opts),
);
}

@bind
onRotateFlipOptionsChange(opts: RotateFlipOptions) {
this.props.onPreprocessorOptionsChange(
cleanMerge(this.props.preprocessorState, 'rotateFlip', opts),
);
private onRotateFlipOptionsChange(opts: RotateFlipOptions) {
// If orientation has changed, we should flip the resize values.
const oldRotate = this.props.preprocessorState.rotateFlip.rotate;
const newRotate = opts.rotate;
let newState = cleanMerge(this.props.preprocessorState, 'rotateFlip', opts);
const orientationChanged = oldRotate % 180 !== newRotate % 180;

if (orientationChanged) {
newState = cleanMerge(newState, 'resize', {
width: this.props.preprocessorState.resize.height,
height: this.props.preprocessorState.resize.width,
});
}

this.props.onPreprocessorOptionsChange(newState);
}

render(
Expand All @@ -134,6 +154,8 @@ export default class Options extends Component<Props, State> {
) {
// tslint:disable variable-name
const EncoderOptionComponent = encoderOptionsComponentMap[encoderState.type];
const flipDimensions =
preprocessorState.rotateFlip.enabled && preprocessorState.rotateFlip.rotate % 180;

return (
<div class={style.optionsScroller}>
Expand Down Expand Up @@ -169,7 +191,11 @@ export default class Options extends Component<Props, State> {
{preprocessorState.resize.enabled ?
<ResizeOptionsComponent
isVector={Boolean(source && source.vectorImage)}
aspect={source ? (source.data.width / source.data.height) : 1}
aspect={source
? flipDimensions
? (source.data.height / source.data.width)
: (source.data.width / source.data.height)
: 1}
options={preprocessorState.resize}
onChange={this.onResizeOptionsChange}
/>
Expand Down
Loading

0 comments on commit 7d96c80

Please sign in to comment.