【问题标题】:using images as buttons on html canvas使用图像作为 html 画布上的按钮
【发布时间】:2015-10-14 13:04:41
【问题描述】:

因此,感谢 markE,我设法让 javascript 代码跟踪显示在 html 画布上的图像上的光标,但现在我试图将每个图像视为一个按钮,并在光标悬停。到目前为止,通过许多排列,我无法将图像或图像路径名存储到数组元素中,该元素还包含我们用来包含路径的点。代码如下:

<script type="text/javascript" language="JavaScript">

    var canvas;
    var canvasWidth;
    var ctx;

    function init() {
        HideContent('readLess');

        var cursors=['default','w-resize','n-resize'];
        var currentCursor=0;

        canvas = document.getElementById('puzzle-container');
        canvas.width = 815;
        canvas.height = 425;
        canvas.align = 'center';
        ctx = canvas.getContext("2d");

        var search = new Image();
        search.src = 'img/puzzleSearch.png';
        var searchHover = new Image();
        search.onload = function() {
            ctx.drawImage(search, 0, 0);
        };
        var nav = new Image();
        nav.src = 'img/puzzleNav.png';
        var navHover = new Image();
        nav.onload = function() {
            ctx.drawImage(nav, 119, 2.5 );
        }
.
.
.           
        var events = new Image();
        events.src = 'img/puzzleEvents.png';
        var eventsHover = new Image();
        eventsHover.src = 'img/puzzleEventsHover.png';
        events.onload = function() {
            ctx.drawImage(events, 564, 265 );
        }

        function reOffset(){
            var BB=canvas.getBoundingClientRect();
            offsetX=BB.left;
            offsetY=BB.top;        
        }
        var offsetX,offsetY;
        reOffset();
        window.onscroll=function(e){ reOffset(); }
        window.onresize=function(e){ reOffset(); }


        $("#puzzle-container").mousemove(function(e){handleMouseMove(e);});

        var shapes=[];
        shapes.push({
                points:[{x:0,y:2.5},{x:155,y:2.5},{x:155,y:205},{x:0,y:205}], cursor:1, img:search, imgHov:searchHover,
        });

.
.
.   
        shapes.push({
                points:[{x:0,y:310},{x:250,y:310},{x:250,y:400},{x:0,y:400}], cursor:1, img:events, imgHov:'img/eventsHover.png',
        });

        for(var i=0;i<shapes.length;i++){
            var s=shapes[i];
            definePath(s.points);
            ctx.stroke();
        }

        function definePath(p){
            ctx.beginPath();
            ctx.moveTo(p[0].x,p[0].y);
            for(var i=1;i<p.length;i++){
                ctx.lineTo(p[i].x,p[i].y);
            }
            ctx.closePath();
        }

        function handleMouseMove(e){
            // tell the browser we're handling this event
            e.preventDefault();
            e.stopPropagation();

            mouseX=parseInt(e.clientX-offsetX);
            mouseY=parseInt(e.clientY-offsetY);

            // Put your mousemove stuff here
            var newCursor;
            for(var i=0;i<shapes.length;i++){
                var s=shapes[i];
                definePath(s.points);
                if(ctx.isPointInPath(mouseX,mouseY)){
                    if (i === 6 ) {
                        var img = new Image();
                        var imgSrc = s.imgHov;
                        img.src = imgSrc;
                        console.log("hover image is: " + s.imgHov );
                        ctx.drawImage(img, 564, 265 );
                    }
                    newCursor=s.cursor;
                    break;
                }
            }
            if(!newCursor){
                if(currentCursor>0){
                    currentCursor=0;
                    canvas.style.cursor=cursors[currentCursor];              
                }
            }else if(!newCursor==currentCursor){
                currentCursor=newCursor;
                canvas.style.cursor=cursors[currentCursor];              
            }
        }



    }

    function HideContent(d) {
        document.getElementById(d).style.display = "none";
    }
    function ShowContent(d) {
        document.getElementById(d).style.display = "block";
    }
    function ReverseDisplay(d) {
        if(document.getElementById(d).style.display == "none") { document.getElementById(d).style.display = "block"; }
        else { document.getElementById(d).style.display = "none"; }
    }

</script>

我尝试将图像变量存储在数组中,将图像路径名存储在数组中,但是当我将光标悬停在图像上时,当它尝试加载图像时总是会出现 404 错误。如果我硬编码图像名称并加载,则当光标悬停在该路径上时将显示它。

将图像名称和/或路径存储在点数组中以便在跟踪光标移动时可以访问它,我做错了什么?

谢谢.....

【问题讨论】:

  • 这是因为在第一个形状中,s.imgHov 是实际的&lt;img&gt; 标签。您应该尝试将 imgHov:searchHover 更改为 imgHov:searchHover.src 或在其他形状中实际引用 标记,然后调用 ctx.drawImage(s.imgHov, 564, 265 ); 以避免在没有缓存的情况下重新下载图像。

标签: javascript html image button canvas


【解决方案1】:

您的解决方法是在使用之前预加载所有图像。

图像不会立即加载。当您设置img.src 时,浏览器开始加载图像,但即使在图像完全加载之前也会继续执行下一行代码。

问题出在这里:

// the browser BEGINS to load the image, but simultaneously
// continues executing the code that follows.
img.src = imgSrc;

// img has not yet loaded when drawImage is executed 
ctx.drawImage(img, 564, 265 );

有数十种图像预加载器可用。这只是一个:

// canvas related variables
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;

// put the paths to your images in imageURLs[]
var imageURLs=[];  
imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/multple/face1.png");
imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/multple/face2.png");

// the loaded images will be placed in imgs[]
var imgs=[];
var imagesOK=0;
startLoadingAllImages(imagesAreNowLoaded);

// Create a new Image() for each item in imageURLs[]
// When all images are loaded, run the callback (==imagesAreNowLoaded)
function startLoadingAllImages(callback){

  // iterate through the imageURLs array and create new images for each
  for (var i=0; i<imageURLs.length; i++) {
    // create a new image an push it into the imgs[] array
    var img = new Image();
    // Important! By pushing (saving) this img into imgs[],
    //     we make sure the img variable is free to
    //     take on the next value in the loop.
    imgs.push(img);
    // when this image loads, call this img.onload
    img.onload = function(){ 
      // this img loaded, increment the image counter
      imagesOK++; 
      // if we've loaded all images, call the callback
      if (imagesOK>=imageURLs.length ) {
        callback();
      }
    };
    // notify if there's an error
    img.onerror=function(){alert("image load failed");} 
    // set img properties
    img.src = imageURLs[i];
  }      
}

// All the images are now loaded
// Do drawImage & fillText
function imagesAreNowLoaded(){

  // the imgs[] array now holds fully loaded images
  // the imgs[] are in the same order as imageURLs[]

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-29
    • 2019-08-09
    • 1970-01-01
    • 2017-09-01
    • 2019-07-29
    • 1970-01-01
    • 1970-01-01
    • 2013-02-16
    相关资源
    最近更新 更多