Иво Стратев
Иво Стратев

Reputation: 415

Is there a way to contour or outline a svg element with Js?

Is there a way to contour or outline a svg element with SnapSVG ot other JavaScript Lib?

Upvotes: 0

Views: 1823

Answers (2)

Blindman67
Blindman67

Reputation: 54089

Create a canvas slightly bigger than the SVG size you want.

Draw a rectangle over it in the colour you want the outLine. Set globalCompositeOperation = "destination-atop" then draw the SVG on top. Now you have a mask of the SVG.

Then draw that Mask on another canvas in a circle the with the radius you want the outline. Then draw the SVG on top and you have an outlined SVG.

If you have semi transparent parts you will have to do some extra work. But that's the general principle.

// the SVG image to outline
svg = `<?xml version="1.0"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"  width="328" height="208" id="testSVG" ><defs></defs><path d="M278.5,30Q317.3,35.8,319,72.5Q288.3,93.3,262.5,65Q242.8,77.3,252,134.5Q261.3,160.3,283.5,149C317.8,121.6,257.5,130.8,271,98.5Q270.9,95.6,319.5,97Q322.4,96.9,321,160.5Q297.8,189.3,261.5,185Q237.3,181.3,226,156.5Q214,135.5,218,86.5Q227.8,44.8,242.5,38Q264.5,26,278.5,30Z
M42.5,30Q89.3,27.3,93,67.5C63.5,99,51.5,42,38,67.5Q95.5,95,97,126.5Q99.3,175.3,60.5,185Q32,187,21.5,177Q4.8,157.3,5,142.5C34.9,102.2,48.5,175.5,65,145.5C75.9,118.3,8.4,111.6,9,86.5Q4.3,36.8,42.5,30Z
M102.5,33Q133.5,33,135,33.5L157,136L179,33.5Q179,32.5,211,33.5Q173.8,191.3,173.5,182Q139,182.5,139,181.5Q99.9,33.6,102.5,33Z
"  fill="rgba(255,134,0,1.000)" fill-rule="evenodd" stroke="transparent" stroke-width="1" stroke-opacity="1" ></path></svg>`

// creates image with 2dContext attached
var createImage= function(w,h){
    var image = document.createElement("canvas");  
    image.width = w;
    image.height =h; 
    image.ctx = image.getContext("2d");
    return image;
}  
// Setting width is in pixels
var outlineWidth = 8;
var outlineColour = "Yellow";

// Function to outline SVG image. Or any image 
function outline(){  // as this is the onload this is the image to outline
    var w = this.width + outlineWidth*2+2;  // get the new width and height
    var h = this.height + outlineWidth*2+2;
    var mask = createImage(w,h); // create the mask image
    mask.ctx.clearRect(0,0,w,h);  // Clear is You must do this for destination-atop to work
    mask.ctx.fillStyle = outlineColour;  // 
    mask.ctx.fillRect(0,0,w,h);  // fill the image with the outline colour
    mask.ctx.globalCompositeOperation = "destination-atop";  // now set so only pixels drawn on will show background colour
    mask.ctx.drawImage(this,outlineWidth+1,outlineWidth+1);
    // we now have a mask of the SVG in the colour we want
  
    var outlined = createImage(w,h);   // create the final image
    // draw an outline by drawing a circle with the mask
    for(var i = 0; i < Math.PI*2; i+= (Math.PI*2)/(outlineWidth*2)){
        var x = Math.cos(i)*outlineWidth+outlineWidth+1;
        var y = Math.sin(i)*outlineWidth+outlineWidth+1;
        outlined.ctx.drawImage(mask,x,y);
    }
    // draw the SVG in the center of the outline
    outlined.ctx.drawImage(this,outlineWidth*2+1,outlineWidth*2+1);    
     // done so show the world
    var output = document.getElementById("resultImage");
    output.src = outlined.toDataURL();
    
}

var svgImage = new Image();
svgImage.onload = outline;
svgImage.src = "data:image/svg+xml;base64,"+btoa(svg);
var input = document.getElementById("inImg");
input.src = "data:image/svg+xml;base64,"+btoa(svg);
SVG outlined<br>Outlined image will appear below the original<br>
<img id="inImg">
<img id="resultImage">

Upvotes: 1

gcandal
gcandal

Reputation: 957

I guess using strokes is what you're looking for.

Upvotes: 0

Related Questions