10

I am working with canvas, right now I can save into DB and I can change the background image to one I choose of a image list.

My problem is when I tried to save the canvas with the background the saved image just show me the draw but doesn't the image background...can somebody help me with this?

Best Regards!

Here the code:

    <script src="js/drawingboard.min.js"></script>
    <script data-example="1">
        var defaultBoard = new DrawingBoard.Board("default-board", {
            background: "#ffff",
            droppable: true,
            webStorage: false,
            enlargeYourContainer: true,
            addToBoard: true,
            stretchImg: false
        });
        defaultBoard.addControl("Download");
        $(".drawing-form").on("submit", function(e) {
            var img = defaultBoard.getImg();
            var imgInput = (defaultBoard.blankCanvas == img) ? "" : img;
            $(this).find("input[name=image]").val( imgInput );
            defaultBoard.clearWebStorage();
        });
        $(function() {
            $("#file-input").change(function(e) {
                var file = e.target.files[0],
                imageType = /image.*/;
                if (!file.type.match(imageType))
                return;
                var reader = new FileReader();
                reader.onload = fileOnload;
                reader.readAsDataURL(file);        
            });
            function fileOnload(e) {
                var $img = $("<img>", { src: e.target.result });
                var canvas = $("#default-board")[0];
                var context = canvas.getContext("2d");
                $img.load(function() {
                    context.drawImage(this, 0, 0);
                });
            }
        });
    </script>
    <script src="js/yepnope.js"></script>
    <script>
        var iHasRangeInput = function() {
            var inputElem  = document.createElement("input"),
                smile = ":)",
                docElement = document.documentElement,
                inputElemType = "range",
                available;
            inputElem.setAttribute("type", inputElemType);
            available = inputElem.type !== "text";
            inputElem.value         = smile;
            inputElem.style.cssText = "position:absolute;visibility:hidden;";
            if ( /^range$/.test(inputElemType) && inputElem.style.WebkitAppearance !== undefined ) {
                docElement.appendChild(inputElem);
                defaultView = document.defaultView;
                available = defaultView.getComputedStyle &&
                    defaultView.getComputedStyle(inputElem, null).WebkitAppearance !== "textfield" &&
                    (inputElem.offsetHeight !== 0);
                docElement.removeChild(inputElem);
            }
            return !!available;
        };

        yepnope({
            test : iHasRangeInput(),
            nope : ["css/fd-slider.min.css", "js/fd-slider.min.js"],
            callback: function(id, testResult) {
                if("fdSlider" in window && typeof (fdSlider.onDomReady) != "undefined") {
                    try { fdSlider.onDomReady(); } catch(err) {}
                }
            }
        });
// with this code I can change the background
            $(document).ready(function () {
                $("#cambiocanvas > input").click(function () {
                    var img = $(this).attr("src");
                    $(".drawing-board-canvas").css("background", "url(" + img + ")");
                });
            });
        </script>

Here the form with the images:

<div class="tab-pane" id="derm">
    <div class="row-fluid sortable">
        <div class="box span3">
            <section id="cambiocanvas">
                <input id="yellowcanvas" class="canvasborder" type="image" src="http://2.imimg.com/data2/MB/BH/MY-651900/23-250x250.jpg">
                <input id="bluecanvas" class="canvasborder" type="image" src="http://jsfiddle.net/img/logo.png">
                <input id="greencanvas" class="canvasborder" type="image" src="https://www.gravatar.com/avatar/86364f16634c5ecbb25bea33dd9819da?s=128&d=identicon&r=PG&f=1">
            </section>
        </div>
    <div class="box span9">
    <div class="box-header well" data-original-title>
        <h2><i class="icon-tasks"></i> </h2>
        <div class="box-icon">
            <a href="#" class="btn btn-minimize btn-round"><i class="icon-chevron-up"></i></a>
            <a href="#" class="btn btn-close btn-round"><i class="icon-remove"></i></a>
        </div>
    </div>
    <div class="box-content">
        <div id="container">
            <div class="example" data-example="1">
                <div class="board" id="default-board"></div>
            </div>
            <form class="drawing-form" method="post" name="diagram" id="diagram" enctype="multipart/form-data">
                <div id="board"></div>
                <input type="hidden" name="image" value="">
                <input type="hidden" name="id_user" value="<?php echo $id" />
<br><hr>
                <button class="btn btn-info" id="btnUpload">Save</button>
            </form>
            <div id="ldiag" style="display:none;"><img src="images/loading4.gif" /></div>
            <div class="progress1"></div>
            <div id="diaga"></div>
        </div>
    </div>
</div>

CODE EDITED

Here the code:

<script src="js/drawingboard.min.js"></script>
<script data-example="1">
    var defaultBoard = new DrawingBoard.Board("default-board", {
        background: "#ffff",
        droppable: true,
        webStorage: false,
        enlargeYourContainer: true,
        addToBoard: true,
        stretchImg: false
    });
    defaultBoard.addControl("Download");
    $(".drawing-form").on("submit", function(e) {
        var img = defaultBoard.getImg();
        var imgInput = (defaultBoard.blankCanvas == img) ? "" : img;
        $(this).find("input[name=image]").val( imgInput );
        defaultBoard.clearWebStorage();
    });
$(function() {
    $("#file-input").change(function(e) {
        var file = e.target.files[0],
        imageType = /image.*/;
        if (!file.type.match(imageType))
        return;
        var reader = new FileReader();
        reader.onload = fileOnload;
        reader.readAsDataURL(file);        
    });
    function fileOnload(e) {
        var canvas = $("#default-board")[0];
        var context = canvas.getContext("2d");
        var background = new Image;
        background.src = canvas.style.background.replace(/url\(/|\)/gi,"").trim();
        background.onload = function(){
            var $img = $("<img>", { src: e.target.result });
            $img.load(function() {
                 context.drawImage(backgroundImage, 0, 0, canvas.width, canvas.height);
                 context.drawImage(this, 0, 0);
            });
        }
    }
});

asterix_jv
  • 824
  • 1
  • 14
  • 35

2 Answers2

5

The canvas element's background (image) is not part of the canvas content and thus not saved.

Solution if you can not redraw the canvas

If you want the background just render it onto the canvas before you save using the composite operation "destination-over" it will only add pixels where the canvas is transparent or semi transparent and you would see the Elements background.

ctx.globalCompositeOperation = "destination-over";
ctx.drawImage(backgroundImage,0,0);
ctx.globalCompositeOperation = "source-over";  // restore default

To load the canvas CSS background image

var background = new Image;
background.src = canvas.style.background.replace(/url\(/|\)/gi,"").trim();
// wait till it has loaded.

You may have to stretch the image

ctx.drawImage(background,0,0,ctx.canvas.width,ctx.canvas.height);

Alternative solution uses a offscreen canvas and draws background first then the original canvas.

// ensure that the image has loaded before running this code.
// canvas is the original canvas that you want to add the background to
// ctx is the origin canvas context
var can2 = document.createElement("canvas");
can2.width = canvas.width;
can2.height = canvas.height;
var ctx2 = can2.getContext("2d");
ctx2.drawImage(background,0,0,ctx.canvas.width,ctx.canvas.height);
ctx2.drawImage(canvas,0,0);
// put the new result back in the original canvas so you can save it without changing code.
ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height);
ctx.drawImage(can2,0,0);

OR to provide a copy and paste solution

    function fileOnload(e) {
        var canvas = $("#default-board")[0];
        var context = canvas.getContext("2d");
        var background = new Image;
        background.src = canvas.style.background.replace(/url\(|\)/gi,"").trim();
        background.onload = function(){
            var $img = $("<img>", { src: e.target.result });
            $img.load(function() {
                 context.drawImage(backgroundImage, 0, 0, canvas.width, canvas.height);
                 context.drawImage(this, 0, 0);
            });
        }
    }); 
Blindman67
  • 51,134
  • 11
  • 73
  • 136
  • Can you help me with that? I put this code in the script but always show me only the draw but not the background...need I change something inside with this portion of code you give me? Best Regards – asterix_jv Mar 21 '17 at 14:33
  • You need to load the background as an image then you can render it. `var backgroundImage = new Image; backgroundImage.src="backgroundImageURL";` and make sure it has loaded before you try to render it. – Blindman67 Mar 21 '17 at 15:46
  • I tried putting the code in different part but without success...can you show me how can this be done? – asterix_jv Mar 21 '17 at 19:58
  • I have an error `SyntaxError: Invalid or unexpected token` in this part: `background.src = canvas.style.background.replace(/url\(/|\)/gi,"").trim();` specifically in this `(/url\(/|\)/gi,"")` – asterix_jv Mar 25 '17 at 20:24
  • @asterix_jv sorry that should have been `/url\(|\)/gi` – Blindman67 Apr 01 '17 at 01:10
  • I don't know why not save the background.. I change the code and now there is not error, but only save the draw but not the background. Can you see if there is something else? here is the link: [link](http://www.demo.grupovg.info/canvas.php) – asterix_jv Apr 01 '17 at 17:05
0

You almost done. Try change this code:

    $(document).ready(function () {
        $("#cambiocanvas > input").click(function () {
            var img = $(this).attr("src");
            $("#default-board").css("background", "url(" + img + ")");
        });
    });

To this one:

    $(".canvasborder").click(function(){
        var src = $(this).attr("src");
        defaultBoard.setImg(src);
    }); 

Like this:

    var defaultBoard = new DrawingBoard.Board("default-board", {
        background: "#fff",
        droppable: true,
        webStorage: false,
        enlargeYourContainer: true,
        addToBoard: true,
        stretchImg: true
    });
    defaultBoard.addControl("Download");

    $(".canvasborder").click(function(){
        var src = $(this).attr("src");
        defaultBoard.setImg(src);
    });     


    $(".drawing-form").on("submit", function(e) {
        var img = defaultBoard.getImg();
        var imgInput = (defaultBoard.blankCanvas == img) ? "" : img;
        $(this).find("input[name=image]").val( imgInput );
        defaultBoard.clearWebStorage();
    });
    $(function() {
        $("#file-input").change(function(e) {
            var file = e.target.files[0],
            imageType = /image.*/;
            if (!file.type.match(imageType))
            return;
            var reader = new FileReader();
            reader.onload = fileOnload;
            reader.readAsDataURL(file);        
        });
        function fileOnload(e) {
            var canvas = $("#default-board")[0];
            var context = canvas.getContext("2d");
            var background = new Image;
            background.src = canvas.style.background.replace(/url\(|\)/gi,"").trim();
            background.onload = function(){
                var $img = $("<img>", { src: e.target.result });
                $img.load(function() {
                    context.drawImage(backgroundImage, 0, 0, canvas.width, canvas.height);
                    context.drawImage(this, 0, 0);
                });
            }
        }
    });

And will be work with any image you put in the select list, remember it has to be accompanied by an Access-Control-Allow-Origin header allowing the origin of your page (potentially via the * wildcard).

asterix_jv
  • 824
  • 1
  • 14
  • 35