JavaScript图片颜色混合效果

本人在一个项目中需要实现如下效果:将一个png格式的图片画到一个canvas上,其颜色根据玩家当前状态进行变化。

原本想法是在首次加载时进行预处理,存为多个离屏canvas,但后来添加颜色的过渡动画将此方法排除了(毕竟不可能将过渡时的这么多颜色全都存一份)

目标:

对于给定的任意颜色,能够高效的将该颜色叠加到图片上(毕竟要每帧渲染)

实现:

首先建一个简单的框架

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="utf-8">
    <title>test</title>
    <style>
        .bg {
            width: 600px;
            height: 600px;
            margin: 0;
            border: 1px solid #777;
        }
        label {
            margin: 10px;
        }
        canvas {
            background: #777;
        }
    </style>
</head>
<body style="display: flex; justify-content: center">
<div style="display: flex; flex-direction: column">
    <label>
        <span>R</span>
        <input id="red" type="range" min="0" max="255" value="128">
    </label>
    <label>
        <span>G</span>
        <input id="green" type="range" min="0" max="255" value="128">
    </label>
    <label>
        <span>B</span>
        <input id="blue" type="range" min="0" max="255" value="128">
    </label>
</div>
<div class="bg">
    <canvas id="game" width="600" height="600"></canvas>
</div>
</body>
<script>
function setColor() { //something }
</script>
</html>

将图片丢上去
圆内是不透明的(黑白色填充),圆外是透明的

JavaScript图片颜色混合效果 第2张插图

JavaScript图片颜色混合效果 第3张插图
此处内容已隐藏,评论后刷新即可查看!

看起来只需要对draw函数进行修改就可以了,即设置要在绘制新形状时应用的合成操作的类型并填充颜色(毕竟是对当前图片进行“染色”)

对于globalCompositeOperation,请参考CanvasRenderingContext2D.globalCompositeOperation

经测试,采用multiply(正片叠底)的效果是最符合预期的

function draw() {
    ctx.save();
    ctx.clearRect(0, 0, N, N);
    ctx.drawImage(tree, 0, 0, N, N);
    ctx.globalCompositeOperation = "multiply";
    ctx.fillStyle = `rgb(${r},${g},${b})`;
    ctx.fillRect(0, 0, N, N);
    ctx.restore();
}

JavaScript图片颜色混合效果 第4张插图

要对处理后图像的透明像素进行处理,source-atop或destination-atop可以完成这个需求,给出一种采用destination-atop的解决方案

function draw() {
    ctx.save();
    ctx.clearRect(0, 0, N, N);
    ctx.drawImage(tree, 0, 0, N, N);
    ctx.globalCompositeOperation = "multiply";
    ctx.fillStyle = `rgb(${r},${g},${b})`;
    ctx.fillRect(0, 0, N, N);
    ctx.globalCompositeOperation = "destination-atop";
    ctx.drawImage(tree, 0, 0, N, N);
    ctx.restore();
}

此外,尝试采用不同的混合模式可以达到原本进行像素运算会十分麻烦的效果,比如采用lighter来还原一下东方神灵庙的特产——瞎眼光玉

JavaScript图片颜色混合效果 第5张插图

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>test</title>
    <link href="main.css" rel="stylesheet">
    <script src="main.js"></script>
</head>
<body>
<h3>左键移动,右键添加/删除</h3>
</body>
</html>
body {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    overflow: hidden;
    width: 100vw;
    height: 100vh;
}

JavaScript图片颜色混合效果 第3张插图
此处内容已隐藏,评论后刷新即可查看!

免责声明

本站提供的一切软件、教程和内容信息仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络收集整理,如果您喜欢该程序和内容,请支持正版,购买注册,得到更好的正版服务。我们非常重视版权问题,如有侵权请邮件与我们联系处理。敬请谅解!
如若转载,请注明出处:https://www.zxki.cn/8162.html

上一篇 2023-11-20 19:55
下一篇 2023-11-21 08:33

相关推荐

发表评论

为了防止灌水评论,登录后即可评论!

还没有评论,快来抢沙发吧!