Open JChehe opened 6 years ago
原文:Piet Mondrian
用代码复现皮特·蒙德里安的艺术作品并不是件简单的事情。老实说,我认为没有方法能复现他的作品,毕竟它们都是手绘的。但我们可以尝试复现皮特作品的部分工作,这也是本教程要阐述的部分。当然,我们也会进行上色。
老规矩,以下是初始化代码,其中包括设置 canvas 大小和使用 window.devicePixelRatio 缩放 canvas 以适配视网膜屏幕。而页面中仅有一个 <canvas> 元素。
window.devicePixelRatio
<canvas>
var canvas = document.querySelector('canvas'); var context = canvas.getContext('2d'); var size = window.innerWidth; var dpr = window.devicePixelRatio; canvas.width = size * dpr; canvas.height = size * dpr; context.scale(dpr, dpr); context.lineWidth = 8;
我采取的方法并不是完美的。首先创建一个大方块(canvas),然后将它进行分割。我会选择一条线(水平或竖直)将其分为多个方块,后续会为分割操作添加随机因子,而不是将所有方块都进行分割,这样应该能呈现出蒙德里安的风格,尽管会有数学上死板的感觉。
创建一组方块。
var squares = [{ x: 0, y: 0, width: size, height: size }];
一如既往地创建 “draw” 函数并进行调用。这样就能我们所做的东西。
function draw() { for (var i = 0; i < squares.length; i++) { context.beginPath(); context.rect( squares[i].x, squares[i].y, squares[i].width, squares[i].height ); context.stroke(); } } draw()
这会遍历所有方块(目前仅有一个方块,并绘制在 canvas 上)。
现在,创建一个用于寻找在哪个方块进行分割的函数,该函数会在我们指定的方向上对方块进行分割。
function splitSquaresWith(coordinates) { // 遍历找出需要进行分割的方块 } function splitOnX(square, splitAt) { // 基于提供的 x 坐标,创建两个新方块 } function splitOnY(square, splitAt) { // 基于提供的 y 坐标,创建两个方块 } splitSquaresWith({x: 160}) splitSquaresWith({y: 160})
代码末尾调用了分割方块的函数,分别在 x、y 的中间位置。若代码能正常运行,我们就可以做更多的分裂操作。但就目前而言,更适合试验。
splitSquaresWith 函数:
splitSquaresWith
const { x, y } = coordinates; for (var i = squares.length - 1; i >= 0; i--) { const square = squares[i]; if (x && x > square.x && x < square.x + square.width) { squares.splice(i, 1); splitOnX(square, x); } if (y && y > square.y && y < square.y + square.height) { squares.splice(i, 1); splitOnY(square, y); } }
这里使用了一些小技巧:
const { x, y } = coordinates
x
y
{x: 160}
{y: 160}
(var i = squares.length - 1; i >= 0; i--)
当然,现在还是仅有一个方块,这是因为 splitOn 函数还未实现。实质上两者(splitOnX 和 splitOnY)非常相似。
splitOn
splitOnX
splitOnY
var squareA = { x: square.x, y: square.y, width: square.width - (square.width - splitAt + square.x), height: square.height }; var squareB = { x: splitAt, y: square.y, width: square.width - splitAt + square.x, height: square.height }; squares.push(squareA); squares.push(squareB);
和
var squareA = { x: square.x, y: square.y, width: square.width, height: square.height - (square.height - splitAt + square.y) }; var squareB = { x: square.x, y: splitAt, width: square.width, height: square.height - splitAt + square.y }; squares.push(squareA); squares.push(squareB);
这两个函数均将先前的一个方块分割成两个方块,并将创建的方块添加到 squares 数组中。通过两次居中分割,最终形成了一个窗口。
squares
取消两次硬编码的分割调用,通过 step 变量,遍历多次进行分割。
step
var step = size / 6;
然后循环遍历。
for (var i = 0; i < size; i += step) { splitSquaresWith({ y: i }); splitSquaresWith({ x: i }); }
这就有了多个方块。通过添加随机因子,将原来每次 100% 分割变为 50% 的机会进行分割。
if(Math.random() > 0.5) { squares.splice(i, 1); splitOnX(square, x); }
哇喔,看起来不错。y 轴同理。
if(Math.random() > 0.5) { squares.splice(i, 1); splitOnY(square, y); }
这就是我们想要的形状和结构!与往常一样,所有教程均可点击编辑器与案例之间的小箭头,让代码重新运行(译者注:原文可体验)。每次点击均可看到不同形状的蒙德里安结构。
现在,让我们为它赋予色彩。首先,定义变量。使用漂亮的红蓝黄色。
var white = '#F2F5F1'; var colors = ['#D40920', '#1356A2', '#F7D842']
我们随机选择三个方块,为它们各自赋予一种颜色。你可能会看到仅有 1 或 2 种颜色,这是因为同一个方块被随机选中了两次以上。
for (var i = 0; i < colors.length; i++) { squares[Math.floor(Math.random() * squares.length)].color = colors[i]; }
当然,还需要确保在 draw 函数内进行填充操作。
if(squares[i].color) { context.fillStyle = squares[i].color; } else { context.fillStyle = white } context.fill()
美丽的色彩!
基于网格,你可以轻松增加或减少复杂性。
var step = size / 20;
var step = size / 4;
var step = size / 7;
这就是我们拥有的蒙德里安作品。
原文:Piet Mondrian
用代码复现皮特·蒙德里安的艺术作品并不是件简单的事情。老实说,我认为没有方法能复现他的作品,毕竟它们都是手绘的。但我们可以尝试复现皮特作品的部分工作,这也是本教程要阐述的部分。当然,我们也会进行上色。
老规矩,以下是初始化代码,其中包括设置 canvas 大小和使用
window.devicePixelRatio
缩放 canvas 以适配视网膜屏幕。而页面中仅有一个<canvas>
元素。我采取的方法并不是完美的。首先创建一个大方块(canvas),然后将它进行分割。我会选择一条线(水平或竖直)将其分为多个方块,后续会为分割操作添加随机因子,而不是将所有方块都进行分割,这样应该能呈现出蒙德里安的风格,尽管会有数学上死板的感觉。
创建一组方块。
一如既往地创建 “draw” 函数并进行调用。这样就能我们所做的东西。
这会遍历所有方块(目前仅有一个方块,并绘制在 canvas 上)。
现在,创建一个用于寻找在哪个方块进行分割的函数,该函数会在我们指定的方向上对方块进行分割。
代码末尾调用了分割方块的函数,分别在 x、y 的中间位置。若代码能正常运行,我们就可以做更多的分裂操作。但就目前而言,更适合试验。
splitSquaresWith
函数:这里使用了一些小技巧:
const { x, y } = coordinates
会提取对象的x
和y
变量,如{x: 160}
或{y: 160}
。(var i = squares.length - 1; i >= 0; i--)
逆序遍历方块,是为了让新元素剔除出循环(分割操作会将一个方块替换为两个)。逆序遍历意味着在遍历下标无需调整的同时,避免新方块不会被再次分割。当然,现在还是仅有一个方块,这是因为
splitOn
函数还未实现。实质上两者(splitOnX
和splitOnY
)非常相似。splitOnX
和
splitOnY
这两个函数均将先前的一个方块分割成两个方块,并将创建的方块添加到
squares
数组中。通过两次居中分割,最终形成了一个窗口。取消两次硬编码的分割调用,通过
step
变量,遍历多次进行分割。然后循环遍历。
这就有了多个方块。通过添加随机因子,将原来每次 100% 分割变为 50% 的机会进行分割。
哇喔,看起来不错。
y
轴同理。这就是我们想要的形状和结构!与往常一样,所有教程均可点击编辑器与案例之间的小箭头,让代码重新运行(译者注:原文可体验)。每次点击均可看到不同形状的蒙德里安结构。
现在,让我们为它赋予色彩。首先,定义变量。使用漂亮的红蓝黄色。
我们随机选择三个方块,为它们各自赋予一种颜色。你可能会看到仅有 1 或 2 种颜色,这是因为同一个方块被随机选中了两次以上。
当然,还需要确保在 draw 函数内进行填充操作。
美丽的色彩!
基于网格,你可以轻松增加或减少复杂性。
这就是我们拥有的蒙德里安作品。