在本篇文章中,我将共享怎么运用 Canvas 和 JavaScript 创建一个共同的字符画生成器。经过此生成器,咱们能够将图片转换为由字符构成的作品,并经过一些JavaScript特点让这些字符动起来。结合现代的 Web 技术,咱们在网页上动态地生成字符画,而且经过增加一些动画作用,使其更富有趣味性。
准备工作
首要,咱们需求一些根底的 HTML 结构和 JavaScript 代码,用于加载图片并创建 Canvas。
<body>
<div class="glass">
<img id="myImg" src="./xxx.png" style="display: none;"></img>
<div id="canvasDiv">
<canvas id="canvas" width="600" height="600" style="display: none;"></canvas>
</div>
<div id="textDiv" class="textDiv" style="line-height: 0.9;"></div>
</div>
<script>
// ...(后续代码将在下文详细介绍)
</script>
</body>
图片和canvas都不需求展示,设置它们为display: none;
图片加载与转换
在 window.onload
事件中,咱们加载图片并将其制作到 Canvas 上。为了保持生成的字符画不失真,咱们需求进行一些调整。
window.onload = () => {
canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
const img = document.querySelector('#myImg');
changeImg(img);
let newimgText = imgText.split('</br>').map((e) => "<div class='amiDiv'>" + e + "</div>") .join('');
document.getElementById("textDiv").innerHTML = newimgText;
};
首要获取canvas
标签,而且创建一个2D渲染上下文ctx
,以便后续运用。接下来,该代码获取图片,而且将其作为参数传递给changeImg
函数,该函数将会对这个图片进行处理,将其转换为字符画并将成果存储在全局变量imgText
中。然后,界说新的字符串变量newimgText
,将imgText
字符串每一行分离隔,方便一瞬间分别给每一行增加动态作用。
Canvas 操作与字符生成
在 changeImg
函数中,咱们运用 Canvas 获取图片像素信息,并逐个读取每个像素的RGB值,核算出对应的灰度值并映射到字符上。同时,咱们也能够调整字符巨细操控显示图像的精度。
function changeImg(img) {
// 清空字符画
imgText = "";
// 先记载比率,如果宽,那么先缩放宽,再用比率算出长,反之同理,这里是确保不超越不超越设定规模
let rate = img.width / img.height;
if (rate > 1) {
img.style.width = IMAGE_SIZE + 'px';
img.style.height = IMAGE_SIZE / rate + 'px';
img.width = IMAGE_SIZE;
img.height = IMAGE_SIZE / rate;
} else {
img.style.height = IMAGE_SIZE + 'px';
img.style.width = IMAGE_SIZE * rate + 'px';
img.height = IMAGE_SIZE;
img.width = IMAGE_SIZE * rate;
}
ctx.clearRect(0, 0, canvas.width, canvas.height)
// 将图片制作在canvas上
ctx.drawImage(img, 0, 0, img.width, img.height);
// 获取像素信息
let pixelInfo;
try {
pixelInfo = ctx.getImageData(0, 0, img.width, img.height);
} catch {
console("图片有问题!");
}
// 数值越小,精度越高
let size = 2;
// 设置zoom缩放
document.querySelector("#textDiv").style.zoom = size / 6;
// 生成主体,逐个读取字符
for (let i = 0; i < img.height; i = i + size) {
for (let j = 0; j < img.width; j = j + size) {
const curPoint = (i * img.width + j) * 4; // 4是因为,1为r,2为g,3为b,4为a,四个是一组rgba值
const [r, g, b] = pixelInfo.data.slice(curPoint, curPoint + 3);
const gray = r * 0.3 + g * 0.6 + b * 0.1; // 核算灰度值
const color = `rgba(${r},${g},${b})`; // 保存像素点rgb值
toText(gray, color)
}
imgText += "</br>";
}
}
拼接字符画
将字符拼接成一行一行的文本。
function toText(g, color) {
if (color) imgText += `<span>`;
if (g == 255) imgText += " ";
else imgText += "@";
if (color) imgText += "</span>";
}
增加动态作用
最终,运用JavaScript的正弦函数来操控每个文字元素的位置和偏移量,从而完成字符画龙在页面上的动态作用。
const container = document.querySelectorAll(".amiDiv");
// 创建曲线运动
function createCurve(func, range) {
container.forEach(e => {
const points = getCurvePoints(func, range, e.children.length, e.clientWidth);
for (let i = 0; i < points.length; i++) {
e.children[i].style.transform = `translateY(${points[i]}px)`;
}
});
}
let offset = 0;
createCurve((x) => Math.sin(x), [offset, offset + 2 * Math.PI]);
setInterval(() => {
offset += 0.1;
createCurve((x) => Math.sin(x), [offset, offset + 2 * Math.PI]);
}, 30);
// 辅佐函数:获取曲线上的点
function getCurvePoints(curveFunc, range, number, xLength) {
if (number < 1) {
return [];
}
if (number === 1) {
return [0];
}
const piece = (range[1] - range[0]) / (number - 1);
const result = [];
const scale = xLength / (range[1] - range[0]);
for (let i = 0; i < number; i++) {
result.push(-curveFunc(i * piece + range[0]) * scale);
}
return result;
}
结语
在这个龙年,愿咱们的代码好像神龙一般威猛,技术好像飞龙一般飞翔,最终祝大家新的一年:龙行龘龘,前程朤朤!✨