A while back, I coded the CBC (Canadian Broadcasting Corporation) logo with a quick css-doodle implementation. There are certainly better ways to do it, but I chose to stack several black boxes and circles, because the background color was black, those black boxes ended up becoming "invisible" as desired.
You can see how it works by using a different background other than black.
I couldn't find an elegant way to not use the black color, and I was reluctant to use CSS masks since it would require more calculations.
One solution
It just hit me tonight that I could use shaders to get rid of the black color, and it's so simple.
In css-doodle, code can generate images in real time, which can be used as textures and fed into shaders for additional effects.
background: @shaders(
texture_0 {
/* css-doodle code */
}
fragment {
/* glsl code */
}
)This is the old implementation.
@grid: 13x1 / 240px;
@place: center;
@size: 30%;
background: #000 @svg(
viewBox: -1 -1 2 2;
circle { r: .9; fill: red }
);
translate: @pn(
-75% 0, 75% 0, 0 -75%, 0 75%,
-50% 50%, 50% 50%, 50% -50%, -50% -50%,
-50% 0, 50% 0, 0 -50%, 0 50%,
0 0
);Turn it into a texture and mask out all the black pixels.
@grid: 1 / 240px / @shaders(
texture_0 {
@grid: 13x1 / 100%;
@place: center;
@size: 30%;
background: #000 @svg(
viewBox: -1 -1 2 2;
circle { r: .9; fill: red }
);
translate: @pn(
-75% 0, 75% 0, 0 -75%, 0 75%,
-50% 50%, 50% 50%, 50% -50%, -50% -50%,
-50% 0, 50% 0, 0 -50%, 0 50%,
0 0
);
}
fragment {
void main() {
vec2 uv = gl_FragCoord.xy / u_resolution.xy;
vec4 c = texture(texture_0, uv);
float b = length(c.rgb);
float alpha = smoothstep(0.0, 1.0, b);
FragColor = vec4(c.rgb, c.a * alpha);
}
}
);The difference blending mode
I often use blend modes to create some combinations of shapes.
The tricky part, though, is working with color. While there are some predictable patterns,
the results of different color combinations can be hard to anticipate.
So most of the time, I just use white color with the difference blend mode,
which produces black-and-white patterns.
@grid: 8x1 / 240px / #f90 +.8;
@place: @plot(r: .5);
@size: 50%;
background: #fff;
border-radius: 50%;
mix-blend-mode: difference;Now I can directly remove the black color and make the pattern transparent, it becomes much more usable.
@grid: 1 / 240px / #f90;
background: @shaders(
texture_0 {
@grid: 8x1 / 100% +.8;
@place: @plot(r: .5);
@size: 50%;
background: #fff;
border-radius: 50%;
mix-blend-mode: difference;
}
fragment {
void main() {
vec2 uv = gl_FragCoord.xy / u_resolution.xy;
vec4 c = texture(texture_0, uv);
float b = length(c.rgb);
float alpha = smoothstep(0.0, 2.0, b);
FragColor = vec4(c.rgb, c.a * alpha);
}
}
);This approach isn’t anything special, after all, shaders are naturally good at handling colors, but it still brings me joy.