用 JS 复制艺术
原文地址(original source):http://jsart.co/11/replicating-art-with-js/
作者(author):https://twitter.com/kodisha
YAYOI KUSAMA
Infinity-Dots [HOFS], 2014
Acrylic on canvas
130.3 x 97 cm
稍微扭曲的圆
它们有边界
越小的圆,扭曲得越多
今天我发现了一副美丽的绘画,经过一番研究,我找到了名字和作者。
(顺便说一句,可以浏览相同作品集的其它作品)
看起来真的不错,更重要的是,它貌似能够用 JavaScript 复制。
我花了一些时间观察,决定使用最简单的方法——带有少许改动的、某种正弦函数。对于资源库,我打算用平常的 JS。
细节
首先,让我们放大、看下图片本身的细节。
我们能够注意到:
本图或许给你留下这是一副“简单的”复制品,但不尽然。看下所有这些点,它们从来没有重叠。
甚至它看起来有一些像正弦波的主风格,它更像是艺术家用大量点做的纵向条纹,然后只是耐心地填充了其余部分(我的看法,或许我完全错了)。我做了少量测试。我现在明白了,为了达到几近完美的复制,我将不得不引入某种 hit-test【注1】,或者保留事先画好的点的位置。
我不想这样做,我想做一些类似于我能做的事情,只使用简单命令和纯粹的 JS。
结果
开干,我尝试了一些简单方法,下面是结果:

刚开始,没有经验的尝试,用了简单的正弦函数。
很明显这行不通,我尝试不覆盖圆,但是空隙太大了:
在接下来的截图里,我对空间做了尝试,只是当心不让圆重叠:
最后,加上一点点扭曲,变成了:
这是真正有趣的试验,即使我做不到在细节上做好复制,但是你能够用几行代码就能搞出某些真正好看的图像,这会给人留下深刻的印象。在我们的例子中,下面是输出最终图片的所有代码:
var canvas = document.getElementById('replica');
var ctx = canvas.getContext('2d');
var circle = function(radius, x, y) {
ctx.fillStyle = '#b50024';
ctx.strokeStyle = '#771522';
ctx.beginPath();
ctx.arc(x, y, radius, 0, Math.PI * 2);
ctx.stroke();
ctx.fill();
ctx.closePath();
};
var lastX = 0;
var fix = 0;
var width = 500;
var height = 677;
for (var i = 0; i < width; i += 2) {
var x = i / (width / 150);
var radius = 6 / (3 * (Math.exp(Math.sin(x))));
lastX = lastX + radius + radius + 3;
for (var j = 4; j < height; j += 2) {
var randOffset = ( 0.7 * radius) * Math.random();
var deviation = j / (height / 10 * (2 * height / j ));
var dOffset = Math.cos(j/(height/4)) * ((3.4 + (1.4 * (j/height)))
* Math.exp(Math.cos(deviation))) * (1.5 + (2 * ((3.2 * (i / width)) )
* Math.exp(Math.sin(deviation))));
if (j % 12 === 0) {
if (radius >= 3.4) {
circle(radius, lastX - dOffset, j + randOffset);
}
} else {
if (radius < (6 * Math.random())) {
circle(radius, lastX - dOffset, j + randOffset);
}
}
}
}本例的完整源代码,还可以点击在线 demo。
这是一次不同凡响的尝试。下次我将挑选一些不同的(但是同样有挑战性的)的例子,并尽量做同样的事情。
更新:
用户 blackle 在评论里留下了更好的实现,她的结果更加完美!
太棒了!你可以访问她的 demo。
注1:In computer graphics programming, hit-testing (hit detection, picking, or pick correlation) is the process of determining whether a user-controlled cursor (such as a mouse cursor or touch-point on a touch-screen interface) intersects a given graphical object (such as a shape, line, or curve) drawn on the screen. http://en.wikipedia.org/wiki/Hit-testing
建议继续学习:
- vim的复制粘贴小结 (阅读:7381)
- VIM复制粘贴的那些事 (阅读:4489)
- MySQL5.5复制/同步的新特性及改进 (阅读:4283)
- MySQL复制的概述、安装、故障、技巧、工具 (阅读:3899)
- 快速复制一张大表讨论 (阅读:3800)
- MySQL Cluster 与 MongoDB 复制及分片设计及原理 (阅读:3727)
- [MySQL优化案例] — slave延迟很大优化方法 (阅读:3503)
- Google Docs Ctrl + C 技术浅析 (阅读:2314)
- 在 Linux 上复制和重命名文件 (阅读:1357)
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:viviworld 来源: 腊八粥
- 标签: 复制
- 发布时间:2015-06-02 13:17:58
-
[927] WordPress插件开发 -- 在插件使用 -
[133] 解决 nginx 反向代理网页首尾出现神秘字 -
[52] 如何保证一个程序在单台服务器上只有唯一实例( -
[52] 整理了一份招PHP高级工程师的面试题 -
[50] 全站换域名时利用nginx和javascri -
[50] 海量小文件存储 -
[50] 用 Jquery 模拟 select -
[49] CloudSMS:免费匿名的云短信 -
[48] Innodb分表太多或者表分区太多,会导致内 -
[47] jQuery性能优化指南






