p5js 剪贴蒙版等效?
p5js clipping mask equivalent?
我有一个超级简单的脚本,可以创建一个带有交替“切片”颜色的圆圈
let slices = 12;
function setup() {
createCanvas(400, 400);
noStroke();
}
function draw() {
background(220);
translate(width/2, height/2);
let inc = TWO_PI/slices;
let c = 0
for (let i = 0; i < TWO_PI+inc; i+=inc) {
if (c % 2 == 0) {
fill('white')
} else {
fill('black')
}
arc(0, 0, width/2, width/2, i, i+inc);
c++
}
}
我怎样才能用正方形(或三角形、六边形等)做同样的事情?也就是说,我想要交替的切片颜色,但封装在正方形而不是圆形中。我不确定如何执行此操作,因为我使用 arc()
创建切片。有什么方法可以制作面具之类的吗?或者有更简单的方法解决我的问题吗?
您可以使用 p5.Image
上的 mask()
功能将您的图案应用到任意形状。或者,您可以找到构成每个饼图切片的每条射线与形状周长的交点,并使用交点和形状的定义来构造一个适合指定形状的饼图切片,但这会很多比较复杂。
举个例子。单击可更改形状。
let slices = 12;
let pattern;
let masked;
let density;
const MaskTypes = ['circle', 'square', 'triangle', 'text'];
let ix = 0;
function setup() {
createCanvas(400, 400);
density = pixelDensity();
let g = createGraphics(width, height);
g.noStroke();
g.translate(width / 2, height / 2);
const inc = TWO_PI / slices;
// fill the screen
const d = sqrt(width * width + height * height);
let c = 0;
for (let i = 0; i < TWO_PI + inc; i += inc) {
if (c % 2 == 0) {
g.fill('white');
} else {
g.fill('black');
}
g.arc(0, 0, d, d, i, i + inc);
c++;
}
pattern = createImage(width * density, height * density);
pattern.copy(g, 0, 0, width, height, 0, 0, width * density, height * density);
updateMask();
}
function mouseClicked() {
ix = (ix + 1) % MaskTypes.length;
updateMask();
}
function updateMask() {
let m = makeMask(MaskTypes[ix]);
masked = createImage(width * density, height * density);
masked.copy(pattern, 0, 0, width * density, height * density, 0, 0, width * density, height * density);
masked.mask(m);
}
function makeMask(type) {
let g = createGraphics(width, height);
g.noStroke();
g.fill(0);
g.translate(width / 2, height / 2);
switch (type) {
case 'circle':
g.circle(0, 0, width / 2);
break;
case 'square':
g.rect(-width / 4, -height / 4, width / 2, height / 2);
break;
case 'triangle':
g.triangle(-width / 4, height / 4, 0, -height / 4, width / 4, height / 4);
break;
case 'text':
g.textAlign(CENTER, CENTER);
g.textSize(96);
g.text("Hello!", 0, 0);
break;
}
let mask = createImage(width * density, height * density);
mask.copy(g, 0, 0, width, height, 0, 0, width * density, height * density);
return mask;
}
function draw() {
background(220);
image(masked, 0, 0, width, height)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
我有一个超级简单的脚本,可以创建一个带有交替“切片”颜色的圆圈
let slices = 12;
function setup() {
createCanvas(400, 400);
noStroke();
}
function draw() {
background(220);
translate(width/2, height/2);
let inc = TWO_PI/slices;
let c = 0
for (let i = 0; i < TWO_PI+inc; i+=inc) {
if (c % 2 == 0) {
fill('white')
} else {
fill('black')
}
arc(0, 0, width/2, width/2, i, i+inc);
c++
}
}
我怎样才能用正方形(或三角形、六边形等)做同样的事情?也就是说,我想要交替的切片颜色,但封装在正方形而不是圆形中。我不确定如何执行此操作,因为我使用 arc()
创建切片。有什么方法可以制作面具之类的吗?或者有更简单的方法解决我的问题吗?
您可以使用 p5.Image
上的 mask()
功能将您的图案应用到任意形状。或者,您可以找到构成每个饼图切片的每条射线与形状周长的交点,并使用交点和形状的定义来构造一个适合指定形状的饼图切片,但这会很多比较复杂。
举个例子。单击可更改形状。
let slices = 12;
let pattern;
let masked;
let density;
const MaskTypes = ['circle', 'square', 'triangle', 'text'];
let ix = 0;
function setup() {
createCanvas(400, 400);
density = pixelDensity();
let g = createGraphics(width, height);
g.noStroke();
g.translate(width / 2, height / 2);
const inc = TWO_PI / slices;
// fill the screen
const d = sqrt(width * width + height * height);
let c = 0;
for (let i = 0; i < TWO_PI + inc; i += inc) {
if (c % 2 == 0) {
g.fill('white');
} else {
g.fill('black');
}
g.arc(0, 0, d, d, i, i + inc);
c++;
}
pattern = createImage(width * density, height * density);
pattern.copy(g, 0, 0, width, height, 0, 0, width * density, height * density);
updateMask();
}
function mouseClicked() {
ix = (ix + 1) % MaskTypes.length;
updateMask();
}
function updateMask() {
let m = makeMask(MaskTypes[ix]);
masked = createImage(width * density, height * density);
masked.copy(pattern, 0, 0, width * density, height * density, 0, 0, width * density, height * density);
masked.mask(m);
}
function makeMask(type) {
let g = createGraphics(width, height);
g.noStroke();
g.fill(0);
g.translate(width / 2, height / 2);
switch (type) {
case 'circle':
g.circle(0, 0, width / 2);
break;
case 'square':
g.rect(-width / 4, -height / 4, width / 2, height / 2);
break;
case 'triangle':
g.triangle(-width / 4, height / 4, 0, -height / 4, width / 4, height / 4);
break;
case 'text':
g.textAlign(CENTER, CENTER);
g.textSize(96);
g.text("Hello!", 0, 0);
break;
}
let mask = createImage(width * density, height * density);
mask.copy(g, 0, 0, width, height, 0, 0, width * density, height * density);
return mask;
}
function draw() {
background(220);
image(masked, 0, 0, width, height)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>