<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Canvas 佛祖身后的璀璨佛光(分形艺术)</title>
<style>
html,
body {
background: black;
height: 100%;
overflow: hidden;
color: white;
}
.controls {
position: absolute;
top: 0;
right: 0;
z-index: 2;
background: #000;
color: #fff;
font-family: sans-serif;
text-transform: uppercase;
padding: 10px;
box-shadow: 0 0 0 2px #fff;
font-size: 12px;
}
.controls label,
.controls input {
display: block;
}
img {
position: absolute;
height: 0;
width: 0;
}
canvas {
position: absolute;
top: 50%;
left: 50%;
height: 100vmin;
width: 100vmin;
margin: -50vmin;
}
input[type='range'] {
-webkit-align-self: center;
-ms-flex-item-align: center;
align-self: center;
border: solid 0 transparent;
border-width: 0 1em;
padding: 0;
width: 10;
height: 0.9em;
background: none;
font-size: 1em;
cursor: pointer;
overflow: visible;
color: #fff;
}
input[type='range'],
input[type='range']::-webkit-slider-runnable-track,
input[type='range']::-webkit-slider-thumb {
-webkit-appearance: none;
}
input[type='range']::-webkit-slider-runnable-track {
position: relative;
width: 10;
height: 0.3em;
background: -webkit-linear-gradient(#fff, #fff) no-repeat 50% 0;
background: linear-gradient(#fff, #fff) no-repeat 50% 0;
background-size: 10 0.3em;
}
input[type='range']::-moz-range-track {
width: 10;
height: 0.3em;
background: linear-gradient(#fff, #fff) no-repeat 50% 0;
background-size: 10 0.3em;
}
input[type='range']::-ms-track {
margin-left: 0.5em;
border: none;
width: 10;
height: 0.3em;
background: linear-gradient(#fff, #fff) no-repeat 50% 0;
background-size: 9.875em 0.3em;
color: transparent;
}
input[type='range']::-webkit-slider-thumb {
position: relative;
margin-top: -0.35em;
border: none;
border-radius: 50%;
background: currentColor;
width: 1em;
height: 1em;
}
input[type='range']::-moz-range-thumb {
border: none;
border-radius: 50%;
background: currentColor;
width: 0.125em;
height: 0.125em;
}
input[type='range']::-ms-thumb {
border: none;
border-radius: 50%;
background: currentColor;
width: 1em;
height: 1em;
}
input[type='range']::-ms-tooltip {
display: none;
}
input[type='range']:focus {
outline: none;
}
/* Chrome/ Opera */
input[type='range']:not(*:root) {
width: 10.875em;
}
/* IE */
_:-ms-input-placeholder,
:root input[type='range'] {
width: 10.875em;
}
</style>
</head>
<body>
<img id="monk" src="img/monk.jpg" />
<canvas id="$"></canvas>
<div class="controls">
<label>change the pattern</label>
<input id="patt" type="range" min="17" max="31" value="23" step="2" />
</div>
<script>
// create context
'use strict';
var patt = document.getElementById('patt');
var $$ = document.getElementById('$');
var $ = $$.getContext('2d');
var monk = document.getElementById('monk');
$$.height = 1000;
$$.width = 1000;
// Converts from degrees to radians.
Math.rad = function(degrees) {
return degrees * Math.PI / 180;
};
// Converts from radians to degrees.
Math.deg = function(radians) {
return radians * 180 / Math.PI;
};
var iterations = 4;
var distance = 1;
var sides = patt.value;
var alpha = 0.2;
var drawLast = false;
patt.addEventListener('change', function() {
sides = patt.value;
if (sides < 20) {
alpha = 0.3;
distance = 0.8;
} else if (sides > 25) {
alpha = 0.12;
distance = 1.1;
} else {
alpha = 0.2;
distance = 1;
}
draw();
});
var fractal = function fractal(pos, size, n, r) {
if (n > 0) {
var x = Math.round(pos[0] - Math.cos(Math.rad(360 / sides * (r + 0.5) - 90)) * size * (Math.cos(Math.rad(45)) * (distance + Math.cos(Math.rad(45 / iterations * n)) * distance * 2)));
var y = Math.round(pos[1] - Math.sin(Math.rad(360 / sides * (r + 0.5) - 90)) * size * (Math.sin(Math.rad(45)) * (distance + Math.cos(Math.rad(45 / iterations * n)) * distance * 2)));
if (n === iterations) {
x = Math.round(pos[0]);
y = Math.round(pos[1]);
}
$.lineWidth = 0.5;
$.beginPath();
$.arc(x, y, size, 0, Math.PI * 2, false);
$.strokeStyle = 'hsla(' + (50 * n * r + 45) + ',100%,55%,' + alpha + ')';
if (!drawLast) {
$.stroke();
} else if (n === 1) {
$.stroke();
}
var newSize = Math.round(size / 2);
for (var i = 0; i < sides; i++) {
fractal([x, y], newSize, n - 1, i);
}
}
};
var draw = function draw() {
$.fillStyle = 'hsla(0,0%,0%,1)';
$.globalCompositeOperation = 'source-over';
$.fillRect(0, 0, $$.width, $$.height);
$.globalCompositeOperation = 'lighten';
fractal([$$.width / 2, $$.height / 2], Math.min($$.width, $$.height) / 4, iterations, 1);
$.globalCompositeOperation = 'color-burn';
$.drawImage(monk, $$.width / -30, $$.height / -30, $$.width, $$.height);
};
draw();
monk.onload = function() {
draw();
};
</script>
</body>
</html>