Search code examples
javascripthtmldomcanvashtml5-canvas

How to make Canvas set image and text overlay in JavaScript?


I am trying to make a Congratulation Card Website where you put your name and then put it into an image all that by JavaScript.

I couldn't render the image with the name. It is just the image in the inspection the SCR is the original image which is supposed to be data:image

I try var dataURL = canvas.toDataURL(); but I believe I didn't use it correctly because it only showed the text without the image but is shown in the inspection the SCR is data:image

HTML

 <div class="d-flex justify-content-center m-5">
        <div class="">
            <div id="img"></div>

            <div class="card p-3" id="form">
                <h1 class="text-center">Make Your Card for Eid</h1>
                <div>
                    <!-- <form action=""> -->
                    <div class="form-group m-3">
                        <label for="name">Write Your Name:<span class="text-danger">*</span></label>
                        <input type="text" class="form-control" id="name" name="name" required>
                    </div>
                    <div class="form-group m-3">
                        <label for="exampleFormControlInput1">Choice Your Card:<span
                                class="text-danger">*</span></label>
                        <div class="form-check m-3">
                            <input class="form-check-input" type="radio" name="Cards" id="exampleRadios1"
                                value="Congratulation-1" required>
                            <label class="form-check-label" for="exampleRadios1">
                                <img src="Congratulation-1.png" alt="" id="Congratulation-1" class="cards">
                            </label>
                        </div>
                        <div class="form-check m-3">
                            <input class="form-check-input" type="radio" name="Cards" id="exampleRadios2"
                                value="Congratulation-2">
                            <label class="form-check-label" for="exampleRadios2">
                                <img src="Congratulation-2.png" alt="" id="Congratulation-2" class="cards">
                            </label>
                        </div>
                        <div class="form-check m-3">
                            <input class="form-check-input" type="radio" name="Cards" id="exampleRadios3"
                                value="Congratulation-3">
                            <label class="form-check-label" for="exampleRadios3">
                                <img src="Congratulation-3.png" alt="" id="Congratulation-3" class="cards">
                            </label>
                        </div>
                        <div class="form-check m-3">
                            <input class="form-check-input" type="radio" name="Cards" id="exampleRadios4"
                                value="Congratulation-4">
                            <label class="form-check-label" for="exampleRadios4">
                                <img src="Congratulation-4.png" alt="" id="Congratulation-4" class="cards">
                            </label>
                        </div>
                    </div>
                    <div class="form-group m-3">
                        <button type="submit" class="form-control btn-sda" id="make-card"
                            onclick="myFunction()">Submit</button>
                    </div>
                    <!-- </form> -->
                </div>
            </div>
        </div>
    </div>

Javascript

function myFunction() {
    var name = document.getElementById("name").value
    var cards = document.getElementsByName("Cards");
    var card

    for (var i = 0; i < cards.length; i++) {
        if (cards[i].checked) {
            alert(cards[i].value);
            card = cards[i].value
            break;
        }
    }

    var img = document.getElementById(card);
    img.setAttribute('crossorigin', 'anonymous'); // works for me 

    var name = document.getElementById("name").value

    var canvas = document.createElement('canvas');
    canvas.setAttribute('width', '900');
    canvas.setAttribute('height', '700');

    var imgFinal = new Image();

    imgFinal.src = card + ".png";

    imgFinal.className = "my-5";
    var context = canvas.getContext('2d');
    context.strokeRect(0, 0, canvas.width, canvas.height);

    
    context.drawImage(imgFinal, 0, 0);
    context.fillStyle = "#fff";
    context.font = "bold 30px serif";
    context.textAlign = "center";
    context.fillText(name, canvas.width / 2, 550);
    
    var container = document.getElementById("img")
    container.parentNode.insertBefore(imgFinal, container.nextSibling);

    img.removeAttribute("crossorigin"); // works for me
    var form = document.getElementById("form")
    form.remove()

}

Solution

  • You should use drawImage() method and fillText() method inside image.onload event. image.onload is asynchronous, So image.src must be outside of the event scope.

    Be sure to use Web Servers like Xampp or Wampp. Cause it will avoid Cross Origin Issues.

    Here is the working code :

    <div class="d-flex justify-content-center m-5">
        <div class="">
            <div id="img"></div>
            <div class="card p-3" id="form">
                <h1 class="text-center">Make Your Card for Eid</h1>
                <div>
                    <!-- <form action=""> -->
                    <div class="form-group m-3">
                        <label for="name">Write Your Name:<span class="text-danger">*</span></label>
                        <input type="text" class="form-control" id="name" name="name" required>
                    </div>
                    <div class="form-group m-3">
                        <label for="exampleFormControlInput1">Choice Your Card:<span class="text-danger">*</span></label>
                        <div class="form-check m-3">
                            <input class="form-check-input" type="radio" name="Cards" id="exampleRadios1" value="Congratulation-1" required>
                            <label class="form-check-label" for="exampleRadios1">
                                <img src="Congratulation-1.png" alt="" id="Congratulation-1" class="cards">
                            </label>
                        </div>
                        <div class="form-check m-3">
                            <input class="form-check-input" type="radio" name="Cards" id="exampleRadios2" value="Congratulation-2">
                            <label class="form-check-label" for="exampleRadios2">
                                <img src="Congratulation-2.png" alt="" id="Congratulation-2" class="cards">
                            </label>
                        </div>
                        <div class="form-check m-3">
                            <input class="form-check-input" type="radio" name="Cards" id="exampleRadios3" value="Congratulation-3">
                            <label class="form-check-label" for="exampleRadios3">
                                <img src="Congratulation-3.png" alt="" id="Congratulation-3" class="cards">
                            </label>
                        </div>
                        <div class="form-check m-3">
                            <input class="form-check-input" type="radio" name="Cards" id="exampleRadios4" value="Congratulation-4">
                            <label class="form-check-label" for="exampleRadios4">
                                <img src="Congratulation-4.png" alt="" id="Congratulation-4" class="cards">
                            </label>
                        </div>
                    </div>
                    <div class="form-group m-3">
                        <button type="submit" class="form-control btn-sda" id="make-card" onclick="myFunction()">Submit</button>
                    </div>
                    <!-- </form> -->
                </div>
            </div>
        </div>
    </div>
    <script>
    function myFunction() {
        let name = document.getElementById("name").value
        let cards = document.getElementsByName("Cards");
        let card;
    
        for (let i = 0; i < cards.length; i++) {
            if (cards[i].checked) {
                alert(cards[i].value);
                card = cards[i].value;
                break;
            }
        }
    
        let img = document.getElementById(card);
        // img.setAttribute('crossorigin', 'anonymous'); // works for me
    
        let canvas = document.createElement('canvas');
        let context = canvas.getContext('2d');
        canvas.setAttribute('width', '900');
        canvas.setAttribute('height', '700');
    
        let imgFinal = new Image();
        imgFinal.className = "my-5";
        imgFinal.crossOrigin = "anonymous";
    
        context.strokeRect(0, 0, canvas.width, canvas.height);
    
        imgFinal.onload = function() {
            context.drawImage(imgFinal, 0, 0);
    
            context.font = "3em sans-serif";
            context.fillStyle = "#fff";
            context.textAlign = "center";
            context.fillText(name, canvas.width / 2, canvas.height / 2);
    
            let newImage = new Image();
            let imgURL = canvas.toDataURL();
            newImage.src = imgURL;
    
            let container = document.getElementById("img");
            container.parentNode.insertBefore(newImage, container.nextSibling);
        }
        imgFinal.src = `${card}.png`;
    
        // img.removeAttribute("crossorigin"); // works for me
        let form = document.getElementById("form");
        form.remove();
    }
    </script>