kimizuka.hatenablog.com
前回 からの改修点
- 実装をクラス風に改良しました。
- imageDataのコピーを取りました。(以前のものは右下ほどぼけてました)
JavaScript
(function(win, doc) {
"use Strict";
function Blur(elm) {
var that = this;
_init();
function _init() {
that.elm = elm;
that.img = new Image();
that.canvas = doc.createElement("canvas");
that.ctx = that.canvas.getContext("2d");
that.src = doc.defaultView.getComputedStyle(elm, null)["background-image"].replace(/^url\(/, "").replace(/\)$/, "").replace(/'|"/g, "");
that.imgData = null;
that._temp = {};
that.img.onload = that._handleOnLoad.bind(that);
that.draw();
}
}
Blur.CONST = {
ZOOM : 1,
LEVEL : 11
};
Blur.prototype._handleOnLoad = _handleOnLoad;
Blur.prototype._blur = _blur;
Blur.prototype._separateSide = _separateSide;
Blur.prototype._getCenterIndex = _getCenterIndex;
Blur.prototype.draw = draw;
function _handleOnLoad() {
var that = this,
startTime = Date.now(),
zoom = Blur.CONST.ZOOM,
width = that.img.width * zoom | 0,
height = that.img.height * zoom | 0,
level = Blur.CONST.LEVEL;
posList = [];
that.canvas.width = width;
that.canvas.height = height;
that.ctx.drawImage(that.img, 0, 0, width, height);
that.imgData = that.ctx.getImageData(0, 0, width, height);
that._temp.data = that.imgData.data;
that._temp.originalData = [].slice.call(that._temp.data);
for (var i = 0, length = that._temp.data.length; i < length; i += 4 | 0) {
that._temp.count = 0;
that._temp.r = 0;
that._temp.g = 0;
that._temp.b = 0;
for (var j = 0, jLength = level * level; j < jLength; ++j | 0) {
posList[j] = i + (4 * ((j / level | 0) - (level / 2 | 0))) * width + (4 * (j % level) - (level - 1) * 2);
}
if (level > 1) {
that._separateSide(posList, level, width, height);
}
that._blur(posList, length, i);
}
that.imgData.data = [];
that.ctx.putImageData(that.imgData, 0, 0);
that.elm.style["background-image"] = "url(" + that.canvas.toDataURL("image/png") + ")";
that._temp = {};
}
function _blur(arr, dataLength, index) {
var that = this;
for (var i = 0, length = arr.length; i < length; ++i | 0) {
if (0 <= arr[i] && arr[i] < dataLength) {
++that._temp.count;
that._temp.r += that._temp.originalData[arr[i] + 0];
that._temp.g += that._temp.originalData[arr[i] + 1];
that._temp.b += that._temp.originalData[arr[i] + 2];
}
}
that._temp.data[index + 0] = that._temp.r / that._temp.count;
that._temp.data[index + 1] = that._temp.g / that._temp.count;
that._temp.data[index + 2] = that._temp.b / that._temp.count;
}
function _separateSide(arr, level, width, height) {
var that = this,
centerIndex = that._getCenterIndex(arr) / 4,
levelLength = (level - 1) / 2;
(function _separateLeft() {
for (var k = 0; k < levelLength; ++k | 0) {
if (centerIndex % width === k) {
for (var i = 0; i < level; ++i | 0) {
for (var j = 0; j < levelLength - k; ++j | 0) {
arr[i * level + j] = -1;
}
}
}
}
})();
(function _separateRight() {
for (var k = 0; k < levelLength; ++k | 0) {
if ((centerIndex + 1 + k) % width === 0) {
for (var i = 0; i < level; ++i | 0) {
for (var j = 0; j < levelLength - k; ++j | 0) {
arr[(level - 1) + level * i - j] = -1;
}
}
}
}
})();
}
function _getCenterIndex(arr) {
return arr[arr.length / 2 | 0];
}
function draw() {
var that = this;
that.img.src = that.src;
}
win.Blur = Blur;
})(this, document);
(function(win, doc) {
"use strict";
new Blur(doc.body);
})(this, document);