HTML5画布显示&拖动图片

时间:2017-02-24 16:08:01

标签: javascript jquery html5 canvas

我完全坚持如何将图像拖到画布上。 到目前为止,我能够很好地拖动文本... 但每当我发布一个新的奉献时,某些东西会触发删除我的图像。

我对我刚刚获得的代码感到非常困惑。

这是我的代码:



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);
        }
 }
&#13;
<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>
&#13;
&#13;
&#13;

一旦我选择其他图像,我也不想删除图像。 如您所见,每次拖动奉献时图像都会消失。

我真的很困惑如何解决它... 谢谢你提前!!!

1 个答案:

答案 0 :(得分:1)

我终于达到了一个我想停止修补的地步。当然,我怀疑我会继续这样做。

这可以执行以下操作:

  • 添加要预览的文字,可以移动和调整大小
  • 添加要预览的图像,可以移动和调整大小
  • 使用Canvas预览生成的图像

工作示例: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("");
    }
  });
});

使用Draggable,Droppable,Dialog和Resize,您可以创建一个允许用户自定义订单的UI。现在,当他们终于准备好保存时,我不确定你想要发生什么。我暂时把它留给你。如果要加载模板作为#disp_card元素的背景,则可以加载这些元素,以便用户知道放置项目的位置。

这是利用以下框架:

  • jQuery 2.1.1
  • jQuery UI 1.12.1
  • html2canvas 0.4.1(本例中未使用)