javascript - 如何在 Canvas 中的可拖动对象上添加工具提示?

标签 javascript jquery html canvas 2d

在我的代码中,SVG 被解析并在 Canvas 上绘制,orange1.png 和 green1.png 图像也被绘制在 SVg 文件上。在这里,我可以缩放和平移 Canvas ,还可以拖动通过 JSON 绘制在其上的图像。

现在,当我单击这些图像或将鼠标悬停在这些图像上时,我想在图像(orange1.png 和 green1.png)上添加工具提示。

showTooltip 函数用于在这些图像(orange1.png 、 green1.png)上显示工具提示。

clearTooltip函数用于清除工具提示。

我应该在更新的代码中的何处以及如何添加 showTooltip 和clearTooltip 函数?

对于显示工具提示,鼠标单击或鼠标悬停哪个选项更好?

I tried some possibilities but I am missing something.

function showTooltip(x, y, index) {         
    var editedValue = [];           
    if (tooltip === null) {
        tooltip = document.createElement('div');
        tooltip.className = 'tooltip';              
        tooltip.style.left = (x) + 'px';
        tooltip.style.top = (y) + 'px';             
        tooltip.innerHTML = "<input type='text' id='generic_txt' value='"+dataJSON[index].tooltiptxt[0]+"' /> <input type='submit' id='generic_edit' value='Edit'>"     

        document.getElementsByTagName('body')[0].appendChild(tooltip);
    }           

    document.getElementById('generic_txt').setAttribute('disabled', 'disabled');    
    $("#generic_edit").click(function(){
        if(document.getElementById('generic_edit').value == "Edit"){
            document.getElementById('generic_txt').removeAttribute('disabled');
            document.getElementById('generic_txt').focus();
            document.getElementById('generic_edit').value = "Change";
        } else {
            document.getElementById('generic_txt').setAttribute('disabled', 'disabled');
            document.getElementById('generic_edit').value = "Edit";
            editedValue = $('#generic_txt').val();          
            dataJSON[index].tooltiptxt[0] = editedValue;  // important line         
        }
       return false;
    });         
}

function clearTooltip(doFade) {         
    if (tooltip !== null) {
        var fade = 1;
        function fadeOut() {
            tooltip.style.opacity = fade;
            fade -= 0.1;
            if (fade > 0) {
                setTimeout(fadeOut, 16);
            } else {
                remove();
            }
        }
        function remove() {
            document.getElementsByTagName('body')[0].removeChild(tooltip);
            tooltip = null;
        }
        if (doFade === true) {
            fadeOut();
            //$('.first_cancel').click(fadeOut());
        } else {
            remove();
        }
    }
}

以下是我更新的源代码。

HTML Code :

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
    <head>      
        <script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
        <style>
            canvas {
                border:1px solid #000
            }
            .tooltip{
                *position:fixed;
                position:absolute;
                *background:#ff7;
                background:green;
                border:1px solid #000;
                padding:7px;
                font-family:sans-serif;
                font-size:12px;
            }
            .tooltip2  {
                *position:fixed;
                position:absolute;
                background:pink;
                border:1px solid #000;
                padding:7px;
                font-family:sans-serif;
                font-size:12px;
            }
        </style>        
    </head>
    <body>
    <script src="http://canvg.googlecode.com/svn/trunk/rgbcolor.js"></script> 
    <script src="http://canvg.googlecode.com/svn/trunk/StackBlur.js"></script>
    <script src="http://canvg.googlecode.com/svn/trunk/canvg.js"></script>

    <canvas id="myCanvas" width="800" height="700" style="border: 1px solid;margin-top: 10px;"></canvas>
    <div id="buttonWrapper">
        <input type="button" id="plus" value="+">
        <input type="button" id="minus" value="-">
        <input type="button" id="original_size" value="100%">       
    </div>  
    <script src="/static/js/markers.js"></script>
    <script src="/static/js/draw.js"></script>


    </body>
</html>

draw.js:

var dataJSON = data || [];
var dataJSON2 = data2 || [];
window.onload = function(){ 
  //$(function(){              
    var canvas=document.getElementById("myCanvas");
    var ctx=canvas.getContext("2d");        

    var canvasOffset=$("#myCanvas").offset();
    var offsetX=canvasOffset.left;
    var offsetY=canvasOffset.top;

    var lastX=0;
    var lastY=0;
    var panX=0;
    var panY=0;
    var dragging=[];
    var dragging2=[];
    var isDown=false;

    function loadImages(sources, callback){
      var images = {};
      var loadImages = 0;
      var numImages = 0;
      //get num of sources
      for(var i in sources){            
        numImages++;
      }
      for(var i in sources){            
        images[i] = new Image();
        images[i].onload = function(){
          if(++loadImages >= numImages){
            callback(images);
          }
        };
        images[i].src = sources[i];            
      }
    }

    var sources = {orange : '/static/images/orange1.png', green : '/static/images/green1.png'};


    // load the tiger image
    var svgfiles = ["/static/images/awesome_tiger.svg"];
    /*var tiger=new Image();
    tiger.onload=function(){
      draw();
    }
     tiger.src="tiger.png";*/

    function draw(scaleValue){ 
      ctx.clearRect(0,0,canvas.width,canvas.height);    
      ctx.save();
      ctx.drawSvg(svgfiles[0],panX,panY,400*scaleValue, 400*scaleValue);         
      //ctx.drawImage(tiger,panX,panY,tiger.width,tiger.height);    
       //ctx.scale(scaleValue, scaleValue);
      loadImages(sources, function(images){     
        ctx.scale(scaleValue, scaleValue);
        for(var i = 0, pos; pos = dataJSON[i]; i++) {            
          ctx.drawImage(images.orange, parseInt(parseInt(pos.x) + parseInt(panX / scaleValue)), parseInt(parseInt(pos.y) + parseInt(panY / scaleValue)), 20/scaleValue, 20/scaleValue);             
        }
        for(var i = 0, pos; pos = dataJSON2[i]; i++) {            
          ctx.drawImage(images.green, parseInt(parseInt(pos.x) + parseInt(panX / scaleValue)), parseInt(parseInt(pos.y) + parseInt(panY / scaleValue)), 20/scaleValue, 20/scaleValue);           
        }
        ctx.restore();
      });

    };
    var scaleValue = 1;
    var scaleMultiplier = 0.8;
    draw(scaleValue);
    var startDragOffset = {};
    var mouseDown = false;          
    // add button event listeners
    document.getElementById("plus").addEventListener("click", function(){           
        scaleValue /= scaleMultiplier;  
        //checkboxZoomPan();            
        draw(scaleValue);               
    }, false);
     document.getElementById("minus").addEventListener("click", function(){
        scaleValue *= scaleMultiplier;
        //checkboxZoomPan();            
        draw(scaleValue);       
    }, false);
    document.getElementById("original_size").addEventListener("click", function(){
        scaleValue = 1;
        //checkboxZoomPan();            
        draw(scaleValue);   
    }, false);


    // create an array of any "hit" colored-images
    function imagesHitTests(x,y){   
      // adjust for panning
      x-=panX;
      y-=panY;
      // create var to hold any hits
      var hits=[];
      // hit-test each image
      // add hits to hits[]
      loadImages(sources, function(images){
        for(var i = 0, pos; pos = dataJSON[i]; i++) { 
          if(x >= parseInt(pos.x * scaleValue) && x <= parseInt((pos.x * scaleValue) + 20) && y >= parseInt(pos.y * scaleValue) && y <= parseInt((pos.y * scaleValue) + 20)){
            hits.push(i);           
          }              
        }            
      });          
      return(hits);
    }

    function imagesHitTests2(x,y){      
      // adjust for panning
      //x-=panX;
      //x = parseInt(x) - parseInt(panX);     
     // y-=panY;
     x-=panX;
     y-=panY;
      // create var to hold any hits
      var hits2=[];
      // hit-test each image
      // add hits to hits[]
      loadImages(sources, function(images){            
        for(var i = 0, pos; pos = dataJSON2[i]; i++) {          
          //if(x > pos.x && x < parseInt(parseInt(pos.x) + parseInt(20)) && y > pos.y && y < parseInt(parseInt(pos.y) + parseInt(20))){
          if(x >= parseInt(pos.x * scaleValue) && x <= parseInt((pos.x * scaleValue) + 20) && y >= parseInt(pos.y * scaleValue) && y <= parseInt((pos.y * scaleValue) + 20)){           
            hits2.push(i);          
          }              
        }            
      });          
      return(hits2);
    }

    function handleMouseDown(e){
      // get mouse coordinates
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);
      // set the starting drag position
      lastX=mouseX;
      lastY=mouseY;
      // test if we're over any of the images
      dragging=imagesHitTests(mouseX,mouseY);
      dragging2=imagesHitTests2(mouseX,mouseY);
      // set the dragging flag    
      isDown=true;
    }

    function handleMouseUp(e){
      // clear the dragging flag
      isDown=false;
    }

    function handleMouseMove(e){
      // if we're not dragging, exit
      if(!isDown){
        return;
      }

      //get mouse coordinates
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);

      // calc how much the mouse has moved since we were last here
      var dx=mouseX-lastX;
      var dy=mouseY-lastY;

      // set the lastXY for next time we're here
      lastX=mouseX;
      lastY=mouseY;

      // handle drags/pans
      if(dragging.length>0){      
        // we're dragging images
        // move all affected images by how much the mouse has moved            
        for(var i = 0, pos; pos = dataJSON[dragging[i]]; i++) {              
          pos.x = parseInt(pos.x) + parseInt(dx);
          pos.y = parseInt(pos.y) + parseInt(dy);              
        }
      }
      else if(dragging2.length>0){      
        for(var i = 0, pos1; pos1 = dataJSON2[dragging2[i]]; i++) {              
          pos1.x = parseInt(pos1.x) + parseInt(dx);              
          pos1.y = parseInt(pos1.y) + parseInt(dy);
        }            
      }
      else{
        // we're panning the tiger
        // set the panXY by how much the mouse has moved
        panX+=dx;
        panY+=dy;
      }
      draw(scaleValue);
    }


    // use jQuery to handle mouse events
    $("#myCanvas").mousedown(function(e){handleMouseDown(e);});
    $("#myCanvas").mousemove(function(e){handleMouseMove(e);});
    $("#myCanvas").mouseup(function(e){handleMouseUp(e);});

// }); // end $(function(){});
  }

markers.js:

data = [  
    {   "id" :["first"],        
        "x": ["195"],
        "y": ["150"],
        "tooltiptxt": ["Region 1"]

    },  
    {
        "id" :["second"],
        "x": ["255"],
        "y": ["180"],
        "tooltiptxt": ["Region 2"]      
    },
    {
        "id" :["third"],
        "x": ["200"],
        "y": ["240"],
        "tooltiptxt": ["Region 3"]      
    }       

];

data2 = [  
    {   "id" :["first2"],       
        "x": ["225"],
        "y": ["150"],
        "tooltiptxt": ["Region 21"]

    },  
    {
        "id" :["second2"],
        "x": ["275"],
        "y": ["180"],
        "tooltiptxt": ["Region 22"]     
    },
    {
        "id" :["third3"],
        "x": ["300"],
        "y": ["240"],
        "tooltiptxt": ["Region 23"]     
    }       

];

最佳答案

我想你可以试试这个:

<!DOCTYPE html>
<html>
<head>
<title>Canvas Links Example</title>
<script>  
    function OnLoad(){
        var canvas = document.getElementById("myCanvas");
        var ctx = canvas.getContext("2d");      
        ctx.translate(0.5, 0.5);
        ctx.strokeStyle = "#5F7FA2";
        ctx.strokeRect(50, 50, 25, 25);
        var img = new Image();
        img.src = "http://www.cs.washington.edu/education/courses/csep576/05wi/projects/project4/web/artifact/liebling/average_face.gif";
        var img1 = new Image();
        img1.src = "E:\Very IMP Projects\WinService\SourceCode\MVC\BpmPresentation\Images\loading.gif";
        img.onload = function(){
        ctx.drawImage(img, 50, 50);
        canvas.addEventListener("mousemove", on_mousemove, false);
        canvas.addEventListener("click", on_click, false);
        Links.push(50 + ";" + 50 + ";" + 25 + ";" + 25 + ";" + "http://plus.google.com/");
        }        
        var Links = new Array();
        var hoverLink = "";         
        var canvas1 = document.getElementById("myCanvas1");
        var ctx1 = canvas1.getContext("2d");
        function on_mousemove (ev) {    
            var x, y;
            if (ev.layerX || ev.layerX == 0) { // For Firefox
                x = ev.layerX;
                y = ev.layerY;
            }
            for (var i = Links.length - 1; i >= 0; i--) {
                var params = new Array();
                params = Links[i].split(";");
                var linkX = parseInt(params[0]),
                    linkY = parseInt(params[1]),
                    linkWidth = parseInt(params[2]),
                    linkHeight = parseInt(params[3]),
                    linkHref = params[4];
                if (x >= linkX && x <= (linkX + linkWidth) && y >= linkY && y <= (linkY + linkHeight)){
                    document.body.style.cursor = "pointer";
                    hoverLink = linkHref;                 
                    ctx1.translate(0.5, 0.5);
                    ctx1.strokeStyle = "#5F7FA2";
                    canvas1.style.left = x + "px";
                    canvas1.style.top = (y+40) + "px";
                    ctx1.clearRect(0, 0, canvas1.width, canvas1.height);                    
                    var img1 = new Image();
                    img1.src = "E:\Very IMP Projects\WinService\SourceCode\MVC\BpmPresentation\Images\loading.gif";
                    img1.onload = function () {
                        ctx1.drawImage(img1, 50, 50);
                    }
                    break;
                }
                else {
                    document.body.style.cursor = "";
                    hoverLink = "";
                    canvas1.style.left = "-200px";
                }
            };
        }
        function on_click(e) {
            if (hoverLink) {               
                window.open(hoverLink);
                //window.location = hoverLink;      
            }
        }
    } 
</script> 
</head>
<body onload="OnLoad();">
<canvas id="myCanvas" width="450" height="250" style="border:1px solid #eee;">
Canvas is not supported in your browser ! :(  
</canvas>
<canvas id="myCanvas1" width="50" height="50" style="background-color:white;border:1px solid blue;position:absolute;left:-200px;top:100px;">
    </canvas>
</body>
</html>

关于javascript - 如何在 Canvas 中的可拖动对象上添加工具提示?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18511800/

相关文章:

javascript - 'bol === !0' 和 'bol == true' 相同吗?

Javascript/Coffeescript 使用函数哈希作为参数

javascript - 如何在此脚本中淡入查询中的结果

java - 如何在 android textview 上使用 removeSpan()?

javascript - 进入对象或对象的对象的条目和键

javascript - Thunderbird 撰写发送消息事件不会触发

javascript - 根据父元素的大小或窗口的大小更改 translateX 的值和元素的大小

javascript - php 如何检查字符串中某个单词是否重复

html - 选择一个元素 "inside":first-child pseudo selector using CSS

html - 固定尺寸盒子的 CSS 流体网格