javascript - Fill svg path with canvas? -


i using svg make custom shape using path:

e.g. <path d="m 180,160 0,218 0,0 180,0 z" >

i use snap.svg transform path on hover to:

m 180,34.57627 -180,0 l 0,0 180,0 z

what want achieve fill path canvas animate javascript , make inside shape , transform shape on hover.

is there way that?

you have multiple choices depending on exact needs. here of these choices :

  • you use <foreignobject> append canvas directly in svg, use clippath on it, limit support ie>=11.

<svg id="svg" width="300" height="300" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">    <defs>      <style>        #clickhandler {          pointer-events: all;        }      </style>      <clippath id="myclip">        <path id="yourpath" d="m 180,160 0,218 0,0 180,0 z" />      </clippath>    </defs>    <foreignobject id="fo" width="100%" height="100%" clip-path="url(#myclip)">      <canvas xmlns="http://www.w3.org/1999/xhtml" id="canvas" width="600" height="300"></canvas>    </foreignobject>    <script>      var pathes = ["m 180,160 0,218 0,0 180,0 z", "m 180,34.57627 -180,0 l 0,0 180,0 z"]      var current = 0;      fo.onclick = function() {        current = (current + 1) % 2;        yourpath.setattribute('d', pathes[current]);      };       // canvas noise      var ctx = canvas.getcontext('2d');      var imagedata = ctx.createimagedata(300, 300);        function animcanvas() {        requestanimationframe(animcanvas);        imagedata.data.foreach(function(v, i, a) {          a[i] = math.random() * 255;        });        ctx.putimagedata(imagedata, 0, 0);      }      animcanvas();    </script>  </svg>

  • you place canvas behind svg css , absolute positioning, you'd have append background inside svg, path set mask, , copy of path handle mouse event. here you'd gain html5 browsers support, you'll loose in svg z-index positioning.

var pathes = ["m 180,160 0,218 0,0 180,0 z", "m 180,34.57627 -180,0 l 0,0 180,0 z"]  var current = 0;  clickhandler.onclick = function() {    current = (current + 1) % 2;    yourpath.setattribute('d', pathes[current]);  };  // canvas noise  var ctx = canvas.getcontext('2d');  var imagedata = ctx.createimagedata(300, 300);    function animcanvas() {    requestanimationframe(animcanvas);    imagedata.data.foreach(function(v, i, a) {      a[i] = math.random() * 255;    });    ctx.putimagedata(imagedata, 0, 0);  }  animcanvas();
canvas {    position: absolute;    z-index: 0;  }  svg {    position: absolute;    z-index: 1;  }
<canvas id="canvas" width="600" height="300"></canvas>  <svg id="svg" width="300" height="300" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">    <defs>      <style>        #clickhandler {          pointer-events: all;        }      </style>      <path id="yourpath" d="m 180,160 0,218 0,0 180,0 z" />      <rect id="bg" x="-1%" y="-1%" width="102%" height="102%" />      <mask id="mymask">        <use xlink:href="#bg" fill="white" />        <use xlink:href="#yourpath" fill="black" />      </mask>    </defs>      <use xlink:href="#bg" mask="url(#mymask)" fill="white" />    <use xlink:href="#yourpath" fill="none" id="clickhandler" />  </svg>

  • or on canvas.
    in below example, use path2d constructor, wasn't supported in earlier implementations of canvas api, can achieve same different functions calls, or there exist path2d polyfills.

var pathes = [    new path2d("m 180,160 0,218 0,0 180,0 z"),    new path2d("m 180,34.57627 -180,0 l 0,0 180,0 z")  ];  var current = 0;    canvas.onclick = function(evt) {    var x = evt.clientx - this.offsetleft,      y = evt.clienty - this.offsettop;      if (ctx.ispointinpath(pathes[current], x, y)) {      current = (current + 1) % 2;    }  };    function clipcanvas() {    ctx.globalcompositeoperation = 'destination-in';    ctx.fill(pathes[current]);    ctx.globalcompositeoperation = 'source-over'; // not needed putimagedata  }  // canvas noise  var ctx = canvas.getcontext('2d');  var imagedata = ctx.createimagedata(300, 300);    function animcanvas() {    requestanimationframe(animcanvas);    imagedata.data.foreach(function(v, i, a) {      a[i] = math.random() * 255;    });    ctx.putimagedata(imagedata, 0, 0);      clipcanvas();    }    animcanvas();
<canvas id="canvas" width="600" height="300"></canvas>


Comments

Popular posts from this blog

asynchronous - C# WinSCP .NET assembly: How to upload multiple files asynchronously -

aws api gateway - SerializationException in posting new Records via Dynamodb Proxy Service in API -

asp.net - Problems sending emails from forum -