Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

【译】欢乐分队—Joy Division #22

Open
JChehe opened this issue Aug 10, 2018 · 0 comments
Open

【译】欢乐分队—Joy Division #22

JChehe opened this issue Aug 10, 2018 · 0 comments

Comments

@JChehe
Copy link
Owner

JChehe commented Aug 10, 2018

原文:Joy Division

欢乐分队的专辑封面有一段非常有趣的历史。同时也是一个数据驱动艺术的惊艳案例。

Unknown Pleasures
欢乐分队的《Unknown Pleasures》专辑封面

这里我们打算使用 canvas 实现,没有额外 API。只需在 HTML 中放置一个 300x300 像素的 元素。

首先进行初始化,没有任何渲染操作。

var canvas = document.querySelector('canvas');
var context = canvas.getContext('2d');

var size = window.innerWidth;

canvas.width = size;
canvas.height = size;

这为我们提供了在页面上绘制的 context 上下文。

首先,在 canvas 上绘制由一系列点组成的线段。然后,将每个点替换成随机数,以达到期待的效果。

定义一些基本变量:

  • step:指定相邻点之间的距离,以像素为单位。
  • lines:存放线段的数组。
var step = 10;
var lines = [];

下面编写函数来生成线。线由一系列点(拥有 x、y 属性的对象)组成。

// Create the lines
for( var i = step; i <= size - step; i += step) {
    
  var line = [];
  for( var j = step; j <= size - step; j+= step ) {
    var point = {x: j, y: i};
    line.push(point)
  } 
  lines.push(line);
}

下一步是绘制线段。和 上篇教程 一样,我们先绘制简单的东西,然后再进行扩展。

// Do the drawing
for(var i = 0; i < lines.length; i++) {

  context.beginPath();
  context.moveTo(lines[i][0].x, lines[i][0].y)
  
  for( var j = 0; j < lines[i].length; j++) {
    context.lineTo(lines[i][j].x, lines[i][j].y);
  }

  context.stroke();
}

多条线段

现在,canvas 上就拥有多条线段。下一步是替换线段里的点。该操作将在第一层循环(创建点的时候)里执行。

var random = Math.random() * 10;
var point = {x: j, y: i + random};

每个点都发生了跳动

噢,现在线的每个点都发生了跳动。但我们期望这些变化集中在线的中间区域,即越靠近线中心的点变化幅度越大,两侧越小。下面通过一个独立函数实现。

var distanceToCenter = Math.abs(j - size / 2);
var variance = Math.max(size / 2 - 50 - distanceToCenter, 0);
var random = Math.random() * variance / 2 * -1;

交叉重叠

现在看起来有点混乱,每条线都存在交叉重叠。这里使用 fill 方法进行覆盖。

首先,设置填充的样式。

context.fillStyle = '#f9f9f9';
context.lineWidth = 2;

设置 fill 样式

然后在每条线绘制后执行 fill 方法,这将会覆盖每个图层下面混乱的线。

译者注:当路径是非封闭图形时,canvas 会直接连接始点和终点,从而形成封闭图形。

context.fill()

fill

快要完成了,唯一剩下的事情是让线看起来更圆滑。二次贝塞尔曲线可以做到这点,只需在两点之间创建一个控制点即可。quadraticCurveTo 就是最后一步。

for( var j = 0; j < lines[i].length - 2; j++) {
    var xc = (lines[i][j].x + lines[i][j + 1].x) / 2;
    var yc = (lines[i][j].y + lines[i][j + 1].y) / 2;
    context.quadraticCurveTo(lines[i][j].x, lines[i][j].y, xc, yc);
  }

  context.quadraticCurveTo(lines[i][j].x, lines[i][j].y, lines[i][j + 1].x, lines[i][j + 1].y);

最终作品——欢乐分队

我们最终得到它了!你可以对每个步骤进行调整,或者更改样式和颜色,从而得到不同效果。一切都令人兴奋!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant