1

I'm building a Lightning Component which has an canvas. I'm trying to draw an image in canvas from an url using javascript. But I'm getting below error:

This page has an error. You might just need to refresh it.

Error in $A.getCallback() [Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The provided value is not of type '(CSSImageValue or HTMLImageElement or SVGImageElement or HTMLVideoElement or HTMLCanvasElement or ImageBitmap or OffscreenCanvas)'] Failing descriptor: {markup://c:CanvasApp}

CanvasApp :

<aura:application extends="force:slds">

    <aura:attribute name="Question" type="Map" access="public" default='{"Id" : "a0R7F000000dCcD", 
                                                                        "Hotspot_Image_Properties__c" : {"area":[{"shape":"circle","$$hashKey":"object:6","coords":"112.5,107,43.60","areaValue":"face"}],"questionImageId":"00P7F000000VNW4","imageWidth":240,"imageHeight":320}}'/>

    <c:HotspotImage question="{!v.Question}"/>

</aura:application>

HotspotImage.cmp

<aura:component >
    <aura:attribute name="question" type="Map" access="public"/>
    <div class="slds-size--1-of-1 slds-grid slds-hide" aura:id="isCanvasRender">

        <div class="slds-size--1-of-3 slds-m-around--x-small">
            <canvas aura:id="imageCanvas" width="{!v.hotspotImgProp.imageWidth}" height="{!v.hotspotImgProp.imageHeight}"/>
        </div>
    </div>
</aura:component>

HotspotImageRenderer.js

({
    afterRender: function (cmp, helper) {
        this.superAfterRender();
        var canvas = cmp.find("imageCanvas").getElement();
        var ctx = canvas.getContext("2d");

        if(cmp.isValid()){
            var question = cmp.get("v.question");
            if(question.Id){
                var hotspotImgProp = JSON.parse(JSON.stringify(question.Hotspot_Image_Properties__c));
                var attachmentId = hotspotImgProp.questionImageId;
                if(attachmentId){
                    helper.showCanvas(cmp);
                    var image = new Image();
                    image.src = "/servlet/servlet.FileDownload?file="+attachmentId;

                    image.onload = $A.getCallback(function(){
                        window.setTimeout($A.getCallback(function(){
                            if(cmp.isValid()){
                                helper.drawShape(cmp, ctx, image, helper);
                            }
                        }), 0);
                    });
                }
            }
        }
    }


})

HotspotImageHelper.js

({
    showCanvas : function(cmp){
        var isCanvasRender = cmp.find("isCanvasRender");
        if($A.util.hasClass(isCanvasRender, "slds-hide")){
            $A.util.removeClass(isCanvasRender,"slds-hide");
        }
    },

    drawShape : function(cmp, ctx, img, helper){        
        ctx.clearRect(0, 0, 240, 320);
        ctx.stroke();
        ctx.beginPath();
        ctx.drawImage(img, 0, 0, 240, 320);
        ctx.stroke();
    }
})
2
  • decrease your component api version to 39
    – Himanshu
    Commented Sep 22, 2017 at 12:20
  • @Himanshu this app will be sent for security review, So it should be in api version 40
    – karthik
    Commented Sep 25, 2017 at 11:51

1 Answer 1

2

You have to give time to load the image before drawing it.add window.setTimout() function .

({
    afterRender :  function(cmp, helper){
        this.superAfterRender();
        if(cmp.isValid()){
            var imageSrc = 'https://www.google.com/images/branding/googlelogo/1x/googlelogo_white_background_color_272x92dp.png';
            var canvas = cmp.find("imageCanvas").getElement();
            var ctx = canvas.getContext('2d');
            var image = new Image();
            image.src = imageSrc;
            image.onload = $A.getCallback(function() {
               window.setTimeout($A.getCallback(function(){
                    ctx.drawImage(image, 0, 0, 200, 300)
               },500));
            });    
        }
    }
})

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .