用 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的复制粘贴小结 (阅读:6538)
- VIM复制粘贴的那些事 (阅读:4092)
- MySQL5.5复制/同步的新特性及改进 (阅读:3778)
- MySQL Cluster 与 MongoDB 复制及分片设计及原理 (阅读:3233)
- MySQL复制的概述、安装、故障、技巧、工具 (阅读:3265)
- 快速复制一张大表讨论 (阅读:3205)
- [MySQL优化案例] — slave延迟很大优化方法 (阅读:2739)
- Google Docs Ctrl + C 技术浅析 (阅读:1789)
- 在 Linux 上复制和重命名文件 (阅读:841)
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:viviworld 来源: 腊八粥
- 标签: 复制
- 发布时间:2015-06-02 13:17:58
- [71] IOS安全–浅谈关于IOS加固的几种方法
- [70] Twitter/微博客的学习摘要
- [65] 如何拿下简短的域名
- [64] android 开发入门
- [63] Go Reflect 性能
- [62] find命令的一点注意事项
- [60] 流程管理与用户研究
- [59] 图书馆的世界纪录
- [59] 读书笔记-壹百度:百度十年千倍的29条法则
- [58] Oracle MTS模式下 进程地址与会话信