Skip to content

Instantly share code, notes, and snippets.

@riix
Created August 31, 2017 08:32
Show Gist options
  • Save riix/ff953ecf312e1a0f0f22f92811266225 to your computer and use it in GitHub Desktop.
Save riix/ff953ecf312e1a0f0f22f92811266225 to your computer and use it in GitHub Desktop.
_motionBlur.js
<div class="container">
<div id="test1" class="js-blur" data-blur-multiplier="0.9" data-blur-dir="x" style="position: absolute; top: 0; left: 0;">
<img class="js-img-placeholder" src="about: blank" />
<img class="js-img-placeholder" src="about: blank" />
<img class="js-img-placeholder" src="about: blank" />
</div>
<div id="test2" class="js-blur" data-blur-multiplier="0.9" data-blur-dir="y" style="position: absolute; margin-top: 250px; top: 0;">
<img class="js-img-placeholder" src="about: blank" />
<img class="js-img-placeholder" src="about: blank" />
<img class="js-img-placeholder" src="about: blank" />
</div>
</div>
<div class="action">
<a href="#test1" class="button js-toggle-el"><span>ToggleX</span></a>
<a href="#test2" class="button js-toggle-el"><span>ToggleY</span></a>
</div>
(function($){
var $document = $document || $(document);
var blurDefaults = { // 블러 기본 옵션
multiplier: 0.25, // 승수
dir: 'x', // blur 방향 적용
html: [ // blur svg html 생성
'<svg xmlns="http://www.w3.org/2000/svg" version="1.1" class="filters hidden">',
'<defs id="defs">',
'<filter id="blur" x="0%" y="0" width="100%" height="100%">',
'<feGaussianBlur in="SourceGraphic" stdDeviation="0,0" />',
'</filter>',
'</defs>',
'</svg>'
]
};
var isBlurUpdating = false,
timerBlurUpdating = null;
$.fn.extend({
toggleBlur: function(_bool) { // toggle blur
this.each(function(){
var $this = $(this),
_blurId = $this.data("blur-id"),
_value = _bool ? "url(#" + _blurId + ")" : "none";
$this.css({
webkitFilter: _value,
filter: _value
});
});
},
setBlur: function(_dir, _value) { // set blur
this.each(function(){
var $this = $(this),
_blur = $this.data("blur"),
_str = '';
_value = Math.round(_value);
if ($this.data("blur-value") !== _value) {
if (_value == 0) {
$this.toggleBlur(false);
} else {
$this.toggleBlur(true);
if (_dir == 'y') {
_str = "0," + _value;
} else {
_str = _value + ",0";
}
_blur.firstElementChild.setAttribute("stdDeviation", _str);
$this.data("blur-value", _value);
}
}
});
}
});
$.extend({
blur: {
update: function(){
$(".js-blur").each(function() {
var $this = $(this),
_pos = $this.offset(),
_lastPos = $this.data('blur-last-pos'),
_dir = $this.data('blur-dir'),
_multiplier = $this.data('blur-multiplier'), // 승수, 기본 0.25
_value = (_dir == 'y') ? _pos.top - _lastPos.top : _pos.left - _lastPos.left;
_value =(Math.abs(_value) * _multiplier).toFixed(1);
$this.data("blur-last-pos", _pos);
$this.setBlur(_dir, _value);
});
if (isBlurUpdating) {
requestAnimationFrame($.blur.update); // requestAnimationFrame
}
},
start: function(){
if (typeof stopDelay == "undefined") {
stopDelay = -1;
}
if (timerBlurUpdating != null) {
clearTimeout(timerBlurUpdating);
timerBlurUpdating = null;
}
if (isBlurUpdating !== true) {
isBlurUpdating = true;
$.blur.update(); // update
}
if (stopDelay > -1) {
timerBlurUpdating = setTimeout($.blur.stop, stopDelay);
}
},
stop: function(){
isBlurUpdating = false;
},
init: function(_el, _options){
var _opts = blurDefaults; // set opts
$.extend(_opts, _options); // merge _options into _opts
var _replaceCustomData = function(_el, _data, _value){ // custom data 가 없을 경우에만 생성 (존재하는 custom data 가 우선함)
if (_el.data(_data) !== undefined) return false; // 존재할 경우 skip
_el.data(_data, _value);
};
if (!$('#blur').length) {
$('body').prepend(_opts.html.join('')); // blur svg html 생성
}
var $html = $html || $('html'), // set elements
$blur = $('#blur'),
$$blur = $blur.get(0),
$$defs = $("#defs").get(0);
$html.addClass('is-blur-init'); // html class init
_el.each(function(i) {
var $this = $(this),
$$blurClone = $$blur.cloneNode(true),
_blurId = "blur" + i;
_replaceCustomData($this, 'blur-multiplier', _opts.multiplier); // custom data 가 없을 경우에만 생성 (존재하는 custom data 가 우선함)
_replaceCustomData($this, 'blur-dir', _opts.dir);
if ($this.data('blur-dir') == 'y') { // blur 방향 조절, 세로일때
$$blurClone.setAttribute("y", "-20%");
$$blurClone.setAttribute("height", "140%");
} else {
$$blurClone.setAttribute("x", "-20%");
$$blurClone.setAttribute("width", "140%");
}
$$blurClone.setAttribute("id", _blurId);
$$defs.appendChild($$blurClone);
$this
.data("blur", $$blurClone)
.data("blur-id", _blurId)
.data("blur-value", 0)
.data("blur-last-pos", $this.offset());
});
}
}
});
})(window.jQuery);
$(function(){
var $document = $document || $(document);
$.extend({
/*
$.toggleElementClass($target);
$.toggleElementClass($target, 'in', 'out');
$(document).on('click', '.js-toggle-el', function(e){
var $this = $(e.target);
$this = ($this.is('a')) ? $this : $this.closest('a');
var $target = $($this.attr('href'));
$.toggleElementClass($target);
});
*/
toggleElementClass: function(_el, _class, _classReverse){
_class = _class || 'in';
_classReverse = _classReverse || 'out';
_el.toggleClass(_class);
_el.toggleClass(_classReverse, (!_el.hasClass(_class)));
},
});
$.fn.extend({
/*
image place holder
$('.js-img-placeholder').imgPlaceHolder();
*/
imgPlaceHolder: function(_el){
var _host = 'https://placeimg.com/';
this.each(function(i){
var $this = $(this);
$this = $this.filter('img');
var _width = $this.width(),
_height = $this.height(),
_src = _host + _width + '/' + _height;
_src = _src + '?idx=' + i;
$this.attr('src', _src);
});
}
});
$('.js-img-placeholder').imgPlaceHolder(); // img placeholder
$document.on('click', '.js-toggle-el', function(e){ // set toggle handler
var $this = $(e.target);
$this = ($this.is('a')) ? $this : $this.closest('a');
var $target = $($this.attr('href'));
$.toggleElementClass($target);
});
$document.on('click', '.js-toggle-el', function(e){ // start blur
$.blur.start(800); // transition-duration 과 같아야 함
return false;
});
// init
$.blur.init($('.js-blur'), {
multiplier: 0.9
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
.container {
margin: 20px;
}
#test1, #test2 {
clear: both;
transform: translate(0, 0);
transition: all .8s;
img {
float: left;
width: 200px;
height: 200px;
}
&::after {
display: table;
content: '';
overflow: hidden;
}
}
#test1.in {
transform: translate(400px, 0);
}
#test2.in {
transform: translate(0, 400px);
}
.button {
padding: 10px;
background: #000;
color: #fff !important;
font-size: 14px;
}
.action {
position: fixed;
botom: 0;
right: 0;
z-index: 10;
margin: 20px;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment