score:0

interesting question. here is a working example: (it wont download in online sandbox, but works fine on independent branches e.g. localhost, see console messages) sandbox

import react, { useref, useeffect, usestate } from "react";

const crop = function(){
    const canvas = useref();
    const file = useref();
    
    const preview = useref();
    const [imageparams, setimageparams] = usestate();
    const [context, setcontext] = usestate();


    // initialize
    useeffect(function(){

        file.current.onchange = onnewimage;
        setcontext( canvas.current.getcontext('2d') );

    },[])

    // draw image on imageparams change
    useeffect(function(){
        if(!imageparams) return;
        
        context.drawimage( preview.current, 0, 0, imageparams.width*(700/imageparams.height), 700 )
        
    }, [imageparams])

    // get with and height, replace preview, set params
    function onnewimage(){
        const newimgurl = url.createobjecturl( file.current.files[0] );
        const newimage = document.createelement('img');

        newimage.setattribute('src', newimgurl);

        newimage.onload = function(){
            const {width, height} = newimage;
            const type = file.current.files[0].type

            newimage.setattribute('width', '50px');

            preview.current.parentelement.append(newimage);
            preview.current.remove();

            preview.current = newimage;

            setimageparams({ width, height, type });
        }
    }

    // save image on click
    function handlesave(){

        canvas.current.toblob(function(blob){
            
            const anchor = document.createelement('a');

            anchor.innerhtml = 'download';

            anchor.download = "my_file."+imageparams.type.replace(/^.{1,}\//,'');

            anchor.href = (window.webkiturl || window.url).createobjecturl(blob);
            anchor.dataset.downloadurl = [imageparams.type, anchor.download, anchor.href].join(':');
            anchor.click();

            preview.current.parentelement.append(anchor);

        }, imageparams.type);

    }

    return <>
        <div classname="input">
            
            <input 
                ref={file}
                type="file"
                accept="image/png, image/jpeg" />

            <div
                style={{width:"100px", display: 'inline-block'}}>
                <img
                    
                    ref={preview}
                    />
            </div>
            

            <button 
                onclick={handlesave} >save image</button>

        </div>

        <div class="canvas">
            <canvas 
                ref={canvas}
                width='700px'
                height='700px' />
        </div>  

    </>;
}

export default crop;

Related Query

More Query from same tag