我正在使用SVG使用路径制作自定义形状:
e.g。 <path d="M 180,160 0,218 0,0 180,0 z" >
我还使用snap.svg将该路径转换为:
m 180,34.57627 -180,0 L 0,0 180,0 z
我想要实现的是使用画布填充该路径,我使用javascript制作动画并将其设置在形状内,并在悬停时使用形状进行转换。
有没有办法做到这一点?
答案 0 :(得分:0)
根据您的具体需求,您有多种选择。以下是其中一些选择:
<foreignObject>
将画布直接附加到svg中,然后在其上使用clipPath,但这会限制对IE&gt; = 11的支持。
data_stack[, Weighted_average := c((10*0.2 + 60*0.8),(20*0.3 + 70*0.7),(30*0.4 + 80*0.6),(40*0.4 + 80*0.4 + 100*0.2))]
data_stack
CompA_value CompB_value CompC_value CompA_weight CompB_weight CompC_weight Weighted_average
1: 10 60 NA 0.2 0.8 NA 50
2: 20 70 NA 0.3 0.7 NA 55
3: 30 80 NA 0.4 0.6 NA 60
4: 40 80 100 0.4 0.4 0.2 68
&#13;
<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>
&#13;
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();
&#13;
canvas {
position: absolute;
z-index: 0;
}
svg {
position: absolute;
z-index: 1;
}
&#13;
<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>
构造函数,这在canvas API的早期实现中不受支持,但您也可以使用不同的函数调用实现相同的功能,或者甚至存在一些Path2D polyfill。
Path2D
&#13;
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 really needed with 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();
&#13;