在mousemove上的Canvas.Context恢复是HTML5失败

时间:2016-02-15 14:43:23

标签: javascript html5-canvas

当鼠标移动到图像上时,我尝试为画布图像创建悬停效果,显示透明叠加层。一旦用户mouseout尝试通过使用Canvas还原方法将画布恢复到初始阶段,但它会一直失败。以下是整个代码

    var images = [];
    var halfCircle;
    var ctx;
    var canvas;
    var effect = true;
    jQuery(document).ready(function() {
        canvas = document.getElementById("myCanvas");
        canvas.style.backgroundColor = '#fafafa';

        ctx = canvas.getContext("2d");
        halfCircle = new HalfCircle();
        halfCircle.doArch(ctx);
        placeImages(ctx);
        addEventListenersToCanvas(canvas, ctx);
    });

    function placeImages(ctx){
        first_image = new Image();
        first_image.src = 'http://example.com/media/features/0.png';
        first_image.onload = function(){
            ctx.drawImage(first_image, 20, 20);
            images.push({x:20,y:20,link: "http://example.com/shoppinglist-infographic", img : first_image});
            ctx.save();
        }
        second_image = new Image();
        second_image.src = "http://example.com/media/features/1.png";
        second_image.onload = function(){
            ctx.drawImage(second_image, 130, 150);
            images.push({x:130,y:150,link: "http://example.com/referral/invite?g=banner", img : second_image});
            ctx.save();
        }
        third_image = new Image();
        third_image.src = "http://example.com/media/features/2.png";
        third_image.onload = function(){
            ctx.drawImage(third_image, 230, 220);
            images.push({x:230,y:220,link: "http://example.com/all-fast-delivery/", img : third_image});
            ctx.save();
        }
        fourth_image = new Image();
        fourth_image.src = "http://example.com/media/features/3.png";
        fourth_image.onload = function(){
            ctx.drawImage(fourth_image,460, 220);
            images.push({x:460,y:220,link:"http://example.com/busyhomemaker/", img : fourth_image});
            ctx.save();

        }
        fifth_image = new Image();
        fifth_image.src = "http://example.com/media/features/4.png";
        fifth_image.onload = function(){
            ctx.drawImage(fifth_image,570, 150);
            images.push({x:570,y:150,link:"#", img: fifth_image});
            ctx.save();
        }
        sixth_image = new Image();
        sixth_image.src = "http://example.com/media/features/5.png";
        sixth_image.onload = function(){
            ctx.drawImage(sixth_image,620, 20);
            images.push({x:620,y:20,link:"#", img:sixth_image});
            ctx.save();
        }
        text_image = new Image();
        text_image.src = "http://example.com/media/features/text.png";
        text_image.onload = function(){
            ctx.drawImage(text_image,285, 20);
            ctx.save();
        }

    }

    function getMousePos(canvas, evt) {
        var rect = canvas.getBoundingClientRect();
        return {
            x: evt.clientX - rect.left,
            y: evt.clientY - rect.top
        };
    }
    function addEventListenersToCanvas(canvas, ctx){
        ctx.save();
        canvas.addEventListener('mousemove', function(evt) {
            var mousePos = getMousePos(canvas, evt);
            for(var i = 0; i < images.length; i++){
                if(    (mousePos.x > images[i].x) && (mousePos.x < (images[i].x + images[i].img.width)) &&
                        (mousePos.y > images[i].y) && (mousePos.y < (images[i].y + images[i].img.height))
                ){

                    document.body.style.cursor = "pointer";
                    if(effect) {
                        ctx.fillStyle = "#fafafa";
                        ctx.globalAlpha = 0.1;
                        ctx.fillRect(images[i].x, images[i].y, images[i].img.width, images[i].img.height);
                        effect = false;
                    }
                }else{
                    document.body.style.cursor = "auto";
                    ctx.restore();
                    effect = true;
                }

            }

        });
       //
        canvas.addEventListener('click', function(event){
            var mousePos = getMousePos(canvas, event);
            for(var i = 0; i < images.length; i++){
                if(
                        (mousePos.x > images[i].x) && (mousePos.x < images[i].x + images[i].img.width) &&
                        (mousePos.y > images[i].y) && (mousePos.y < images[i].y + images[i].img.height)
                ){
                   // console.log('clicking on: ' + images[i].link);
                    window.open(images[i].link);

                }
            }

        });
    }

    var HalfCircle = function(){
        this.numOfArch = 6;
        this.posX = 438;
        this.posY = 20;
        this.rad = 170;
        this.color = [
            { start_color: 'rgb(255,182,54)', end_color: 'rgb(255,220,159)' },
            { start_color: 'rgb(240,97,38)', end_color: 'rgb(249,166,57)' },
            { start_color: 'rgb(254,107,108)', end_color: 'rgb(250,74,78)' },
            { start_color: 'rgb(0,131,195)', end_color: 'rgb(0,150,219)' },
            { start_color: 'rgb(115,174,14)', end_color: 'rgb(214,243,137)' },
            { start_color: 'rgb(133,29,250)', end_color: 'rgb(203,159, 255)' },
        ];
        this.lineWidth = 5;
    };

    HalfCircle.prototype = {
        smallDot: function (posX, posY, ctx, colr){
            ctx.beginPath();
            ctx.fillStyle = colr;
            ctx.arc(posX, posY, 7, 0, Math.PI*2, false);
            ctx.fill();
            ctx.closePath();
        },
        bigDot : function (posX, posY, ctx, colr){
            ctx.beginPath();
            ctx.fillStyle = colr;
            ctx.arc(posX, posY, 10, 0, Math.PI*2, false);
            ctx.fill();
            ctx.closePath();
        },
        getEndCord: function(startCord){
            return startCord + Math.PI/this.numOfArch;
        },
        doArch : function (ctx){
            var startCord = 0;
            for( i = 0; i < this.numOfArch; i++ ){
                dotStartX = this.rad * Math.cos(startCord) + this.posX;
                dotStartY = this.rad * Math.sin(startCord) + this.posY;
                this.smallDot(dotStartX, dotStartY, ctx , this.color[i].start_color);
                ctx.lineWidth = this.lineWidth;
                ctx.beginPath();
                ctx.strokeStyle = this.color[i].start_color;
                var endCord = this.getEndCord(startCord);
                ctx.arc(this.posX, this.posY, this.rad, startCord, endCord , false);
                ctx.stroke();
                ctx.closePath();
                startCord = endCord;
                dotStartX = this.rad * Math.cos(endCord) + this.posX;
                dotStartY = this.rad * Math.sin(endCord) + this.posY;
                this.bigDot(dotStartX, dotStartY, ctx , this.color[i].end_color);
            }
        }

    }

我真的需要有人输入这些。感谢

2 个答案:

答案 0 :(得分:0)

希望它会帮助你......

<!doctype html>
<html>
<head>
<meta charset="UTF-8" />
<title>Canvas Test</title>
</head>
<body>
<header> </header>
<nav> </nav>
<section>

<div>
<canvas id="canvas" width="320" height="200">
This text is displayed if your browser does not support HTML5 Canvas.
</canvas>
</div>

<script type="text/javascript">
var canvas;
var ctx;

function init() {
canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
draw();
}


function draw() {

ctx.fillStyle = '#FA6900';
ctx.shadowOffsetX = 5;
ctx.shadowOffsetY = 5;
ctx.shadowBlur    = 4;
ctx.shadowColor   = 'rgba(204, 204, 204, 0.5)';
ctx.fillRect(0,0,15,150);
ctx.save();

ctx.fillStyle = '#E0E4CD';
ctx.shadowOffsetX = 10;
ctx.shadowOffsetY = 10;
ctx.shadowBlur    = 4;
ctx.shadowColor   = 'rgba(204, 204, 204, 0.5)';
ctx.fillRect(30,0,30,150);
ctx.save();

ctx.fillStyle = '#A7DBD7';
ctx.shadowOffsetX = 15;
ctx.shadowOffsetY = 15;
ctx.shadowBlur    = 4;
ctx.shadowColor   = 'rgba(204, 204, 204, 0.5)';
ctx.fillRect(90,0,45,150);
ctx.save();

ctx.restore();
ctx.beginPath();
ctx.arc(185, 75, 22, 0, Math.PI*2, true);
ctx.closePath();
ctx.fill();

ctx.restore();
ctx.beginPath();
ctx.arc(260, 75, 15, 0, Math.PI*2, true);
ctx.closePath();
ctx.fill();

ctx.restore();
ctx.beginPath();
ctx.arc(305, 75, 8, 0, Math.PI*2, true);
ctx.closePath();
ctx.fill();
}

init();
</script>
</section>
<aside> </aside>
<footer> </footer>
</body>
</html>

答案 1 :(得分:0)

context.save仅保存上下文状态(样式,转换等)。它不会保存您在画布上绘制的任何内容。所以context.restore只会恢复上下文状态,而不是图纸。

要删除之前在画布上绘制的内容,您必须清除整个画布并重新绘制画布上所需的所有内容。

这是示例代码和演示:

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
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(); }

//
var halfCircle;
var effect = true;
var overlayIndex=-1;
//
var images = [];
images.push({x:20,y:20,  link: "http://example.com/shoppinglist-infographic"});
images.push({x:130,y:150,link: "http://example.com/referral/invite?g=banner"});
images.push({x:230,y:220,link: "http://example.com/all-fast-delivery/"});
images.push({x:460,y:220,link:"http://example.com/busyhomemaker/"});
images.push({x:570,y:150,link:"#"});
images.push({x:620,y:20, link:"#"});
images.push({x:285,y:20, link:"#"});


// Define HalfCircle
var HalfCircle = function(){
    this.numOfArch = 6;
    this.posX = 438;
    this.posY = 20;
    this.rad = 170;
    this.color = [
        { start_color: 'rgb(255,182,54)', end_color: 'rgb(255,220,159)' },
        { start_color: 'rgb(240,97,38)', end_color: 'rgb(249,166,57)' },
        { start_color: 'rgb(254,107,108)', end_color: 'rgb(250,74,78)' },
        { start_color: 'rgb(0,131,195)', end_color: 'rgb(0,150,219)' },
        { start_color: 'rgb(115,174,14)', end_color: 'rgb(214,243,137)' },
        { start_color: 'rgb(133,29,250)', end_color: 'rgb(203,159, 255)' },
    ];
    this.lineWidth = 5;
};
//
HalfCircle.prototype = {
    smallDot: function (posX, posY, ctx, colr){
        ctx.beginPath();
        ctx.fillStyle = colr;
        ctx.arc(posX, posY, 7, 0, Math.PI*2, false);
        ctx.fill();
        ctx.closePath();
    },
    bigDot : function (posX, posY, ctx, colr){
        ctx.beginPath();
        ctx.fillStyle = colr;
        ctx.arc(posX, posY, 10, 0, Math.PI*2, false);
        ctx.fill();
        ctx.closePath();
    },
    getEndCord: function(startCord){
        return startCord + Math.PI/this.numOfArch;
    },
    doArch : function (ctx){
        var startCord = 0;
        for( i = 0; i < this.numOfArch; i++ ){
            dotStartX = this.rad * Math.cos(startCord) + this.posX;
            dotStartY = this.rad * Math.sin(startCord) + this.posY;
            this.smallDot(dotStartX, dotStartY, ctx , this.color[i].start_color);
            ctx.lineWidth = this.lineWidth;
            ctx.beginPath();
            ctx.strokeStyle = this.color[i].start_color;
            var endCord = this.getEndCord(startCord);
            ctx.arc(this.posX, this.posY, this.rad, startCord, endCord , false);
            ctx.stroke();
            ctx.closePath();
            startCord = endCord;
            dotStartX = this.rad * Math.cos(endCord) + this.posX;
            dotStartY = this.rad * Math.sin(endCord) + this.posY;
            this.bigDot(dotStartX, dotStartY, ctx , this.color[i].end_color);
        }
    }
}

// preload all images
// put the paths to your images in imageURLs[]
var imageURLs=[];  
imageURLs.push('http://example.com/media/features/0.png');
imageURLs.push('http://example.com/media/features/1.png');
imageURLs.push('http://example.com/media/features/2.png');
imageURLs.push('http://example.com/media/features/3.png');
imageURLs.push('http://example.com/media/features/4.png');
imageURLs.push('http://example.com/media/features/5.png');
imageURLs.push('http://example.com/media/features/text.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();
    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];
  }      
}
//
function imagesAreNowLoaded(){
  // the imgs[] array now holds fully loaded images
  // the imgs[] are in the same order as imageURLs[]
  halfCircle = new HalfCircle();
  draw();
  $("#canvas").mousemove(function(e){handleMouseMove(e);});
}

function draw(){
    ctx.fillStyle='#fafafa';
    ctx.fillRect(0,0,cw,ch);
    halfCircle.doArch(ctx);
    for(var i=0;i<imgs.length;i++){
        ctx.drawImage(imgs[i], images[i].x,images[i].y);        
        if(i==overlayIndex){
            ctx.fillStyle = "#fafafa";
            ctx.globalAlpha = 0.35;
            ctx.fillRect( images[i].x, images[i].y, imgs[i].width, imgs[i].height);
            ctx.globalAlpha = 1.00;
        }
    }
}

function handleMouseMove(e){
  // tell the browser we're handling this event
  e.preventDefault();
  e.stopPropagation();
  mx=parseInt(e.clientX-offsetX);
  my=parseInt(e.clientY-offsetY);
  //
  overlayIndex=-1;
  for(var i=0;i<images.length;i++){
      var img=images[i];
      var image=imgs[i];
      if(
          mx>img.x && mx<img.x+image.width &&
          my>img.y && my<img.y+image.height
      ){
          overlayIndex=i;
      }
  }
  draw();
}
body{ background-color: ivory; }
#canvas{border:1px solid red; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<canvas id="canvas" width=900 height=500></canvas>