【图片需要完全填充/拉伸以适应容器尺寸,不保持原始比例,使用 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>