你是否想过,仅仅使用CSS就能创造出令人惊叹的视觉艺术?今天,我们将带你走进CSS的神奇世界,探索如何使用前端CSS技巧来实现独特的阴影画图!
在线演示地址: CSS阴影画图
.item{
width: 50px;
height: 50px;
background: #009688;
box-shadow: 50px 0 red, 100px 0px #000;
}
效果:
.item{
width: 50px;
height: 50px;
background: #009688;
box-shadow: 50px 0 red, 100px 0px #000;/*增加了一个*/
}
变成了:
当box-shadow添加的越来越多的时候,就形成了一个个像素点,用不同的颜色根据位置进行拼接,那么就可以拼接成一张图片。
利用这一特性,再将它封装一下,就可以实现上传图片生成css阴影图。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<label style='margin-top:20px;background:#009688;color:#fff;text-align:center;padding:10px;display: block;cursor: pointer;'>
上传图片 <span id="loading" style="color:rgb(214, 202, 202)"></span> <input style="display:none;left:-9999px;position:absolute;" type="file" id="file-input">
</label>
<br>
<p style="background:#FAFAFA;border-left: 5px solid #e05637;text-align: left;padding:20px;font-size:18px;"> <a href="https://www.zhangpingguo.com/" style='text-decoration: none;color:#000' target="_blank">张苹果博客:www.zhangpingguo.com</a></p>
<p style="background:#FAFAFA;border-left: 5px solid #1E9FFF;text-align: left;padding:20px;font-size:18px;">标签样式:</p>
<p id="myInput" style="
width: 100%;
height: 300px;
overflow: auto;
"></p>
<p style="background:#FAFAFA;border-left: 5px solid #1E9FFF;text-align: left;padding:20px;font-size:18px;">效果图:</p>
<div id="pixelated-image" style="height: 100vh;"></div>
</body>
<script>
// 获取文件输入框和像素化图片元素
const fileInput = document.getElementById('file-input');
const pixelatedImage = document.getElementById('pixelated-image');
// 定义一个将 RGB 颜色值转换成十六进制颜色值的函数
function rgbToHex(r, g, b) {
var hex = "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
return hex;
}
// 给文件输入框添加 change 事件监听器
fileInput.addEventListener('change', function () {
// 获取用户选择的文件
const file = fileInput.files[0];
// 创建一个 FileReader 对象
const reader = new FileReader();
// 定义一个变量用于显示加载状态
let loading = "";
// 给 FileReader 对象添加 load 事件监听器
reader.addEventListener('load', function () {
// 创建一个 Image 对象
const image = new Image();
// 将 FileReader 对象读取的文件内容赋值给 Image 对象的 src 属性
image.src = reader.result;
// 显示加载状态
loading = "正在生成中(图片越大就越慢,也可能会出问题.)...";
document.getElementById("loading").innerText = loading;
// 给 Image 对象添加 load 事件监听器
image.addEventListener('load', function () {
try {
// 创建一个 Canvas 对象
const canvas = document.createElement('canvas');
// 设置 Canvas 对象的宽度和高度
canvas.width = image.width;
canvas.height = image.height;
// 获取 Canvas 对象的 2D 上下文
const context = canvas.getContext('2d');
// 在 Canvas 对象上绘制图像
context.drawImage(image, 0, 0);
// 获取 Canvas 对象上的像素数据
const imageData = context.getImageData(0, 0, canvas.width, canvas.height);
const pixels = imageData.data;
let html = '';
let i = 0;
let boxShadow = '';
// 遍历像素数据
while (i < pixels.length) {
const r = pixels[i];
const g = pixels[i + 1];
const b = pixels[i + 2];
const a = pixels[i + 3];
// 如果像素的 alpha 值大于 0,则将该像素的颜色转换成十六进制颜色值,并将其添加到 boxShadow 变量中
if (a > 0) {
const x = (i / 4) % canvas.width;
const y = Math.floor(i / 4 / canvas.width);
boxShadow += `${x}px ${y}px ${rgbToHex(r,g,b)},`;
}
i += 4;
}
// 隐藏加载状态
loading = "已完成";
document.getElementById("loading").innerText = loading;
// 将像素化后的图片添加到页面中
html =
`<div style="box-shadow: ${boxShadow.slice(0, boxShadow.length - 1)};width:1px;height:1px;"></div>`;
document.getElementById("myInput").innerText = html;
pixelatedImage.innerHTML = html;
} catch (error) {
loading = "出错了";
document.getElementById("loading").innerText = loading;
}
});
});
// 读取用户选择的文件
reader.readAsDataURL(file);
});
</script>
</html>