In a 2D canvas, is there a way to give a sprite an outline?

前端 未结 3 570
刺人心
刺人心 2020-12-04 03:40

I\'d like to give a sprite an outline when the character gets healed/damaged/whatever but I can\'t think of a way to code this using the 2d canvas. If it were possible, I\'

3条回答
  •  独厮守ぢ
    2020-12-04 04:10

    Maybe it would be worth trying this :

    • build a canvas 1.1 time bigger than the original sprite
    • fill it with the outline color
    • draw the sprite scaled by 1.1 on the canvas using destination-in globalCompositeOperation.

    Then you have a bigger 'shadow' of your sprite in the outline color.

    When you want to draw the outline :

    • draw the 'shadow' (centered)
    • draw your sprite within the shadow.

    Depending on the convexity of your sprite, this will work more or less nicely, but i think it's worth trying since it avoids you doubling the number of input graphic files.

    I just did a short try as proof-of-concept and it quite works :
    http://jsbin.com/dogoroxelupo/1/edit?js,output

    Before : enter image description here

    After : enter image description here

    html

    
    
      
      
    
    
    

    code

    window.onload=function() {
      var spr = document.getElementById('spr');
      var margin = 4;
      var gh = createGhost(spr, '#F80', margin);
      var cv = document.getElementById('cv');
      var ctx = cv.getContext('2d');
      var outlined = true;
      setInterval(function() {
         ctx.clearRect(0,0,cv.width, cv.height);
         if (outlined)       
           ctx.drawImage(gh, 0, 0)
         ctx.drawImage(spr, 0, 0)
         outlined = !outlined;
      }, 400);
    }
    
    function createGhost (img, color, margin) {
      var cv= document.createElement('canvas');
      cv.width = img.width+2*margin;
      cv.height = img.height + 2*margin;
      var ctx = cv.getContext('2d');
      ctx.fillStyle = color;
      ctx.fillRect(0,0, cv.width, cv.height);
      ctx.save();
      ctx.globalCompositeOperation = 'destination-in';
      var scale = cv.width/spr.width;
      ctx.scale(cv.width/spr.width, cv.height/spr.height); 
      ctx.drawImage(img, -margin, -margin);
      ctx.restore();
      return cv;  
    }
    

提交回复
热议问题