# Crop plugin

Use the Crop plugin to manipulate the crop selection and image orientation.

The crop plugin handles the following functionality:

* Manipulating the crop selection
* Free rotating the image
* Exposing crop selection presets
* Zooming the image
* Turning the image left and right
* Flipping the image
* Showing current crop size

All functionality can be toggled and configured with the properties below:

| Property                                                                              | Default value | Description                                                                                                                                                                                                      |
| ------------------------------------------------------------------------------------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [cropMaskOpacity](#cropmaskopacity)                                                   | .85           | Adjust the opacity of the mask outside of the crop area.                                                                                                                                                         |
| [cropSelectPresetOptions](#cropselectpresetoptions)                                   | \[\]          | A list of crop presets.                                                                                                                                                                                          |
| [cropSelectPresetFilter](#cropselectpresetfilter)                                     | false         | An orientation filter to apply to the crop presets list. Set to 'landscape' to enable orientation tabs in the preset dropdown and show landscape aspect ratios.                                                  |
| cropEnableFilterMatchAspectRatio                                                      | true          | Automatically switch crop aspect ratio when the preset filter is changed.                                                                                                                                        |
| cropImageSelectionCornerStyle                                                         | 'circle'      | Determines style of crop selection corners, either 'circle', 'hook', or 'invisible', defaults to 'circle'.                                                                                                       |
| [cropWillRenderImageSelectionGuides](#cropwillrenderimageselectionguides)             | undefined     | Determines if and how many image selection guides are rendered.                                                                                                                                                  |
| [cropWillRenderTools](#cropwillrendertools)                                           | undefined     | Can be used to adjust the items in the crop toolbar.                                                                                                                                                             |
| [cropEnableButtonFlipHorizontal](#cropenablebuttonfliphorizontal)                     | true          | Toggle flip horizontal button.                                                                                                                                                                                   |
| [cropEnableButtonFlipVertical](#cropenablebuttonflipvertical)                         | false         | Toggle flip vertical button.                                                                                                                                                                                     |
| [cropEnableButtonRotateLeft](#cropenablebuttonrotateleft)                             | true          | Toggle rotate left button.                                                                                                                                                                                       |
| [cropEnableButtonRotateRight](#cropenablebuttonrotateright)                           | false         | Toggle Rotate right button.                                                                                                                                                                                      |
| [cropEnableButtonToggleCropLimit](#cropenablebuttontogglecroplimit)                   | false         | Toggle crop limit button.                                                                                                                                                                                        |
| [cropEnableImageSelection](#cropenableimageselection)                                 | true          | Enable or disable the crop selection controls.                                                                                                                                                                   |
| [cropEnableInfoIndicator](#cropenableinfoindicator)                                   | false         | Show image size indicator.                                                                                                                                                                                       |
| [cropWillRenderInfoIndicator](#cropwillrenderinfoindicator)                           | undefined     | Called before rendering the info indicator, receives crop, and size, should return a string.                                                                                                                     |
| [cropEnableLimitWheelInputToCropSelection](#cropenablelimitwheelinputtocropselection) | true          | Only captures mouse wheel interactions when the mouse is inside the crop selection.                                                                                                                              |
| [cropEnableRotationInput](#cropenablerotationinput)                                   | true          | Toggle the image rotation input on and off.                                                                                                                                                                      |
| [cropEnableSelectPreset](#cropenableselectpreset)                                     | true          | If crop presets have been defined this will show the preset dropdown in the toolbar.                                                                                                                             |
| [cropEnableZoom](#cropenablezoom)                                                     | true          | Enable generic zooming of the image. If set to false all zoom related input will be disabled.                                                                                                                    |
| [cropEnableZoomInput](#cropenablezoominput)                                           | true          | Enable the zoom input control at the bottom of the crop tool. This control will automatically hide if there's not enough vertical space.                                                                         |
| [cropEnableZoomAutoHide](#cropenablezoomautohide)                                     | true          | When set to true the zoom control is automatically hidden to preserve space in layouts with low vertical space.                                                                                                  |
| [cropActiveTransformTool](#cropactivetransformtool)                                   | 'rotation'    | Set to 'zoom' to activate the zoom tool instead of the rotation tool.                                                                                                                                            |
| [cropEnableZoomMatchImageAspectRatio](#cropenablezoommatchimageaspectratio)           | true          | Will automatically adjust the crop aspect ratio when zooming out, only works if aspect ratio is set to undefined                                                                                                 |
| [cropEnableRotateMatchImageAspectRatio](#cropenablerotatematchimageaspectratio)       | 'never'       | Will automatically rotate the crop rectangle with the image if set to 'custom', or 'always'.                                                                                                                     |
| cropEnableZoomTowardsWheelPosition                                                    | true          | Will zoom in towards the mouse position within the crop.                                                                                                                                                         |
| cropEnableCenterImageSelection                                                        | true          | Toggle the center selection button on and off.                                                                                                                                                                   |
| cropAutoCenterImageSelectionTimeout                                                   | undefined     | Timeout in milliseconds after which the crop automatically re-centers.                                                                                                                                           |
| cropMinimizeToolbar                                                                   | 'auto'        | Set to 'always' to force propagating the toolbar items to the main toolbar instead of showing in separate row.                                                                                                   |
| [cropInteractionFocus](#cropinteractionfocus)                                         | 'image'       | The focus of interaction, defaults to 'image' meaning the user interacts with the image instead of the crop selection. Change to 'selection' to lock the image in place and interact with the selection instead. |
| [cropRotationRange](#croprotationrange)                                               | Math.PI / 4   | The negative and positive range the rotation control can move. The default value Math.PI / 4 results in a range from \-Math.PI / 4 to Math.PI / 4.                                                               |

## cropMaskOpacity

Adjust the opacity of the mask outside of the crop area, by default is set to `.85`

## cropSelectPresetOptions

A flat or a grouped array of crop presets.

```js
// An example of a flat list of crop aspect ratio presets.
[
    [undefined, 'Custom'],
    [1, 'Square'],
    [4 / 3, 'Landscape'],
    [3 / 4, 'Portrait'],
];
```

If we don't supply the 'Custom' crop options with value `undefined` we have to make sure we set the `imageCropAspectRatio` property to one of the values in the list otherwise the editor won't know which value to select.

```js
// An example of a grouped list of presets.
[
    [
        'Crop Aspect Ratios',
        [
            [undefined, 'Custom'],
            [1, 'Square'],
            [4 / 3, 'Landscape'],
            [3 / 4, 'Portrait'],
        ],
    ],
    [
        'Crop sizes',
        [
            [[180, 180], 'Profile Picture'],
            [[1200, 600], 'Header Image'],
            [[800, 400], 'Timeline Photo'],
        ],
    ],
];
```

As we could see in the previous code snippets we can describe a crop with `[aspectRatio, 'label']` and a size preset with `[[width, height], 'label']`.

Pintura Image Editor will apply the `aspectRatio` value to the [imageCropAspectRatio](../../image-editor/properties/#imagecropaspectratio) prop. When a `size` is selected it will apply the matching aspect ratio and apply the size to the `imageTargetSize` prop.

* [ ![](/pintura/static/assets/technologies-mono/javascript.svg)JavaScript](#javascript-panel-32)
* [ ![](/pintura/static/assets/technologies-mono/react.svg)React](#react-panel-32)
* [ ![](/pintura/static/assets/technologies-mono/vue.svg)Vue](#vue-panel-32)
* [ ![](/pintura/static/assets/technologies-mono/svelte.svg)Svelte](#svelte-panel-32)
* [ ![](/pintura/static/assets/technologies-mono/angular.svg)Angular](#angular-panel-32)
* [ ![](/pintura/static/assets/technologies-mono/jquery.svg)jQuery](#jquery-panel-32)

* [index.html](#index-html-panel-32)

`<!DOCTYPE html>

<head>
    <link rel="stylesheet" href="./pintura.css" />
</head>

<style>
    .pintura-editor {
        height: 600px;
    }
</style>

<div id="editor"></div>

<script type="module">
    import { appendDefaultEditor } from './pintura.js';

    const editor = appendDefaultEditor('#editor', {
        src: 'image.jpeg',
        cropSelectPresetOptions: [
            [
                'Crop',
                [
                    [undefined, 'Custom'],
                    [1, 'Square'],
                    [4 / 3, 'Landscape'],
                    [3 / 4, 'Portrait'],
                ],
            ],
            [
                'Size',
                [
                    [[180, 180], 'Profile Picture'],
                    [[1200, 600], 'Header Image'],
                    [[800, 400], 'Timeline Photo'],
                ],
            ],
        ],
    });
</script>
`

* [App.jsx](#App-jsx-panel-32)
* [App.css](#App-css-panel-32)

`import '@pqina/pintura/pintura.css';
import './App.css';
import { PinturaEditor } from '@pqina/react-pintura';
import { getEditorDefaults } from '@pqina/pintura';

const editorDefaults = getEditorDefaults();

function App() {
    return (
        <div className="App">
            <PinturaEditor
                {...editorDefaults}
                src={'image.jpeg'}
                cropSelectPresetOptions={[
                    [
                        'Crop',
                        [
                            [undefined, 'Custom'],
                            [1, 'Square'],
                            [4 / 3, 'Landscape'],
                            [3 / 4, 'Portrait'],
                        ],
                    ],
                    [
                        'Size',
                        [
                            [[180, 180], 'Profile Picture'],
                            [[1200, 600], 'Header Image'],
                            [[800, 400], 'Timeline Photo'],
                        ],
                    ],
                ]}
            />
        </div>
    );
}

export default App;
`

```css
.pintura-editor {
    height: 600px;
}

```

* [App.vue](#App-vue-panel-32)

`<template>
    <div>
        <PinturaEditor
            v-bind="editorDefaults"
            src="image.jpeg"
            :cropSelectPresetOptions="cropSelectPresetOptions"
        />
    </div>
</template>
<script>
import { PinturaEditor } from '@pqina/vue-pintura';
import { getEditorDefaults } from '@pqina/pintura';

export default {
    name: 'App',

    components: {
        PinturaEditor,
    },

    data() {
        return {
            editorDefaults: getEditorDefaults(),

            cropSelectPresetOptions: [
                [
                    'Crop',
                    [
                        [undefined, 'Custom'],
                        [1, 'Square'],
                        [4 / 3, 'Landscape'],
                        [3 / 4, 'Portrait'],
                    ],
                ],
                [
                    'Size',
                    [
                        [[180, 180], 'Profile Picture'],
                        [[1200, 600], 'Header Image'],
                        [[800, 400], 'Timeline Photo'],
                    ],
                ],
            ],
        };
    },

    methods: {},
};
</script>
<style>
@import '@pqina/pintura/pintura.css';

.pintura-editor {
    height: 600px;
}
</style>
`

* [App.svelte](#App-svelte-panel-32)

`<script>
    import { PinturaEditor } from '@pqina/svelte-pintura';
    import { getEditorDefaults } from '@pqina/pintura';
    import '@pqina/pintura/pintura.css';

    let editorDefaults = getEditorDefaults();
</script>

<div>
    <PinturaEditor
        {...editorDefaults}
        src={'image.jpeg'}
        cropSelectPresetOptions={[
            [
                'Crop',
                [
                    [undefined, 'Custom'],
                    [1, 'Square'],
                    [4 / 3, 'Landscape'],
                    [3 / 4, 'Portrait'],
                ],
            ],
            [
                'Size',
                [
                    [[180, 180], 'Profile Picture'],
                    [[1200, 600], 'Header Image'],
                    [[800, 400], 'Timeline Photo'],
                ],
            ],
        ]}
    />
</div>

<style>
    div :global(.pintura-editor) {
        height: 600px;
    }
</style>
`

* [app.component.ts](#app-component-ts-panel-32)
* [app.component.html](#app-component-html-panel-32)
* [app.component.css](#app-component-css-panel-32)
* [app.module.ts](#app-module-ts-panel-32)

`import { Component } from '@angular/core';

import { getEditorDefaults } from '@pqina/pintura';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css'],
})
export class AppComponent {
    editorDefaults: any = getEditorDefaults();

    cropSelectPresetOptions: any = [
        [
            'Crop',
            [
                [undefined, 'Custom'],
                [1, 'Square'],
                [4 / 3, 'Landscape'],
                [3 / 4, 'Portrait'],
            ],
        ],
        [
            'Size',
            [
                [[180, 180], 'Profile Picture'],
                [[1200, 600], 'Header Image'],
                [[800, 400], 'Timeline Photo'],
            ],
        ],
    ];
}
`

`<pintura-editor
    [options]="editorDefaults"
    src="image.jpeg"
    [cropSelectPresetOptions]="cropSelectPresetOptions"
></pintura-editor>
`

```css
::ng-deep .pintura-editor {
    height: 600px;
}

```

```javascript
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { AngularPinturaModule } from '@pqina/angular-pintura';

@NgModule({
    declarations: [AppComponent],
    imports: [BrowserModule, AngularPinturaModule],
    exports: [AppComponent],
    providers: [],
    bootstrap: [AppComponent],
})
export class AppModule {}

```

* [index.html](#index-html-panel-32)

`<!DOCTYPE html>
<head>
    <link rel="stylesheet" href="./pintura/pintura.css" />
</head>

<script src="./jquery.js"></script>
<script src="./jquery-pintura/useEditorWithJQuery-iife.js"></script>
<script src="./pintura/pintura-iife.js"></script>

<style>
    .pintura-editor {
        height: 600px;
    }
</style>

<div id="editor"></div>

<script>
    useEditorWithJQuery(jQuery, pintura);

    $(function () {
        var editor = $('#editor').pinturaDefault({
            src: 'image.jpeg',
            cropSelectPresetOptions: [
                [
                    'Crop',
                    [
                        [undefined, 'Custom'],
                        [1, 'Square'],
                        [4 / 3, 'Landscape'],
                        [3 / 4, 'Portrait'],
                    ],
                ],
                [
                    'Size',
                    [
                        [[180, 180], 'Profile Picture'],
                        [[1200, 600], 'Header Image'],
                        [[800, 400], 'Timeline Photo'],
                    ],
                ],
            ],
        });
    });
</script>
`

## cropSelectPresetFilter

If we want to list a lot of crop aspect ratios the dropdown might get a bit long. The `cropSelectPresetFilter` option enables us to filter the list of options.

Set to `'landscape'` to enable orientation tabs in the preset dropdown and show landscape aspect ratios.

A aspect ratio value of `1` or `undefined` will always be shown.

* [ ![](/pintura/static/assets/technologies-mono/javascript.svg)JavaScript](#javascript-panel-33)
* [ ![](/pintura/static/assets/technologies-mono/react.svg)React](#react-panel-33)
* [ ![](/pintura/static/assets/technologies-mono/vue.svg)Vue](#vue-panel-33)
* [ ![](/pintura/static/assets/technologies-mono/svelte.svg)Svelte](#svelte-panel-33)
* [ ![](/pintura/static/assets/technologies-mono/angular.svg)Angular](#angular-panel-33)
* [ ![](/pintura/static/assets/technologies-mono/jquery.svg)jQuery](#jquery-panel-33)

* [index.html](#index-html-panel-33)

`<!DOCTYPE html>

<head>
    <link rel="stylesheet" href="./pintura.css" />
</head>

<style>
    .pintura-editor {
        height: 600px;
    }
</style>

<div id="editor"></div>

<script type="module">
    import { appendDefaultEditor } from './pintura.js';

    const editor = appendDefaultEditor('#editor', {
        src: 'image.jpeg',
        cropSelectPresetFilter: 'landscape',
        cropSelectPresetOptions: [
            [undefined, 'Custom'],
            [1, 'Square'],

            // shown when cropSelectPresetFilter is set to 'landscape'
            [2 / 1, '2:1'],
            [3 / 2, '3:2'],
            [4 / 3, '4:3'],
            [16 / 10, '16:10'],
            [16 / 9, '16:9'],

            // shown when cropSelectPresetFilter is set to 'portrait'
            [1 / 2, '1:2'],
            [2 / 3, '2:3'],
            [3 / 4, '3:4'],
            [10 / 16, '10:16'],
            [9 / 16, '9:16'],
        ],
    });
</script>
`

* [App.jsx](#App-jsx-panel-33)
* [App.css](#App-css-panel-33)

`import '@pqina/pintura/pintura.css';
import './App.css';
import { PinturaEditor } from '@pqina/react-pintura';
import { getEditorDefaults } from '@pqina/pintura';

const editorDefaults = getEditorDefaults();

function App() {
    return (
        <div className="App">
            <PinturaEditor
                {...editorDefaults}
                src={'image.jpeg'}
                cropSelectPresetFilter={'landscape'}
                cropSelectPresetOptions={[
                    [undefined, 'Custom'],
                    [1, 'Square'],

                    // shown when cropSelectPresetFilter is set to 'landscape'
                    [2 / 1, '2:1'],
                    [3 / 2, '3:2'],
                    [4 / 3, '4:3'],
                    [16 / 10, '16:10'],
                    [16 / 9, '16:9'],

                    // shown when cropSelectPresetFilter is set to 'portrait'
                    [1 / 2, '1:2'],
                    [2 / 3, '2:3'],
                    [3 / 4, '3:4'],
                    [10 / 16, '10:16'],
                    [9 / 16, '9:16'],
                ]}
            />
        </div>
    );
}

export default App;
`

```css
.pintura-editor {
    height: 600px;
}

```

* [App.vue](#App-vue-panel-33)

`<template>
    <div>
        <PinturaEditor
            v-bind="editorDefaults"
            src="image.jpeg"
            cropSelectPresetFilter="landscape"
            :cropSelectPresetOptions="cropSelectPresetOptions"
        />
    </div>
</template>
<script>
import { PinturaEditor } from '@pqina/vue-pintura';
import { getEditorDefaults } from '@pqina/pintura';

export default {
    name: 'App',

    components: {
        PinturaEditor,
    },

    data() {
        return {
            editorDefaults: getEditorDefaults(),

            cropSelectPresetOptions: [
                [undefined, 'Custom'],
                [1, 'Square'],

                // shown when cropSelectPresetFilter is set to 'landscape'
                [2 / 1, '2:1'],
                [3 / 2, '3:2'],
                [4 / 3, '4:3'],
                [16 / 10, '16:10'],
                [16 / 9, '16:9'],

                // shown when cropSelectPresetFilter is set to 'portrait'
                [1 / 2, '1:2'],
                [2 / 3, '2:3'],
                [3 / 4, '3:4'],
                [10 / 16, '10:16'],
                [9 / 16, '9:16'],
            ],
        };
    },

    methods: {},
};
</script>
<style>
@import '@pqina/pintura/pintura.css';

.pintura-editor {
    height: 600px;
}
</style>
`

* [App.svelte](#App-svelte-panel-33)

`<script>
    import { PinturaEditor } from '@pqina/svelte-pintura';
    import { getEditorDefaults } from '@pqina/pintura';
    import '@pqina/pintura/pintura.css';

    let editorDefaults = getEditorDefaults();
</script>

<div>
    <PinturaEditor
        {...editorDefaults}
        src={'image.jpeg'}
        cropSelectPresetFilter={'landscape'}
        cropSelectPresetOptions={[
            [undefined, 'Custom'],
            [1, 'Square'],

            // shown when cropSelectPresetFilter is set to 'landscape'
            [2 / 1, '2:1'],
            [3 / 2, '3:2'],
            [4 / 3, '4:3'],
            [16 / 10, '16:10'],
            [16 / 9, '16:9'],

            // shown when cropSelectPresetFilter is set to 'portrait'
            [1 / 2, '1:2'],
            [2 / 3, '2:3'],
            [3 / 4, '3:4'],
            [10 / 16, '10:16'],
            [9 / 16, '9:16'],
        ]}
    />
</div>

<style>
    div :global(.pintura-editor) {
        height: 600px;
    }
</style>
`

* [app.component.ts](#app-component-ts-panel-33)
* [app.component.html](#app-component-html-panel-33)
* [app.component.css](#app-component-css-panel-33)
* [app.module.ts](#app-module-ts-panel-33)

`import { Component } from '@angular/core';

import { getEditorDefaults } from '@pqina/pintura';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css'],
})
export class AppComponent {
    editorDefaults: any = getEditorDefaults();

    cropSelectPresetOptions: any = [
        [undefined, 'Custom'],
        [1, 'Square'],

        // shown when cropSelectPresetFilter is set to 'landscape'
        [2 / 1, '2:1'],
        [3 / 2, '3:2'],
        [4 / 3, '4:3'],
        [16 / 10, '16:10'],
        [16 / 9, '16:9'],

        // shown when cropSelectPresetFilter is set to 'portrait'
        [1 / 2, '1:2'],
        [2 / 3, '2:3'],
        [3 / 4, '3:4'],
        [10 / 16, '10:16'],
        [9 / 16, '9:16'],
    ];
}
`

`<pintura-editor
    [options]="editorDefaults"
    src="image.jpeg"
    cropSelectPresetFilter="landscape"
    [cropSelectPresetOptions]="cropSelectPresetOptions"
></pintura-editor>
`

```css
::ng-deep .pintura-editor {
    height: 600px;
}

```

```javascript
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { AngularPinturaModule } from '@pqina/angular-pintura';

@NgModule({
    declarations: [AppComponent],
    imports: [BrowserModule, AngularPinturaModule],
    exports: [AppComponent],
    providers: [],
    bootstrap: [AppComponent],
})
export class AppModule {}

```

* [index.html](#index-html-panel-33)

`<!DOCTYPE html>
<head>
    <link rel="stylesheet" href="./pintura/pintura.css" />
</head>

<script src="./jquery.js"></script>
<script src="./jquery-pintura/useEditorWithJQuery-iife.js"></script>
<script src="./pintura/pintura-iife.js"></script>

<style>
    .pintura-editor {
        height: 600px;
    }
</style>

<div id="editor"></div>

<script>
    useEditorWithJQuery(jQuery, pintura);

    $(function () {
        var editor = $('#editor').pinturaDefault({
            src: 'image.jpeg',
            cropSelectPresetFilter: 'landscape',
            cropSelectPresetOptions: [
                [undefined, 'Custom'],
                [1, 'Square'],

                // shown when cropSelectPresetFilter is set to 'landscape'
                [2 / 1, '2:1'],
                [3 / 2, '3:2'],
                [4 / 3, '4:3'],
                [16 / 10, '16:10'],
                [16 / 9, '16:9'],

                // shown when cropSelectPresetFilter is set to 'portrait'
                [1 / 2, '1:2'],
                [2 / 3, '2:3'],
                [3 / 4, '3:4'],
                [10 / 16, '10:16'],
                [9 / 16, '9:16'],
            ],
        });
    });
</script>
`

## cropWillRenderImageSelectionGuides

Set opacity to `.25` to always render the image selection guides.

`interactionFraction` tweens from `0` to `1` when the user interacts with the editor UI this allows us to fade in and out the image selection guides.

* [ ![](/pintura/static/assets/technologies-mono/javascript.svg)JavaScript](#javascript-panel-34)
* [ ![](/pintura/static/assets/technologies-mono/react.svg)React](#react-panel-34)
* [ ![](/pintura/static/assets/technologies-mono/vue.svg)Vue](#vue-panel-34)
* [ ![](/pintura/static/assets/technologies-mono/svelte.svg)Svelte](#svelte-panel-34)
* [ ![](/pintura/static/assets/technologies-mono/angular.svg)Angular](#angular-panel-34)
* [ ![](/pintura/static/assets/technologies-mono/jquery.svg)jQuery](#jquery-panel-34)

* [index.html](#index-html-panel-34)

```html
<!DOCTYPE html>

<head>
    <link rel="stylesheet" href="./pintura.css" />
</head>

<style>
    .pintura-editor {
        height: 600px;
    }
</style>

<div id="editor"></div>

<script type="module">
    import { appendDefaultEditor } from './pintura.js';

    const editor = appendDefaultEditor('#editor', {
        src: 'image.jpeg',
        cropWillRenderImageSelectionGuides: (
            interaction,
            interactionFraction
        ) => {
            const isRotating = interaction === 'rotate';
            return {
                rows: isRotating ? 5 : 3,
                cols: isRotating ? 5 : 3,
                opacity: interactionFraction * 0.25,
            };
        },
    });
</script>

```

* [App.jsx](#App-jsx-panel-34)
* [App.css](#App-css-panel-34)

`import '@pqina/pintura/pintura.css';
import './App.css';
import { PinturaEditor } from '@pqina/react-pintura';
import { getEditorDefaults } from '@pqina/pintura';

const editorDefaults = getEditorDefaults();

function App() {
    const cropWillRenderImageSelectionGuides = (
        interaction,
        interactionFraction
    ) => {
        const isRotating = interaction === 'rotate';
        return {
            rows: isRotating ? 5 : 3,
            cols: isRotating ? 5 : 3,
            opacity: interactionFraction * 0.25,
        };
    };

    return (
        <div className="App">
            <PinturaEditor
                {...editorDefaults}
                src={'image.jpeg'}
                cropWillRenderImageSelectionGuides={
                    cropWillRenderImageSelectionGuides
                }
            />
        </div>
    );
}

export default App;
`

```css
.pintura-editor {
    height: 600px;
}

```

* [App.vue](#App-vue-panel-34)

`<template>
    <div>
        <PinturaEditor
            v-bind="editorDefaults"
            src="image.jpeg"
            :cropWillRenderImageSelectionGuides="
                cropWillRenderImageSelectionGuides
            "
        />
    </div>
</template>
<script>
import { PinturaEditor } from '@pqina/vue-pintura';
import { getEditorDefaults } from '@pqina/pintura';

export default {
    name: 'App',

    components: {
        PinturaEditor,
    },

    data() {
        return {
            editorDefaults: getEditorDefaults(),

            cropWillRenderImageSelectionGuides: (
                interaction,
                interactionFraction
            ) => {
                const isRotating = interaction === 'rotate';
                return {
                    rows: isRotating ? 5 : 3,
                    cols: isRotating ? 5 : 3,
                    opacity: interactionFraction * 0.25,
                };
            },
        };
    },

    methods: {},
};
</script>
<style>
@import '@pqina/pintura/pintura.css';

.pintura-editor {
    height: 600px;
}
</style>
`

* [App.svelte](#App-svelte-panel-34)

```svelte
<script>
    import { PinturaEditor } from '@pqina/svelte-pintura';
    import { getEditorDefaults } from '@pqina/pintura';
    import '@pqina/pintura/pintura.css';

    let editorDefaults = getEditorDefaults();

    const cropWillRenderImageSelectionGuides = (
        interaction,
        interactionFraction
    ) => {
        const isRotating = interaction === 'rotate';
        return {
            rows: isRotating ? 5 : 3,
            cols: isRotating ? 5 : 3,
            opacity: interactionFraction * 0.25,
        };
    };
</script>

<div>
    <PinturaEditor
        {...editorDefaults}
        src={'image.jpeg'}
        {cropWillRenderImageSelectionGuides}
    />
</div>

<style>
    div :global(.pintura-editor) {
        height: 600px;
    }
</style>

```

* [app.component.ts](#app-component-ts-panel-34)
* [app.component.html](#app-component-html-panel-34)
* [app.component.css](#app-component-css-panel-34)
* [app.module.ts](#app-module-ts-panel-34)

```javascript
import { Component } from '@angular/core';

import { getEditorDefaults } from '@pqina/pintura';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css'],
})
export class AppComponent {
    editorDefaults: any = getEditorDefaults();

    cropWillRenderImageSelectionGuides = (
        interaction: string,
        interactionFraction: number
    ): { rows: number; cols: number; opacity: number } => {
        const isRotating = interaction === 'rotate';
        return {
            rows: isRotating ? 5 : 3,
            cols: isRotating ? 5 : 3,
            opacity: interactionFraction * 0.25,
        };
    };
}

```

`<pintura-editor
    [options]="editorDefaults"
    src="image.jpeg"
    [cropWillRenderImageSelectionGuides]="cropWillRenderImageSelectionGuides"
></pintura-editor>
`

```css
::ng-deep .pintura-editor {
    height: 600px;
}

```

```javascript
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { AngularPinturaModule } from '@pqina/angular-pintura';

@NgModule({
    declarations: [AppComponent],
    imports: [BrowserModule, AngularPinturaModule],
    exports: [AppComponent],
    providers: [],
    bootstrap: [AppComponent],
})
export class AppModule {}

```

* [index.html](#index-html-panel-34)

```html
<!DOCTYPE html>
<head>
    <link rel="stylesheet" href="./pintura/pintura.css" />
</head>

<script src="./jquery.js"></script>
<script src="./jquery-pintura/useEditorWithJQuery-iife.js"></script>
<script src="./pintura/pintura-iife.js"></script>

<style>
    .pintura-editor {
        height: 600px;
    }
</style>

<div id="editor"></div>

<script>
    useEditorWithJQuery(jQuery, pintura);

    $(function () {
        var editor = $('#editor').pinturaDefault({
            src: 'image.jpeg',
            cropWillRenderImageSelectionGuides: (
                interaction,
                interactionFraction
            ) => {
                const isRotating = interaction === 'rotate';
                return {
                    rows: isRotating ? 5 : 3,
                    cols: isRotating ? 5 : 3,
                    opacity: interactionFraction * 0.25,
                };
            },
        });
    });
</script>

```

## cropWillRenderTools

The `cropWillRenderTools` hook receives the current tools definition and editor environment parameters. The hook allows injecting custom controls into the tools list using the [createNode](../../ui/exports/#createnode) helper function.

The third parameter of the hook is a `redraw` function, you can call this function to redraw the UI. Only needed when adjusting external parameters.

* [ ![](/pintura/static/assets/technologies-mono/javascript.svg)JavaScript](#javascript-panel-35)
* [ ![](/pintura/static/assets/technologies-mono/react.svg)React](#react-panel-35)
* [ ![](/pintura/static/assets/technologies-mono/vue.svg)Vue](#vue-panel-35)
* [ ![](/pintura/static/assets/technologies-mono/svelte.svg)Svelte](#svelte-panel-35)
* [ ![](/pintura/static/assets/technologies-mono/angular.svg)Angular](#angular-panel-35)
* [ ![](/pintura/static/assets/technologies-mono/jquery.svg)jQuery](#jquery-panel-35)

* [index.html](#index-html-panel-35)

`<!DOCTYPE html>

<head>
    <link rel="stylesheet" href="./pintura.css" />
</head>

<style>
    .pintura-editor {
        height: 600px;
    }
</style>

<div id="editor"></div>

<script type="module">
    import { appendDefaultEditor, createNode } from './pintura.js';

    const editor = appendDefaultEditor('#editor', {
        src: 'image.jpeg',
        cropWillRenderTools: (tools, env) => {
            console.log(tools);
            // logs: [ Array(4), Array(4), Array(4) ]

            console.log(env);
            // logs: { orientation: "landscape", verticalSpace: "short", … }

            // insert your item
            return [
                createNode('div', 'my-div', { textContent: 'Hello world' }),
                ...tools,
            ];
        },
    });
</script>
`

* [App.jsx](#App-jsx-panel-35)
* [App.css](#App-css-panel-35)

`import '@pqina/pintura/pintura.css';
import './App.css';
import { PinturaEditor } from '@pqina/react-pintura';
import { getEditorDefaults, createNode } from '@pqina/pintura';

const editorDefaults = getEditorDefaults();

function App() {
    const cropWillRenderTools = (tools, env) => {
        console.log(tools);
        // logs: [ Array(4), Array(4), Array(4) ]

        console.log(env);
        // logs: { orientation: "landscape", verticalSpace: "short", … }

        // insert your item
        return [
            createNode('div', 'my-div', { textContent: 'Hello world' }),
            ...tools,
        ];
    };

    return (
        <div className="App">
            <PinturaEditor
                {...editorDefaults}
                src={'image.jpeg'}
                cropWillRenderTools={cropWillRenderTools}
            />
        </div>
    );
}

export default App;
`

```css
.pintura-editor {
    height: 600px;
}

```

* [App.vue](#App-vue-panel-35)

`<template>
    <div>
        <PinturaEditor
            v-bind="editorDefaults"
            src="image.jpeg"
            :cropWillRenderTools="cropWillRenderTools"
        />
    </div>
</template>
<script>
import { PinturaEditor } from '@pqina/vue-pintura';
import { getEditorDefaults, createNode } from '@pqina/pintura';

export default {
    name: 'App',

    components: {
        PinturaEditor,
    },

    data() {
        return {
            editorDefaults: getEditorDefaults(),

            cropWillRenderTools: (tools, env) => {
                console.log(tools);
                // logs: [ Array(4), Array(4), Array(4) ]

                console.log(env);
                // logs: { orientation: "landscape", verticalSpace: "short", … }

                // insert your item
                return [
                    createNode('div', 'my-div', { textContent: 'Hello world' }),
                    ...tools,
                ];
            },
        };
    },

    methods: {},
};
</script>
<style>
@import '@pqina/pintura/pintura.css';

.pintura-editor {
    height: 600px;
}
</style>
`

* [App.svelte](#App-svelte-panel-35)

`<script>
    import { PinturaEditor } from '@pqina/svelte-pintura';
    import { getEditorDefaults, createNode } from '@pqina/pintura';
    import '@pqina/pintura/pintura.css';

    let editorDefaults = getEditorDefaults();

    const cropWillRenderTools = (tools, env) => {
        console.log(tools);
        // logs: [ Array(4), Array(4), Array(4) ]

        console.log(env);
        // logs: { orientation: "landscape", verticalSpace: "short", … }

        // insert your item
        return [
            createNode('div', 'my-div', { textContent: 'Hello world' }),
            ...tools,
        ];
    };
</script>

<div>
    <PinturaEditor
        {...editorDefaults}
        src={'image.jpeg'}
        {cropWillRenderTools}
    />
</div>

<style>
    div :global(.pintura-editor) {
        height: 600px;
    }
</style>
`

* [app.component.ts](#app-component-ts-panel-35)
* [app.component.html](#app-component-html-panel-35)
* [app.component.css](#app-component-css-panel-35)
* [app.module.ts](#app-module-ts-panel-35)

`import { Component } from '@angular/core';

import { getEditorDefaults, createNode, PinturaNode } from '@pqina/pintura';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css'],
})
export class AppComponent {
    editorDefaults: any = getEditorDefaults();

    cropWillRenderTools = (tools: PinturaNode[], env: any): PinturaNode[] => {
        console.log(tools);
        // logs: [ Array(4), Array(4), Array(4) ]

        console.log(env);
        // logs: { orientation: "landscape", verticalSpace: "short", … }

        // insert your item
        return [
            createNode('div', 'my-div', { textContent: 'Hello world' }),
            ...tools,
        ];
    };
}
`

`<pintura-editor
    [options]="editorDefaults"
    src="image.jpeg"
    [cropWillRenderTools]="cropWillRenderTools"
></pintura-editor>
`

```css
::ng-deep .pintura-editor {
    height: 600px;
}

```

```javascript
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { AngularPinturaModule } from '@pqina/angular-pintura';

@NgModule({
    declarations: [AppComponent],
    imports: [BrowserModule, AngularPinturaModule],
    exports: [AppComponent],
    providers: [],
    bootstrap: [AppComponent],
})
export class AppModule {}

```

* [index.html](#index-html-panel-35)

`<!DOCTYPE html>
<head>
    <link rel="stylesheet" href="./pintura/pintura.css" />
</head>

<script src="./jquery.js"></script>
<script src="./jquery-pintura/useEditorWithJQuery-iife.js"></script>
<script src="./pintura/pintura-iife.js"></script>

<style>
    .pintura-editor {
        height: 600px;
    }
</style>

<div id="editor"></div>

<script>
    useEditorWithJQuery(jQuery, pintura);

    $(function () {
        var { createNode } = $.fn.pintura;

        var editor = $('#editor').pinturaDefault({
            src: 'image.jpeg',
            cropWillRenderTools: (tools, env) => {
                console.log(tools);
                // logs: [ Array(4), Array(4), Array(4) ]

                console.log(env);
                // logs: { orientation: "landscape", verticalSpace: "short", … }

                // insert your item
                return [
                    createNode('div', 'my-div', { textContent: 'Hello world' }),
                    ...tools,
                ];
            },
        });
    });
</script>
`

## cropEnableButtonFlipHorizontal

Toggle flip horizontal button, defaults to `true`.

## cropEnableButtonFlipVertical

Toggle flip vertical button, defaults to `false`.

## cropEnableButtonRotateLeft

Toggle rotate left button, defaults to `true`.

## cropEnableButtonRotateRight

Toggle Rotate right button, defaults to `false`.

## cropEnableButtonToggleCropLimit

Toggle crop limit button, defaults to `false`.

## cropEnableImageSelection

Enable or disable the crop selection controls, defaults to `true`.

## cropEnableInfoIndicator

Show image size indicator, defaults to `false`.

## cropWillRenderInfoIndicator

Called before rendering the info indicator, receives `crop`, and `size`, should return a string.

* [ ![](/pintura/static/assets/technologies-mono/javascript.svg)JavaScript](#javascript-panel-36)
* [ ![](/pintura/static/assets/technologies-mono/react.svg)React](#react-panel-36)
* [ ![](/pintura/static/assets/technologies-mono/vue.svg)Vue](#vue-panel-36)
* [ ![](/pintura/static/assets/technologies-mono/svelte.svg)Svelte](#svelte-panel-36)
* [ ![](/pintura/static/assets/technologies-mono/angular.svg)Angular](#angular-panel-36)
* [ ![](/pintura/static/assets/technologies-mono/jquery.svg)jQuery](#jquery-panel-36)

* [index.html](#index-html-panel-36)

`<!DOCTYPE html>

<head>
    <link rel="stylesheet" href="./pintura.css" />
</head>

<style>
    .pintura-editor {
        height: 600px;
    }
</style>

<div id="editor"></div>

<script type="module">
    import { appendDefaultEditor } from './pintura.js';

    const editor = appendDefaultEditor('#editor', {
        src: 'image.jpeg',

        // Have to enable info indicator
        cropEnableInfoIndicator: true,

        // Format custom image info
        cropWillRenderInfoIndicator: (crop, size) => {
            // log params
            console.log(crop, size);

            // build string
            return (
                Math.round(crop.width) + ' &times; ' + Math.round(crop.height)
            );
        },
    });
</script>
`

* [App.jsx](#App-jsx-panel-36)
* [App.css](#App-css-panel-36)

`import '@pqina/pintura/pintura.css';
import './App.css';
import { PinturaEditor } from '@pqina/react-pintura';
import { getEditorDefaults } from '@pqina/pintura';

const editorDefaults = getEditorDefaults();

function App() {
    const cropWillRenderInfoIndicator = (crop, size) => {
        // log params
        console.log(crop, size);

        // build string
        return Math.round(crop.width) + ' &times; ' + Math.round(crop.height);
    };

    return (
        <div className="App">
            <PinturaEditor
                {...editorDefaults}
                src={'image.jpeg'}
                // Have to enable info indicator
                cropEnableInfoIndicator={true}
                // Format custom image info
                cropWillRenderInfoIndicator={cropWillRenderInfoIndicator}
            />
        </div>
    );
}

export default App;
`

```css
.pintura-editor {
    height: 600px;
}

```

* [App.vue](#App-vue-panel-36)

`<template>
    <div>
        <PinturaEditor
            v-bind="editorDefaults"
            src="image.jpeg"
            :cropEnableInfoIndicator="true"
            :cropWillRenderInfoIndicator="cropWillRenderInfoIndicator"
        />
    </div>
</template>
<script>
import { PinturaEditor } from '@pqina/vue-pintura';
import { getEditorDefaults } from '@pqina/pintura';

export default {
    name: 'App',

    components: {
        PinturaEditor,
    },

    data() {
        return {
            editorDefaults: getEditorDefaults(),

            // Format custom image info
            cropWillRenderInfoIndicator: (crop, size) => {
                // log params
                console.log(crop, size);

                // build string
                return (
                    Math.round(crop.width) +
                    ' &times; ' +
                    Math.round(crop.height)
                );
            },
        };
    },

    methods: {},
};
</script>
<style>
@import '@pqina/pintura/pintura.css';

.pintura-editor {
    height: 600px;
}
</style>
`

* [App.svelte](#App-svelte-panel-36)

`<script>
    import { PinturaEditor } from '@pqina/svelte-pintura';
    import { getEditorDefaults } from '@pqina/pintura';
    import '@pqina/pintura/pintura.css';

    let editorDefaults = getEditorDefaults();

    const cropWillRenderInfoIndicator = (crop, size) => {
        // log params
        console.log(crop, size);

        // build string
        return Math.round(crop.width) + ' &times; ' + Math.round(crop.height);
    };
</script>

<div>
    <PinturaEditor
        {...editorDefaults}
        src={'image.jpeg'}
        cropEnableInfoIndicator={/* Have to enable info indicator */
        true}
        {cropWillRenderInfoIndicator}
    />
</div>

<style>
    div :global(.pintura-editor) {
        height: 600px;
    }
</style>
`

* [app.component.ts](#app-component-ts-panel-36)
* [app.component.html](#app-component-html-panel-36)
* [app.component.css](#app-component-css-panel-36)
* [app.module.ts](#app-module-ts-panel-36)

`import { Component } from '@angular/core';

import { getEditorDefaults } from '@pqina/pintura';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css'],
})
export class AppComponent {
    editorDefaults: any = getEditorDefaults();

    // Format custom image info
    cropWillRenderInfoIndicator = (crop: Rect, size: Size): string => {
        // log params
        console.log(crop, size);

        // build string
        return Math.round(crop.width) + ' &times; ' + Math.round(crop.height);
    };
}
`

`<pintura-editor
    [options]="editorDefaults"
    src="image.jpeg"
    [cropEnableInfoIndicator]="true"
    [cropWillRenderInfoIndicator]="cropWillRenderInfoIndicator"
></pintura-editor>
`

```css
::ng-deep .pintura-editor {
    height: 600px;
}

```

```javascript
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { AngularPinturaModule } from '@pqina/angular-pintura';

@NgModule({
    declarations: [AppComponent],
    imports: [BrowserModule, AngularPinturaModule],
    exports: [AppComponent],
    providers: [],
    bootstrap: [AppComponent],
})
export class AppModule {}

```

* [index.html](#index-html-panel-36)

`<!DOCTYPE html>
<head>
    <link rel="stylesheet" href="./pintura/pintura.css" />
</head>

<script src="./jquery.js"></script>
<script src="./jquery-pintura/useEditorWithJQuery-iife.js"></script>
<script src="./pintura/pintura-iife.js"></script>

<style>
    .pintura-editor {
        height: 600px;
    }
</style>

<div id="editor"></div>

<script>
    useEditorWithJQuery(jQuery, pintura);

    $(function () {
        var editor = $('#editor').pinturaDefault({
            src: 'image.jpeg',

            // Have to enable info indicator
            cropEnableInfoIndicator: true,

            // Format custom image info
            cropWillRenderInfoIndicator: (crop, size) => {
                // log params
                console.log(crop, size);

                // build string
                return (
                    Math.round(crop.width) +
                    ' &times; ' +
                    Math.round(crop.height)
                );
            },
        });
    });
</script>
`

## cropEnableLimitWheelInputToCropSelection

Only captures mouse wheel interactions when the mouse is inside the crop selection, defaults to `true`.

## cropEnableRotationInput

Toggle the image rotation input on and off, defaults to `true`.

## cropEnableSelectPreset

If crop presets have been defined this will show the preset dropdown in the toolbar, defaults to `true`.

## cropEnableZoom

Enable generic zooming of the image. If set to `false` all zoom related input will be disabled. Defaults to `true`.

## cropEnableZoomInput

Enable the zoom input control at the bottom of the crop tool. This control will automatically hide if there's not enough vertical space. Defaults to `true`.

## cropEnableZoomAutoHide

When set to true the zoom control is automatically hidden to preserve space in layouts with low vertical space. Defaults to `true`.

## cropActiveTransformTool

Set to `'zoom'` to activate the zoom tool instead of the rotation tool. Defaults to `'rotation'`.

## cropEnableZoomMatchImageAspectRatio

Will automatically adjust the crop aspect ratio when zooming out, only works if aspect ratio is set to `undefined`. Defaults to `true`.

## cropEnableRotateMatchImageAspectRatio

When set to `'always'` or `'custom'` this will automatically rotate the crop rectangle with the image is the crop rectangle is fully zoomed out and centered.

| Value    | Description                                                                                                                                                         |
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 'never'  | Don't rotate the crop when the image is rotated.                                                                                                                    |
| 'custom' | Only rotate the crop with the image if the crop aspect ratio is set to custom imageCropAspectRatio === undefined                                                    |
| 'always' | Rotate the crop rectangle with the image if the crop aspect ratio is custom or a rotated crop aspect ratio can be found in the preset list. For example 4:3 to 3:4. |

In this example the crop will automatically switch between `4:3` and `3:4` when the image is rotated while fully zoomed out.

* [ ![](/pintura/static/assets/technologies-mono/javascript.svg)JavaScript](#javascript-panel-40)
* [ ![](/pintura/static/assets/technologies-mono/react.svg)React](#react-panel-40)
* [ ![](/pintura/static/assets/technologies-mono/vue.svg)Vue](#vue-panel-40)
* [ ![](/pintura/static/assets/technologies-mono/svelte.svg)Svelte](#svelte-panel-40)
* [ ![](/pintura/static/assets/technologies-mono/angular.svg)Angular](#angular-panel-40)
* [ ![](/pintura/static/assets/technologies-mono/jquery.svg)jQuery](#jquery-panel-40)

* [index.html](#index-html-panel-40)

`<!DOCTYPE html>

<head>
    <link rel="stylesheet" href="./pintura.css" />
</head>

<style>
    .pintura-editor {
        height: 600px;
    }
</style>

<div id="editor"></div>

<script type="module">
    import { appendDefaultEditor } from './pintura.js';

    const editor = appendDefaultEditor('#editor', {
        src: 'image.jpeg',
        cropEnableRotateMatchImageAspectRatio: 'always',
        cropSelectPresetOptions: [
            [undefined, 'Custom'],
            [1, 'Square'],
            [4 / 3, 'Landscape'],
            [3 / 4, 'Portrait'],
        ],
    });
</script>
`

* [App.jsx](#App-jsx-panel-40)
* [App.css](#App-css-panel-40)

`import '@pqina/pintura/pintura.css';
import './App.css';
import { PinturaEditor } from '@pqina/react-pintura';
import { getEditorDefaults } from '@pqina/pintura';

const editorDefaults = getEditorDefaults();

function App() {
    return (
        <div className="App">
            <PinturaEditor
                {...editorDefaults}
                src={'image.jpeg'}
                cropEnableRotateMatchImageAspectRatio={'always'}
                cropSelectPresetOptions={[
                    [undefined, 'Custom'],
                    [1, 'Square'],
                    [4 / 3, 'Landscape'],
                    [3 / 4, 'Portrait'],
                ]}
            />
        </div>
    );
}

export default App;
`

```css
.pintura-editor {
    height: 600px;
}

```

* [App.vue](#App-vue-panel-40)

`<template>
    <div>
        <PinturaEditor
            v-bind="editorDefaults"
            src="image.jpeg"
            cropEnableRotateMatchImageAspectRatio="always"
            :cropSelectPresetOptions="cropSelectPresetOptions"
        />
    </div>
</template>
<script>
import { PinturaEditor } from '@pqina/vue-pintura';
import { getEditorDefaults } from '@pqina/pintura';

export default {
    name: 'App',

    components: {
        PinturaEditor,
    },

    data() {
        return {
            editorDefaults: getEditorDefaults(),

            cropSelectPresetOptions: [
                [undefined, 'Custom'],
                [1, 'Square'],
                [4 / 3, 'Landscape'],
                [3 / 4, 'Portrait'],
            ],
        };
    },

    methods: {},
};
</script>
<style>
@import '@pqina/pintura/pintura.css';

.pintura-editor {
    height: 600px;
}
</style>
`

* [App.svelte](#App-svelte-panel-40)

`<script>
    import { PinturaEditor } from '@pqina/svelte-pintura';
    import { getEditorDefaults } from '@pqina/pintura';
    import '@pqina/pintura/pintura.css';

    let editorDefaults = getEditorDefaults();
</script>

<div>
    <PinturaEditor
        {...editorDefaults}
        src={'image.jpeg'}
        cropEnableRotateMatchImageAspectRatio={'always'}
        cropSelectPresetOptions={[
            [undefined, 'Custom'],
            [1, 'Square'],
            [4 / 3, 'Landscape'],
            [3 / 4, 'Portrait'],
        ]}
    />
</div>

<style>
    div :global(.pintura-editor) {
        height: 600px;
    }
</style>
`

* [app.component.ts](#app-component-ts-panel-40)
* [app.component.html](#app-component-html-panel-40)
* [app.component.css](#app-component-css-panel-40)
* [app.module.ts](#app-module-ts-panel-40)

```javascript
import { Component } from '@angular/core';

import { getEditorDefaults } from '@pqina/pintura';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css'],
})
export class AppComponent {
    editorDefaults: any = getEditorDefaults();

    cropSelectPresetOptions: any = [
        [undefined, 'Custom'],
        [1, 'Square'],
        [4 / 3, 'Landscape'],
        [3 / 4, 'Portrait'],
    ];
}

```

`<pintura-editor
    [options]="editorDefaults"
    src="image.jpeg"
    cropEnableRotateMatchImageAspectRatio="always"
    [cropSelectPresetOptions]="cropSelectPresetOptions"
></pintura-editor>
`

```css
::ng-deep .pintura-editor {
    height: 600px;
}

```

```javascript
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { AngularPinturaModule } from '@pqina/angular-pintura';

@NgModule({
    declarations: [AppComponent],
    imports: [BrowserModule, AngularPinturaModule],
    exports: [AppComponent],
    providers: [],
    bootstrap: [AppComponent],
})
export class AppModule {}

```

* [index.html](#index-html-panel-40)

`<!DOCTYPE html>
<head>
    <link rel="stylesheet" href="./pintura/pintura.css" />
</head>

<script src="./jquery.js"></script>
<script src="./jquery-pintura/useEditorWithJQuery-iife.js"></script>
<script src="./pintura/pintura-iife.js"></script>

<style>
    .pintura-editor {
        height: 600px;
    }
</style>

<div id="editor"></div>

<script>
    useEditorWithJQuery(jQuery, pintura);

    $(function () {
        var editor = $('#editor').pinturaDefault({
            src: 'image.jpeg',
            cropEnableRotateMatchImageAspectRatio: 'always',
            cropSelectPresetOptions: [
                [undefined, 'Custom'],
                [1, 'Square'],
                [4 / 3, 'Landscape'],
                [3 / 4, 'Portrait'],
            ],
        });
    });
</script>
`

## cropInteractionFocus

The focus of interaction. Defaults to `'image'` meaning the user moves the image and not the crop selection.

Change to `'selection'` to lock the image in place and allow the user to move the crop selection instead of the image.

## cropRotationRange

The negative and positive range the rotation control can move. The default value `Math.PI / 4` results in a range from `-Math.PI / 4` to `Math.PI / 4`.

## Crop plugin exports

The core editor module exports the following Crop plugin objects.

| Export                       | Description            |
| ---------------------------- | ---------------------- |
| plugin\_crop                 | The crop util view.    |
| plugin\_crop\_locale\_en\_gb | The crop util locales. |