2

I'm quite stuck on how to drag the images to my canvas. So far I was able to drag the text around well... But something's do trigger to remove my image everytime I post a new Dedication..

I'm very confuse at the codes which I just got it.

Here's my code:

function updateTotal() { 
if (document.getElementById('fig1').checked)   
    {  var context = document.getElementById('display').getContext('2d');
      var imageObj = new Image();
      imageObj.onload = function()
        { context.drawImage(imageObj, 100, 100); }
    imageObj.src = 'http://vignette1.wikia.nocookie.net/doratheexplorer/images/8/88/Dora_Exploradora_(11).png/revision/latest?cb=20130928190347';
    }


    if (document.getElementById('fig2').checked)   
    { var context = document.getElementById('display').getContext('2d');
      var imageObj = new Image();
      imageObj.onload = function()
        { context.drawImage(imageObj, 100, 100); }
    imageObj.src = 'http://vignette1.wikia.nocookie.net/angrybirds/images/f/f7/Red_shoked_3.png/revision/latest?cb=20130505082125';
    }


     if (document.getElementById('fig3').checked)   
    { var context = document.getElementById('display').getContext('2d');
      var imageObj = new Image();
      imageObj.onload = function()
        { context.drawImage(imageObj, 100, 100); }
    imageObj.src = 'http://lh3.googleusercontent.com/-fsFMyfNLNG8/TuZs45U0dZI/AAAAAAAAg38/QIjqug0MnAo/Ic42/barbie6.png';
    }


// FUNCTION FOR DISPLAYING AND DRAGGING THE TEXT!

if (document.getElementById('design3').checked) {
          var canvas2 = document.getElementById("display");
              context = canvas2.getContext("2d");

          var $canvas2 = $("#display");
          var canvasOffset = $canvas2.offset();
          var offsetX = canvasOffset.left;
          var offsetY = canvasOffset.top;
          var scrollX = $canvas2.scrollLeft();
          var scrollY = $canvas2.scrollTop();
          var startX;
          var startY;
          var texts = []; // an array to hold text objects
          var selectedText = -1;// this var will hold the index of the hit-selected text

        function draw() { // clear the canvas & redraw all texts
          context.clearRect(0, 0, canvas2.width, canvas2.height);
            for (var i = 0; i < texts.length; i++) { var text = texts[i];
              context.fillText(text.text, text.x, text.y);  }
          }

        function textHittest(x, y, textIndex) { // test if x,y is inside the bounding box of texts[textIndex]
          var text = texts[textIndex];
            return (x >= text.x && x <= text.x + text.width && y >= text.y - text.height && y <= text.y);
            }

        function handleMouseDown(d) {
           d.preventDefault();
              startX = parseInt(d.clientX - offsetX);
              startY = parseInt(d.clientY - offsetY);
          
            for (var i = 0; i < texts.length; i++) {
              if (textHittest(startX, startY, i)) {
                selectedText = i; }  }
          }

        function handleMouseUp(d) { // done dragging
          d.preventDefault();
            selectedText = -1;  }

        function handleMouseOut(d) { // also done dragging
            d.preventDefault();
            selectedText = -1;  }

        function handleMouseMove(d) {
          if (selectedText < 0) { return; }
          d.preventDefault();
            mouseX = parseInt(d.clientX - offsetX);
            mouseY = parseInt(d.clientY - offsetY);

              var dx = mouseX - startX;
              var dy = mouseY - startY;
              startX = mouseX;
              startY = mouseY;
              var text = texts[selectedText];
              text.x += dx;
              text.y += dy;
              draw();     }
          
          $("#display").mousedown(function (d) { handleMouseDown(d); }); // listen for mouse events
          $("#display").mousemove(function (d) { handleMouseMove(d); });
          $("#display").mouseup(function (d) { handleMouseUp(d); });
          $("#display").mouseout(function (d) {  handleMouseOut(d);  });
          $("#text_dedi").click(function () {
              var y = texts.length * 20 + 20; 
              var text = {  text: $("#dedi_text").val(),
                  x: 20,
              y: y
               };

            context.font = "30px Roboto";
            text.width = context.measureText(text.text).width;
            text.height = 16;
            text.color = "#ffffff";   
            texts.push(text); // put this new text in the texts array
            draw(); // redraw everything
          });
          
          //this is the code for CLEAR BUTTON
          document.getElementById('clear').addEventListener('click', function() {
          context.clearRect(0, 0, canvas2.width, canvas2.height);  
          texts = []; },
          false);
        }
 }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<input type="radio" id="design3" name="design_3"  onchange="updateTotal()" />Dedication (click me first)
<div class="disp_dedi"> <input type="text" size="15" id="dedi_text" name="dedicationT" placeholder="Dedication"> 
<button id="text_dedi"> Post </button>  <input type="button" value="Clear" id="clear" size="23" onchange="updateTotal()">  </div> 

<br> <input type="radio" id="fig1" name="figurine_select" value="dora" onchange="updateTotal()" /> Dora 
<input type="radio" id="fig2" name="figurine_select" value="Angry Bird" onchange="updateTotal()" /> Angry Bird
<br> <input type="radio" id="fig3" name="figurine_select" value="barbie" onchange="updateTotal()" /> Barbie

<canvas id="display" height="400px" width="600px" style="position:absolute;"> </canvas>

And i also wan't to remove the image once i choose other image. As you can see, the image will disappear everytime I drag the dedication.

I'm really confused how to fix it... THANK YOU IN ADVANCE!!!

Khyana
  • 195
  • 1
  • 14
  • What have you tried so far? May want to consider using jQuery UI and "building" your image with HTML elements. Then once everything is in place, you can something like html2canvas to create an image. – Twisty Feb 27 '17 at 23:13
  • I would first run your code through http://jshint.com/ and get it cleared of syntax errors. – Twisty Feb 27 '17 at 23:32
  • @Twisty hello, thank you so much. Can't i run html here too right? .. well i got another method , can you help me about multiple images? http://stackoverflow.com/questions/42497330/html5-multiple-images-drag-drop – Khyana Feb 28 '17 at 02:24
  • It's not clear what you're using or what you're trying to do. I took a stab at a suggestion: https://jsfiddle.net/Twisty/955j8so3/8/ – Twisty Feb 28 '17 at 03:23
  • @Twisty WWOOOWWTHANK YOUUU!!! That was so amazing .. Is this possible in canvas? Because After the customization I need to capture the Card and save the image into my database . – Khyana Feb 28 '17 at 13:22
  • @Twisty I tried to copy your code, I didn't made any changes on the html part, only I removed the widget 3 cause I wanted it to displayed it in other part which is i'm using canvas. here's the problem I've encountered, i'll just show you the image - https://scontent.fmnl8-1.fna.fbcdn.net/v/t1.0-9/16938762_1427312857299994_701896807709543765_n.jpg?oh=0404957cecff03b2a8f4052bc2f15128&oe=592FDD13 – Khyana Feb 28 '17 at 13:59
  • Your usage is more clear now. Based on your image, the contaiment option is restricting you. Need to see your html. – Twisty Feb 28 '17 at 14:41
  • @Twisty wow I'm glad i was able to reach you. I'm using a Wizard template in my customization part...my html has very very long set of codes... what part does concern you? – Khyana Feb 28 '17 at 14:50
  • @Twisty here, I tried to make changes on your code and here's the outcome so far .. I was able to drag around the image outside the widgets but whenever I drop the image it will disappear -- https://scontent.fmnl8-1.fna.fbcdn.net/v/t1.0-9/16998949_1427352240629389_7993199482637295886_n.jpg?oh=80aaa72151b8df41a3eab0a0946f97d0&oe=593986B4 – Khyana Feb 28 '17 at 14:59
  • You're going to be struggling with this for a long time. Take a look here: https://jsfiddle.net/Twisty/955j8so3/12/ I'm leveraging Draggable and Droppable. When dragging to a Canvas, you'll need to adjust your droppable to add the image into the Canvas itself. I would advise you to hire or consult with someone regarding this. This is all pretty advanced and you already admitted that this is not something you are familiar with. – Twisty Feb 28 '17 at 17:30
  • Here is a further example: http://stackoverflow.com/questions/18961389/jquery-drag-drop-on-html-canvas – Twisty Feb 28 '17 at 18:16
  • A further example: https://jsfiddle.net/Twisty/955j8so3/15/ Note, this loses the "edit" features. Since you're working in a Image, you have to add a lot of stuff to build that into the image. I would advise that once the user is done "editing" all the content then gets written to a canvas. Or this could be done in SVG and converted too. – Twisty Feb 28 '17 at 18:42
  • @Twisty ooohh i think I found it, Guess I'll start it from scratch http://jsfiddle.net/djnBD/ .. thank you so much for the help! – Khyana Feb 28 '17 at 23:16
  • There are lots of ways to do this. Canvas makes an image... but there are a lot of advanced techniques you need. I found some easel plugins and things that could be used too. Lots out there, don't have to remake the wheel. – Twisty Feb 28 '17 at 23:42
  • Where I left things: https://jsfiddle.net/Twisty/955j8so3/23/ – Twisty Feb 28 '17 at 23:43

1 Answers1

2

I finally got to a point where I want to stop tinkering on this. OF course, I suspect I will continue to do so.

This can do the following:

  • Add Text to preview, that can be moved and resized
  • Add Image(s) to preview, that can be moved and resized
  • Preview, using Canvas, the resulting image

Working Example: https://jsfiddle.net/Twisty/955j8so3/27/

HTML

<div id="myWidget" class="ui-widget">
  <div class="left column">
    <div class="ui-widget-header ui-corner-top">
      A. Dedication Text
    </div>
    <div class="ui-widget-content ui-corner-bottom">
      <div class="disp_dedi">
        <form id="dedi_form">
          <input type="text" id="dedi_text" placeholder="Dedication">
          <select id="dedi_font">
            <option>Times New Roman</option>
            <option>Georgia</option>
            <option>Arial</option>
            <option>Courier New</option>
          </select>
          <select id="dedi_font_size">
            <option>11</option>
            <option>12</option>
            <option>14</option>
            <option selected>18</option>
            <option>24</option>
            <option>36</option>
          </select>
          <select id="dedi_font_align">
            <option>Left</option>
            <option>Center</option>
            <option>Right</option>
          </select>
          <a href="" id="add_dedi_text" class="button default">Add</a>
          <a href="" id="clear_dedi_text" class="button">Clear</a>
        </form>
      </div>
    </div>
    <div class="ui-widget-header ui-corner-top">
      B. Figures
    </div>
    <div class="ui-widget-content ui-corner-bottom">
      <ul id="fig_list">
        <li>
          <div class="fig_image" data-image-src="https://vignette1.wikia.nocookie.net/doratheexplorer/images/8/88/Dora_Exploradora_(11).png/revision/latest?cb=20130928190347" title="Dora">
          </div>
        </li>
        <li>
          <div class="fig_image" data-image-src="https://vignette1.wikia.nocookie.net/angrybirds/images/f/f7/Red_shoked_3.png/revision/latest?cb=20130505082125" title="Angry Bird">
          </div>
        </li>
        <li>
          <div class="fig_image" data-image-src="https://lh3.googleusercontent.com/-fsFMyfNLNG8/TuZs45U0dZI/AAAAAAAAg38/QIjqug0MnAo/Ic42/barbie6.png" title="Barbie">
          </div>
        </li>
      </ul>
    </div>
    <div class="ui-widget-header ui-corner-top">
      C. Finish
    </div>
    <div class="ui-widget-content ui-corner-bottom">
      <a id="save_display" class="default button">Preview</a>
      <a id="clear_display" class="button">Clear</a>
    </div>
  </div>
  <div class="right column">
    <div class="ui-widget-header ui-corner-top">
      Edit Design
    </div>
    <div class="ui-widget-content ui-corner-bottom">
      <div id="disp_card" class="disp_temp">
      </div>
    </div>
  </div>
  <div class="clear: both;">
  </div>
  <div id="card_modal" title="Preview">
    <canvas id="preview_image" width="600" height="400" style="margin: 0 auto;"></canvas>
  </div>
</div>

CSS

body {
  background: #fff;
}

#myWidget {
  width: 1110px;
  margin: 0 auto;
}

#myWidget:after {
  content: "";
  display: table;
  clear: both;
}

#myWidget div.left {
  padding-right: 0;
  margin-right: 0;
  float: left;
  width: 500px;
}

#myWidget div.left .ui-widget-content {
  margin-bottom: 4px;
}

#myWidget div.right {
  float: right;
  width: 606px;
}

#myWidget input,
#myWidget select {
  border: 1px solid #ccc;
  height: 25px;
  padding: 2px;
  border-radius: 4px;
  font-size: 1em;
}

#myWidget select {
  height: 30px;
}

#myWidget .button {
  padding: 0.2em 0.3em;
  margin: 4px 1px;
}

#myWidget .button.default {
  font-weight: bold;
  border-color: #9f9f9f;
}

#myWidget .ui-widget-header {
  padding: 0.25em 0;
  padding-left: 20px;
}

#myWidget .right .ui-widget-header {
  padding: 0.25em 0;
  text-align: center;
}

#myWidget .ui-widget-content {
  padding: 5px;
}

#myWidget #fig_list {
  list-style: none;
  height: 60px;
  padding: 0;
  margin: 0;
}

#myWidget #fig_list li {
  float: left;
}

#myWidget .fig_image {
  border: 1px solid #ccc;
  border-radius: 6px;
  width: 50px;
  height: 50px;
  background-repeat: no-repeat;
  background-size: 50px;
  margin-right: 7px;
  padding: 2px;
}

#myWidget .disp_temp {
  width: 598px;
  height: 398px;
  border: 1px solid #eee;
  position: relative;
}

#myWidget .disp_temp span {
  position: absolute;
}

#myWidget .disp_temp span.top {
  top: 0;
}

#myWidget .disp_temp span.right {
  right: 0;
}

.no-title .ui-dialog-titlebar {
  display: none;
}

.small-title .ui-dialog-titlebar {
  height: 1.25em;
  font-size: 0.75em
}

.small-title .ui-dialog-buttonpane .ui-dialog-buttonset .ui-button {
  padding: 0.125em;
}

JavaScript

$(function() {
  // Init
  var $imageContent = $([]);
  $(".button").button();
  $("#card_modal").dialog({
    autoOpen: false,
    dialogClass: "small-title",
    modal: true,
    width: 640,
    height: 540,
    buttons: [{
      text: "Save",
    }, {
      text: "Close",
      click: function() {
        $(this).dialog("close");
      }
    }]
  });

  $(".fig_image").each(function() {
    var figSrc = $(this).data("image-src");
    $(this).css("background-image", "url('" + figSrc + "')");
  }).draggable({
    containment: "#myWidget",
    helper: "clone",
    cursor: "move"
  });

  $("#disp_card").droppable({
    accept: ".fig_image",
    drop: function(e, ui) {
      console.log("Receving: ", ui.helper);
      if (!ui.helper.hasClass("placed")) {
        addFigure(ui.helper);
      }
    }
  });

  // Utility Functions
  function addDed(txt) {
    var $close = $("<span>", {
      class: "floating top right ui-icon ui-icon-close",
      title: "Remove Image"
    }).click(function(e) {
      removeItem($(e.target).parent());
    });
    var $dedTxt = $("<div>", {
      id: "ded-" + ($(".text").length + 1),
      class: "placed text"
    }).html(txt).append($close).css({
      position: "absolute",
      top: "20px",
      left: "20px",
      "font-size": $("#dedi_font_size option:selected").val() + "pt",
      "font-family": $("#dedi_font option:selected").val(),
      "text-align": $("#dedi_font_align option:selected").val(),
      "min-width": "1em",
      "min-height": "20px",
      "padding-right": "16px"
    });
    makeDrag($dedTxt);
    makeResize($dedTxt);
    $dedTxt.disableSelection();
    $dedTxt.appendTo($("#disp_card")).fadeIn();
  }

  function addFigure($item) {
    var dropPos = $item.position();
    var dropSrc = $item.data("image-src");
    var dropPlace = {
      top: dropPos.top - $("#disp_card").position().top,
      left: dropPos.left - $("#disp_card").position().left
    };
    var $close = $("<span>", {
      class: "floating top right ui-icon ui-icon-close",
      title: "Remove Image"
    }).click(function(e) {
      removeItem($(e.target).parent());
    });
    var $image = $("<div>", {
      id: "fig-" + ($(".placed").length + 1),
      class: "placed image"
    }).data("image-source", dropSrc).css({
      "background-image": "url('" + dropSrc + "')",
      "background-repeat": "no-repeat",
      width: "200px",
      height: "250px",
      position: "absolute",
      top: dropPlace.top + "px",
      left: dropPlace.left + "px"
    }).append($close);
    $item.fadeOut(function() {
      makeDrag($image);
      makeResize($image);
      $image.appendTo($("#disp_card")).fadeIn();
    });
  }

  function makeDrag($item) {
    $item.draggable({
      containment: "#disp_card"
    });
  }

  function makeResize($item) {
    $item.resizable({
      containment: "#disp_card",
      minWidth: 50,
      aspectRatio: !$item.hasClass("text"),
      start: function(e, ui) {
        if ($item.hasClass("text")) {
          $item.css("border", "1px dashed #ccc");
        }
      },
      resize: function(e, ui) {
        if ($item.hasClass("text")) {
          switch (true) {
            case (ui.size.height < 16):
              $item.css("font-size", "11pt");
              break;
            case (ui.size.height < 19):
              $item.css("font-size", "12pt");
              break;
            case (ui.size.height < 24):
              $item.css("font-size", "14pt");
              break;
            case (ui.size.height < 32):
              $item.css("font-size", "18pt");
              break;
            case (ui.size.height < 48):
              $item.css("font-size", "24pt");
              break;
            case (ui.size.height >= 48):
              $item.css("font-size", "36pt");
              break;
          }
        } else {
          $item.css("background-size", ui.size.width + "px " + ui.size.height + "px");
        }
      },
      stop: function(e, ui) {
        if ($item.hasClass("text")) {
          $item.css("border", "0");
        }
      }
    });
  }

  function removeItem($item) {
    console.log("Remove Item: ", $item);
    $item.fadeOut(function() {
      $item.remove();
    });
  }

  function createPreview() {
    $imageContent = [];
    var ctx = $("#preview_image")[0].getContext("2d");
    ctx.clearRect(0, 0, 600, 400);
    var $source = $("#disp_card");
    // Find and draw Text items
    var $text = $source.find(".text");
    var $det = {};
    var img;
    $text.each(function(ind, el) {
      $det.type = "Text";
      $det.top = parseInt($(el).css("top").slice(0, -2));
      $det.left = parseInt($(el).css("left").slice(0, -2));
      $det.width = $(el).width();
      $det.height = $(el).height();
      $det.content = $(el).text();
      $det.font = {};
      $det.font.size = $(el).css("font-size");
      $det.font.family = $(el).css("font-family");
      $det.font.align = $(el).css("text-align");
      $imageContent.push($det);
      console.log("Adding to Image: ", $det);
      ctx.font = $det.font.size + " " + $det.font.family;
      ctx.textAlign = $det.font.align;
      ctx.textBaseline = "top";
      ctx.fillText($det.content, $det.left, $det.top, $det.width);
      $det = {};
    });

    // Find and draw Image items
    var $images = $source.find(".image");
    $det = {};
    $images.each(function(ind, el) {
      var $det = {};
      $det.type = "Image";
      $det.top = parseInt($(el).css("top").slice(0, -2));
      $det.left = parseInt($(el).css("left").slice(0, -2));
      $det.width = $(el).width();
      $det.height = $(el).height();
      $det.src = {};
      $det.src.url = $(el).data("image-source");
      $imageContent.push($det);
      img = new Image();
      img.src = $det.src.url;
      $det.src.width = img.width;
      $det.src.height = img.height;
      $det.ratio = $det.width / img.width;
      $(img).on("load", function() {
        console.log("Adding to Image: ", $det);
        ctx.drawImage(img, $det.left, $det.top, $det.src.width * $det.ratio, $det.src.height * $det.ratio);
        $det = {};
      });
    });
    console.log($imageContent);
  }

  //Button Action Functions
  $("#add_dedi_text").click(function(e) {
    e.preventDefault();
    $("#dedi_form").submit();
  });
  $("#dedi_form").submit(function(e) {
    // Will catch when Enter / Return is hit in form
    e.preventDefault();
    addDed($("#dedi_text").val());
    $("#dedi_text").val("");
  })
  $("#clear_dedi_text").click(function(e) {
    e.preventDefault();
    $("#dedi_text").val("");
  });
  $("#save_display").click(function(e) {
    e.preventDefault();
    createPreview();
    $("#card_modal").dialog("open");
  });

  $("#clear_display").click(function(e) {
    e.preventDefault();
    if (confirm("Are you sure you wish to clear everything?")) {
      $("#disp_card").html("");
    }
  });
});

Using Draggable, Droppable, Dialog, and Resize, you can create a UI that allows users to customize an order. Now, when they are finally ready to Save, I am not sure what you want to have happen. I leave that to you for now. If you have Templates to load as the background of the #disp_card element, you can load those in too so that users will know where to place items.

This is making use of the following frameworks:

  • jQuery 2.1.1
  • jQuery UI 1.12.1
  • html2canvas 0.4.1 (Not used in this example)
Twisty
  • 30,304
  • 2
  • 26
  • 45
  • Thank you so much!!!, I'm just really stuck on the images and dedication text. my template for saving the canvas to my database is ready. This is really enough, I'm going to review what you've made. Thank you really! – Khyana Mar 01 '17 at 01:13
  • hello, is there any other way to Save the image in my database and could display it later? I did have some algo but it didn't work. http://stackoverflow.com/questions/43386478/store-and-display-image-using-canvas-in-database – Khyana Apr 13 '17 at 14:29
  • On my first set of codes, I got two canvases first is where the customization part then the display part. So I used your codes then I tried to apply my codes into it by getting the base64 string, the problem is its only a cracked picture. – Khyana Apr 13 '17 at 14:30