css++图片有空,css3 + Js:有趣的图片马赛克~ (高斯模糊)

前两篇文介绍了css3的过滤器filter用来实现图片的高斯模糊效果,还有js拖拽的功能。

要实现局部模糊就要把两者结合起来,计算位移就可以了。

实现原理

原理其实很简单,就是两张图的叠加。底部一张清晰的图,上面一个高斯模糊过的图,将高斯模糊的图当作上层元素的背景,利用背景定位使其只显示一部分,然后把这个高斯模糊的窗口放置在高清图的上层,背景图片的位置与下面的图片位置一致,这样看起来就像一张高清的图片打上了马赛克一样。讲起来不是很清楚,大家可以看一下代码。

基础版本

HTML

#css_box {

position: relative;

width: 100%;

height: 500px;

background: url('https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1567844929804&di=75928af77a3db7ff54cd4eab49361bc0&imgtype=0&src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fblog%2F201307%2F19%2F20130719082039_k2NHG.jpeg') no-repeat;

}

#css_target {

position: absolute;

left: 0px;

top: 0px;

width: 200px;

height: 200px;

background: inherit;

filter: blur(10px);

/* 继承父元素的background属性 */

}

var bar = document.getElementById("css_box");

var target = document.getElementById("css_target");

startDrag(bar, target, function(x, y) {

target.style.backgroundPosition = (-1 * x) + "px " + (-1 * y) + "px";

});

复制代码

JS (当作JS文件引入)

var getCss = function(o, key) {

return o.currentStyle ? o.currentStyle[key] : document.defaultView.getComputedStyle(o, false)[key];

};

// 拖拽

var startDrag = function(bar, target, callback) {

maxX = parseInt(getCss(bar, "width")) - parseInt(getCss(target, "width"));

maxY = parseInt(getCss(bar, "height")) - parseInt(getCss(target, "height"));

var resX = 0,

resY = 0;

var params = {

left: 0,

top: 0,

currentX: 0,

currentY: 0,

flag: false

};

if (getCss(target, "left") !== "auto") {

params.left = getCss(target, "left");

}

if (getCss(target, "top") !== "auto") {

params.top = getCss(target, "top");

}

target.onmousedown = function(event) {

params.flag = true;

if (!event) {

event = window.event;

bar.onselectstart = function() {

return false;

}

}

var e = event;

params.currentX = e.clientX;

params.currentY = e.clientY;

};

document.onmouseup = function() {

params.flag = false;

if (getCss(target, "left") !== "auto") {

params.left = getCss(target, "left");

}

if (getCss(target, "top") !== "auto") {

params.top = getCss(target, "top");

}

};

document.onmousemove = function(event) {

var e = event ? event : window.event;

if (params.flag) {

var nowX = e.clientX,

nowY = e.clientY;

var disX = nowX - params.currentX,

disY = nowY - params.currentY;

if ((parseInt(params.left) + disX) > maxX) {

resX = maxX;

} else if ((parseInt(params.left) + disX) < 0) {

resX = 0;

} else {

resX = parseInt(params.left) + disX;

}

if ((parseInt(params.top) + disY) > maxY) {

resY = maxY;

} else if ((parseInt(params.top) + disY) < 0) {

resY = 0;

} else {

resY = parseInt(params.top) + disY;

}

target.style.left = resX + 'px'

target.style.top = resY + 'px'

if (typeof callback == "function") {

callback(resX, resY);

}

if (event.preventDefault) {

event.preventDefault();

}

return false;

}

}

};

复制代码

兼容移动端优化版本

HTML

#css_box {

position: relative;

touch-action: none;

width: 100%;

height: 500px;

background: url('https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1567844929804&di=75928af77a3db7ff54cd4eab49361bc0&imgtype=0&src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fblog%2F201307%2F19%2F20130719082039_k2NHG.jpeg') no-repeat;

background-size: contain;

}

#css_target {

position: absolute;

left: 0px;

top: 0px;

background: inherit;

filter: blur(10px);

touch-action: none;

/* 继承父元素的background属性 */

}

mosaic Demo 传送门

X: 0 px Y: 0 px

$(document).ready(function() {

var bar = document.getElementById("css_box");

var target = document.getElementById("css_target");

var p_img = document.getElementById("position_img");

// 兼容分辨率

bar.style.height = (parseInt(getCss(bar, "width")) * 636 / 900) + 'px';

target.style.backgroundSize = parseInt(getCss(bar, "width")) + 'px ' + (parseInt(getCss(bar, "width")) * 636 / 900) + 'px';

startDrag(bar, target, function(x, y) {

target.style.backgroundPosition = (-1 * x) + "px " + (-1 * y) + "px";

p_img.innerText = "X: " + target.style.left + " Y: " + target.style.top;

});

})

复制代码

JS (当作JS文件引入)

// 拖拽

var startDrag = function(bar, target, callback) {

var getCss = function(o, key) {

return o.currentStyle ? o.currentStyle[key] : document.defaultView.getComputedStyle(o, false)[key];

};

var down = function(event) {

// 兼容分辨率

bar.style.height = (parseInt(getCss(bar, "width")) * 636 / 900) + 'px';

target.style.backgroundSize = parseInt(getCss(bar, "width")) + 'px ' + (parseInt(getCss(bar, "width")) * 636 / 900) + 'px';

params.flag = true;

if (!event) {

event = window.event;

bar.onselectstart = function() {

return false;

}

}

var e = event;

params.currentX = e.clientX || e.changedTouches[0].clientX;

params.currentY = e.clientY || e.changedTouches[0].clientY;

};

var up = function() {

params.flag = false;

if (getCss(target, "left") !== "auto") {

params.left = getCss(target, "left");

}

if (getCss(target, "top") !== "auto") {

params.top = getCss(target, "top");

}

};

var move = function(event) {

var e = event ? event : window.event;

if (params.flag) {

var nowX = e.clientX || e.changedTouches[0].clientX,

nowY = e.clientY || e.changedTouches[0].clientY;

var disX = nowX - params.currentX,

disY = nowY - params.currentY;

if ((parseInt(params.left) + disX) > maxX) {

resX = maxX;

} else if ((parseInt(params.left) + disX) < 0) {

resX = 0;

} else {

resX = parseInt(params.left) + disX;

}

if ((parseInt(params.top) + disY) > maxY) {

resY = maxY;

} else if ((parseInt(params.top) + disY) < 0) {

resY = 0;

} else {

resY = parseInt(params.top) + disY;

}

target.style.left = resX + 'px'

target.style.top = resY + 'px'

if (typeof callback == "function") {

callback(resX, resY);

}

if (event.preventDefault) {

event.preventDefault();

}

return false;

}

}

var resX = 0,

resY = 0;

var params = {

left: 0,

top: 0,

currentX: 0,

currentY: 0,

flag: false

};

if (getCss(target, "left") !== "auto") {

params.left = getCss(target, "left");

}

if (getCss(target, "top") !== "auto") {

params.top = getCss(target, "top");

}

if ((navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i))) {

console.log("mobile");

target.style.width = '100px';

target.style.height = '100px';

maxX = parseInt(getCss(bar, "width")) - parseInt(getCss(target, "width"));

maxY = parseInt(getCss(bar, "height")) - parseInt(getCss(target, "height"));

target.ontouchstart = down

document.ontouchend = up

document.ontouchmove = move

} else {

console.log("pc");

target.style.width = '150px';

target.style.height = '150px';

maxX = parseInt(getCss(bar, "width")) - parseInt(getCss(target, "width"));

maxY = parseInt(getCss(bar, "height")) - parseInt(getCss(target, "height"));

target.onmousedown = down

document.onmouseup = up

document.onmousemove = move

}

};

复制代码以上就是局部模糊的实现方法。可以直接套用。将JS部分当作文件引入。否则要把初始化函数放在函数声明的后面。

最后可查看实际效果:demo演示地址

借鉴于张鑫旭大神

你可能感兴趣的:(css++图片有空)