GetmeUK / ContentTools

A JS library for building WYSIWYG editors for HTML content.
http://getcontenttools.com
MIT License
3.95k stars 395 forks source link

cropRegion is not giving Correct Or Updated Data #440

Closed rohitcoder closed 6 years ago

rohitcoder commented 6 years ago

I tried lots of Combinations and Methods even i tried to console.info(cropRegion) data at every 4 seconds so that i can get update result while cropping but still its not giving correct output for crop selected region.

anthonyjb commented 6 years ago

Crop region provides the following information (top, left, bottom, right), values are normalized to the range 0.0 - 1.0 as per the code here:(https://github.com/GetmeUK/ContentTools/blob/master/src/scripts/ui/dialogs/image.coffee#L409)

If you're getting an unexpected response provide an example of you code, the output your seeing, etc please.

rohitcoder commented 6 years ago

After Selecting Crop area whenever am pressing enter am getting this error in my console

image

image

anthonyjb commented 6 years ago

My guess is that this is because the 'enter' is triggering a different event than intended (it seems to be attempting to create a paragraph based on the fact a paragraph is currently selected). Do you get the same issue if you click the insert button?

rohitcoder commented 6 years ago

After Selecting Crop Area and pressing insert button its not showing any error in console but it also not cropping images in final preview (after insert)

anthonyjb commented 6 years ago

the cropping of the image must be implemented on the server side (or by you on the client side) it's not something CT handles.

rohitcoder commented 6 years ago

I can do that in server side only after getting Correct Crop Output Right Now whenever am trying to get Current Crop data it always giving me this as output [0, 0, 1, 1] So, can you suggest me final way. how can i get updated crop details so that i can crop it on server side.

anthonyjb commented 6 years ago

I think you'll need to post your image handler code, I recently implement 2 different image handlers (one for cloudinary and one for an internal tool hanager51) and I've not had this issue so I can't repeat my end to track it down.

rohitcoder commented 6 years ago

138 to 176 Lines are edited by me (Rotate Functions because this was also not working with crop feature) but i managed it but now only crop is not working. This is my JS Code : https://pastebin.com/WRDG892r Flow of Image is something like this

User Selects Image > Image is transferred to internal_process.php > this php file upload imgae to cloudinary and then it returns back the file url to CT.

anthonyjb commented 6 years ago

OK I can't see a call to get the cropRegion anywhere in your code? Here's an example of a recent ImageUploader script I'm using on an internal project which might help you better see what's going on and where you need to get/perform your crop:

ContentTools = require 'ContentTools'

class ImageUploader
    # An image uploader class for manhattan

    constructor: (dialog, baseParams={}) ->
        # A reference to the UI dialog being used to upload an image
        @dialog = dialog

        # A table of params to include when uploading or transforming images
        @baseParams = baseParams

        # Check if the image upload is for an image fixture and if so extract
        # any transform stack.
        @postTransforms = []
        @element = ContentEdit.Root.get().focused()
        if @element.type() is 'ImageFixture'
            @postTransforms = JSON.parse(
                @element.domElement().getAttribute('data-transforms') or '[]'
            )

        # Listen to and map events from the dialog to handlers
        dialog.addEventListener 'imageuploader.cancelupload', () =>
            @onCancelUpload()

        dialog.addEventListener 'imageuploader.clear', () =>
            @onClear()

        dialog.addEventListener 'imageuploader.clear', () =>
            @onClear()

        dialog.addEventListener 'imageuploader.fileready', (ev) =>
            if ev.detail().file
                @onFileReady(ev.detail().file)

        dialog.addEventListener 'imageuploader.rotateccw', (ev) =>
            @onRotate(-90)

        dialog.addEventListener 'imageuploader.rotatecw', (ev) =>
            @onRotate(90)

        dialog.addEventListener 'imageuploader.save', () =>
            @onSave()

    # Methods

    getTransformURL: () ->
        # Return the transform URL
        return '/manage/transform-asset'

    getUploadURL: () ->
        # Return the upload URL
        return '/manage/upload-asset'

    transform: (transforms, callback) ->
        # Transform the image

        # Build the form data to transform the image
        formData = new FormData()
        for k, v of @baseParams
            formData.append(k, v)
        formData.append('key', @image.key)
        formData.append('transforms', JSON.stringify(transforms))

        # Build a request to send the file
        xhr = new XMLHttpRequest()
        xhr.open('POST', @getTransformURL(), true)

        xhr.addEventListener 'load', (ev) =>
            if parseInt(ev.target.status) is 200
                # Handle successful upload

                # Unpack the repsonse
                response = JSON.parse(ev.target.responseText)

                # Trigger the callback
                callback(response.payload.asset)

            else
                # Handle failed upload
                new ContentTools.FlashUI('no')

            # Clear the XHR
            @xhr = null

        # Transform the image
        xhr.send(formData)

    # Dialog event handlers

    onCancelUpload: () ->
        # Handle a request to cancel an upload

        # Stop any current upload
        if @xhr
            @xhr.upload.removeEventListener('progress', @xhrProgress)
            @xhr.upload.removeEventListener('load', @xhrComplete)
            @xhr.abort()

        # Set the dialog to empty
        @dialog.state('empty')

    onClear: () ->
        # Handle a request to clear the image
        @dialog.clear()
        @image = null

    onFileReady: (file) ->
        # Handle a request to upload a file

        # Set the dialog state to uploading
        @dialog.progress(0)
        @dialog.state('uploading')

        # Build the form data to upload the image
        formData = new FormData()
        for k, v of @baseParams
            formData.append(k, v)
        formData.append('file', file)

        # Build a request to send the file
        @xhr = new XMLHttpRequest()
        @xhr.open('POST', @getUploadURL(), true)

        # Add handlers for progress and load

        @xhrProgress = (ev) =>
            # Update the progress bar
            @dialog.progress((ev.loaded / ev.total) * 100)

        @xhr.upload.addEventListener('progress', @xhrProgress)

        @xhrComplete = (ev) =>
            if parseInt(ev.target.status) is 200
                # Handle successful upload

                # Unpack the repsonse
                response = JSON.parse(ev.target.responseText)
                asset = response.payload.asset

                # Make sure an image was uploaded
                if asset['type']

                    # Build the image from the resposne
                    @image = {
                        angle: 0,
                        height: asset['core_meta']['image']['size'][1],
                        key: asset['key'],
                        maxWidth: asset['core_meta']['image']['size'][0],
                        url: asset['variations']['--draft--']['url'],
                        width: asset['core_meta']['image']['size'][0]
                    }

                    # Update the dialog to display the new image
                    @dialog.populate(@image.url, [@image.width, @image.height])

                else
                    # Handle upload of non-image
                    new ContentTools.FlashUI('no')

            else
                # Handle failed upload
                new ContentTools.FlashUI('no')

            # Clear the XHR
            @xhr = null

        @xhr.addEventListener('load', @xhrComplete)

        # Upload the file
        @xhr.send(formData)

    onRotate: (angle) ->
        # Handle a request to rotate the image

        # Update the angle of the image
        @image.angle += angle

        # Stay within 360 degress
        if @image.angle < 0
            @image.angle += 360
        else if @image.angle > 270
            @image.angle -= 360

        # Build the transform
        transforms = [
            {'id': 'image.rotate', 'settings': {'angle': @image.angle}}
        ]

        # Perfom the transform
        @transform transforms, (asset) =>
            # Update the image from the resposne
            @image.url = asset['variations']['--draft--']['url']

            # Flip the image width/height based on the angle
            if @image.angle is 90 or @image.angle = 270
                @image.height = asset['core_meta']['image']['size'][0]
                @image.maxWidth = asset['core_meta']['image']['size'][1]
                @image.width = width = asset['core_meta']['image']['size'][1]
            else
                @image.height = asset['core_meta']['image']['size'][1]
                @image.maxWidth = asset['core_meta']['image']['size'][0]
                @image.width = width = asset['core_meta']['image']['size'][0]

            # Update the dialog to display the new image
            @dialog.populate(@image.url, [@image.width, @image.height])

    onSave: () ->
        # Handle a request to save the image

        # Build the transforms for the final image
        transforms = []

        # Angle
        unless @image.angle is 0
            transforms.push({
                'id': 'image.rotate',
                'settings': {'angle': @image.angle}
            })

        # Crop
        region = @dialog.cropRegion()
        maxWidth = @image.maxWidth
        unless region.toString() is [0, 0, 1, 1].toString()
            transforms.push({
                'id': 'image.crop',
                'settings': {
                    'top': Math.max(0, region[0]),
                    'left': Math.max(0, region[1]),
                    'bottom': Math.min(1, region[2]),
                    'right': Math.min(1, region[3])
                }
            })
            maxWidth = parseInt(maxWidth * (region[3] - region[1]))

        # Apply any post transforms
        transforms = transforms.concat(@postTransforms)

        # Perform the transform
        @transform transforms, (asset) =>
            # Insert the image into the page
            draft = asset['variations']['--draft--']
            @dialog.save(
                draft['url'],
                [
                    draft['core_meta']['image']['size'][0],
                    draft['core_meta']['image']['size'][1]
                ],
                {
                    'alt': '',
                    'data-ce-max-width': maxWidth,
                    'data-mh-asset-key': asset['key']
                }
            )

            # For image fixtures the attributes must be set independently
            if @element.type() is 'ImageFixture'
                @element.attr('data-mh-asset-key', asset['key'])
                unless @element.attr('alt')
                    @element.attr('alt', '')

module.exports = {ImageUploader: ImageUploader}