我正在研究一种看起来像熔岩灯的东西。不幸的是,我在开始时已经失败了:
我设法创建随机生成的blob,但我无法应用填充。中风工作得很好。
这是创建blob的相关代码:
var ctx = this; // context
this.path = d3.areaRadial()
.angle(function(d) {return d.theta})
.radius(function(d) {return d.r})
.curve(d3.curveCatmullRomClosed.alpha(1));
// create the blob
this.create = function() {
var anchors = [];
for (var i = 0; i < ctx.options.anchors; i++) {
var currTheta = i * (360 / ctx.options.anchors) + rand(ctx.options.spread.theta);
var currRadians = Math.radians(currTheta);
var currRadius = ctx.options.radius + rand(ctx.options.spread.r);
anchors.push({theta: currRadians, r: currRadius});
}
var pathData = ctx.path(anchors);
d3.select(ctx.options.target).append('path')
.attr('d', pathData)
.attr('class', 'blob')
.style('opacity', ctx.options.opacity)
.style('transform', 'translate(' + ctx.x + 'px, ' + ctx.y + 'px)')
.attr('transform', 'translate(' + ctx.x + 'px, ' + ctx.y + 'px)');
console.log(pathData);
}
function rand(x) // creates a random number between -0.5 * x and 0.5 * x
完整代码:https://codepen.io/normanwink/pen/BrMVrE
谢谢!
答案 0 :(得分:2)
这是预期的行为,因为您正在使用radius,即:
等同于area.y,除了访问者返回半径:距原点的距离⟨0,0⟩。
对于area.y
:
如果指定y,将y0设置为y,将y1设置为null 并返回此区域生成器。如果未指定y,则返回当前的y0访问器。 (强调我的)
因此,您可能需要outerRadius
。
this.path = d3.areaRadial()
.angle(function(d) {
return d.theta
})
.outerRadius(function(d) {
return d.r
})
.curve(d3.curveCatmullRomClosed.alpha(1));
这是您的代码仅包含该更改:
(function() {
"use strict";
// window size
var windowX = window.innerWidth;
var windowY = window.innerHeight;
var svgX = windowX;
var svgY = windowY;
var blobCount = 1;
function init() {
// console.log(new Blob());
var svg = d3.select('#svg')
.attr('viewBox', '0 0 ' + svgX + ' ' + svgY)
.attr('preserveAspectRatio', 'xMinYMin meet');
for (var i = 0; i < blobCount; i++) {
var newBlob = new Blob(svgX * 0.5, svgY * 0.5);
}
}
function Blob(x, y) {
var ctx = this; // context
this.options = {
anchors: 8,
breathe: 30,
fill: '#ffffff',
opacity: 0.5,
radius: 150,
spread: {
theta: 10, // angle
r: 300 // radius
},
target: '#svg',
};
this.x = x || 0;
this.y = y || 0;
this.path = d3.areaRadial()
.angle(function(d) {return d.theta})
.outerRadius(function(d) {return d.r})
.curve(d3.curveCatmullRomClosed.alpha(1));
// create the blob
this.create = function() {
var anchors = [];
for (var i = 0; i < ctx.options.anchors; i++) {
var currTheta = i * (360 / ctx.options.anchors) + rand(ctx.options.spread.theta);
var currRadians = Math.radians(currTheta);
var currRadius = ctx.options.radius + rand(ctx.options.spread.r);
anchors.push({theta: currRadians, r: currRadius});
}
var pathData = ctx.path(anchors);
d3.select(ctx.options.target).append('path')
.attr('d', pathData)
.attr('class', 'blob')
.style('opacity', ctx.options.opacity)
.style('transform', 'translate(' + ctx.x + 'px, ' + ctx.y + 'px)')
.attr('transform', 'translate(' + ctx.x + 'px, ' + ctx.y + 'px)');
}
// update position and anchor movement
this.update = function() {
}
// apply changes
this.render = function() {
}
this.create();
}
function rand(i) {
return (Math.random()-0.5) * (i || 1);
}
Math.radians = function(degrees) {
return degrees * Math.PI / 180;
};
// init when ready
init();
})();
#svg {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
}
.blob {
fill: blue; /* why is this not working? */
stroke: red;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg id="svg"></svg>
答案 1 :(得分:1)
您的问题是pathData
,因为如果您将.attr('d', pathData)
替换为有效路径.attr('d', 'M37,17v15H14V17z M50,0H0v50h50z')
,那么您的填充工作正常。
我会继续搜索这个问题,只是想给你一个提示,也许你会发现问题比我更快。 :)