【图片需要完全填充/拉伸以适应容器尺寸,不保持原始比例,使用 object-fit: fill 属性实现】
效果:
代码案例:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>图片悬停渐变背景效果</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Arial, sans-serif;
min-height: 100vh;
display: flex;
flex-direction: column;
position: relative;
background-color: #f0f0f0;
overflow-x: hidden;
}
.background-container {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
transition: all 0.5s ease-in-out;
}
.background-image {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-size: cover;
background-position: center;
filter: blur(20px);
transition: opacity 0.5s ease;
opacity: 0;
}
.gradient-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
transition: opacity 0.5s ease;
opacity: 0.85;
}
.content-wrapper {
position: relative;
z-index: 1;
}
.container {
width: 650px;
margin: 50px auto;
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
gap: 20px;
}
.image-container {
width: 300px;
height: 200px;
overflow: hidden;
border-radius: 8px;
cursor: pointer;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
transition: transform 0.3s ease, box-shadow 0.3s ease, opacity 0.5s ease;
background: white;
position: relative;
z-index: 2;
}
.image-container:hover {
transform: translateY(-10px) scale(1.05);
box-shadow: 0 12px 24px rgba(0, 0, 0, 0.2);
}
.image-container img {
width: 100%;
height: 100%;
object-fit: fill;
transition: transform 0.5s ease;
}
.image-container:hover img {
transform: scale(1.05);
}
/* 新增:非激活状态的图片透明度 */
.image-container.fade {
opacity: 0.3;
transform: scale(0.95);
z-index: 1;
}
h1 {
text-align: center;
margin-top: 50px;
margin-bottom: 30px;
color: #333;
transition: color 0.5s ease;
text-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
#canvas {
display: none;
}
</style>
</head>
<body>
<div class="background-container">
<div class="background-image" id="bg-image"></div>
<div class="gradient-overlay" id="gradient-overlay"></div>
</div>
<div class="content-wrapper">
<h1>悬停图片查看效果</h1>
<div class="container">
<div class="image-container">
<img src="1 (1).jpeg" alt="图片1" data-src="1 (1).jpeg">
</div>
<div class="image-container">
<img src="1 (1).jpg" alt="图片2" data-src="1 (1).jpg">
</div>
<div class="image-container">
<img src="1 (1).png" alt="图片3" data-src="1 (1).png">
</div>
<div class="image-container">
<img src="1 (2).jpeg" alt="图片4" data-src="1 (2).jpeg">
</div>
</div>
</div>
<!-- 隐藏的canvas元素用于分析图片颜色 -->
<canvas id="canvas"></canvas>
<script>
document.addEventListener('DOMContentLoaded', function() {
const imageContainers = document.querySelectorAll('.image-container');
const bgImage = document.getElementById('bg-image');
const gradientOverlay = document.getElementById('gradient-overlay');
const heading = document.querySelector('h1');
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
// 提取图片多个区域的颜色
function extractColors(img) {
// 设置canvas大小
const width = 100;
const height = 100;
canvas.width = width;
canvas.height = height;
// 在canvas上绘制图片
ctx.drawImage(img, 0, 0, width, height);
// 从图片的不同区域提取颜色
const topLeft = getColorFromRegion(0, 0, width/3, height/3);
const topRight = getColorFromRegion(2*width/3, 0, width/3, height/3);
const bottomLeft = getColorFromRegion(0, 2*height/3, width/3, height/3);
const bottomRight = getColorFromRegion(2*width/3, 2*height/3, width/3, height/3);
const center = getColorFromRegion(width/3, height/3, width/3, height/3);
return {
topLeft,
topRight,
bottomLeft,
bottomRight,
center
};
}
// 获取指定区域的平均颜色
function getColorFromRegion(x, y, width, height) {
const imageData = ctx.getImageData(x, y, width, height);
const data = imageData.data;
let r = 0, g = 0, b = 0;
const pixelCount = data.length / 4;
for (let i = 0; i < data.length; i += 4) {
r += data[i];
g += data[i + 1];
b += data[i + 2];
}
r = Math.floor(r / pixelCount);
g = Math.floor(g / pixelCount);
b = Math.floor(b / pixelCount);
return { r, g, b };
}
// 计算颜色亮度
function getBrightness(r, g, b) {
return (r * 299 + g * 587 + b * 114) / 1000;
}
// 创建带透明度的CSS渐变字符串
function createGradient(colors) {
const { topLeft, topRight, bottomLeft, bottomRight, center } = colors;
// 添加0.85的透明度到每个颜色值
return `linear-gradient(135deg,
rgba(${topLeft.r}, ${topLeft.g}, ${topLeft.b}, 0.85) 0%,
rgba(${center.r}, ${center.g}, ${center.b}, 0.85) 50%,
rgba(${bottomRight.r}, ${bottomRight.g}, ${bottomRight.b}, 0.85) 100%),
linear-gradient(45deg,
rgba(${bottomLeft.r}, ${bottomLeft.g}, ${bottomLeft.b}, 0.85) 0%,
rgba(${center.r}, ${center.g}, ${center.b}, 0.85) 50%,
rgba(${topRight.r}, ${topRight.g}, ${topRight.b}, 0.85) 100%)`;
}
// 定义默认渐变
const defaultGradient = 'linear-gradient(135deg, rgba(245, 247, 250, 0.85) 0%, rgba(195, 207, 226, 0.85) 100%)';
// 淡化其他图片
function fadeOtherImages(currentContainer) {
imageContainers.forEach(container => {
if (container !== currentContainer) {
container.classList.add('fade');
}
});
}
// 恢复所有图片
function resetAllImages() {
imageContainers.forEach(container => {
container.classList.remove('fade');
});
}
// 为每个图片容器添加事件监听器
imageContainers.forEach(container => {
const img = container.querySelector('img');
// 预加载图片并处理颜色
const preloadImg = new Image();
preloadImg.crossOrigin = "Anonymous";
preloadImg.src = img.src;
preloadImg.onload = function() {
// 提取并存储多个颜色
img.dataset.colors = JSON.stringify(extractColors(preloadImg));
};
container.addEventListener('mouseenter', function() {
// 淡化其他图片
fadeOtherImages(container);
if (img.dataset.colors) {
const colors = JSON.parse(img.dataset.colors);
const centerColor = colors.center;
const brightness = getBrightness(centerColor.r, centerColor.g, centerColor.b);
// 设置模糊背景图片
bgImage.style.backgroundImage = `url(${img.getAttribute('data-src')})`;
bgImage.style.opacity = '1';
// 创建渐变效果
gradientOverlay.style.background = createGradient(colors);
// 根据背景亮度调整标题颜色
if (brightness < 128) {
heading.style.color = '#fff';
heading.style.textShadow = '0 2px 4px rgba(0,0,0,0.3)';
} else {
heading.style.color = '#333';
heading.style.textShadow = '0 2px 4px rgba(255,255,255,0.3)';
}
}
});
container.addEventListener('mouseleave', function() {
// 恢复所有图片
resetAllImages();
// 当鼠标离开时,恢复初始状态
bgImage.style.opacity = '0';
gradientOverlay.style.background = defaultGradient; // 恢复默认渐变
heading.style.color = '#333';
heading.style.textShadow = '0 2px 4px rgba(0,0,0,0.1)';
});
});
// 初始状态 - 设置默认渐变
gradientOverlay.style.background = defaultGradient;
});
</script>
</body>
</html>