canvas画布:金花文本特效
<canvas id="mycanv" width="760" height="200" style="border: 1px solid tan; border-radius: 6px;"></canvas><script>
var skip = 4;
var text = '花潮論壇風光美';
var ww = mycanv.width, hh = mycanv.height;
var ctx = mycanv.getContext('2d');
ctx.fillStyle = 'yellow';
ctx.font = 'bold 100px sans-serif';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText(text, ww/2, hh/2);
var tData = ctx.getImageData(0, 0, ww, hh);
var data = tData.data;
for (var j = 0; j < data.length; j += skip) {
if(data > 0) {
data = `${Math.floor(Math.random() * 256)}`;
data = `${Math.floor(Math.random() * 256)}`;
data = `${Math.floor(Math.random() * 256)}`;
data = `${Math.floor(Math.random() * 150 + 100)}`;
}
}
ctx.putImageData(tData, 0, 0);
</script>
<style>
.mum { position: relative; margin: 0; padding: 10px; font: normal 16px/20px Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; color: black; background: rgba(240, 240, 240,.95); box-shadow: 2px 2px 4px gray; border: thick groove lightblue; border-radius: 6px; }
.mum ::selection { background-color: rgba(0,100,100,.35); }
.mum div { margin: 0; padding: 0; }
.mum cl-cd { display: block; position: relative; margin: 0 0 0 50px; padding: 0 0 0 10px; white-space: pre-wrap; overflow-wrap: break-word; border-left: 1px solid silver; }
.mum cl-cd::before { position: absolute; content: attr(data-idx); width: 50px; color: gray; text-align: right; transform: translate(-70px); }
.tRed { color: red; }
.tBlue { color: blue; }
.tGreen { color: green; }
.tDarkRed { color: darkred; }
.tMagenta { color: magenta; }
</style>
<h2>代码</h2>
<div class='mum'>
<cl-cd data-idx="1"><<span class="tDarkRed">canvas</span> <span class="tRed">id</span>=<span class="tMagenta">"mycanv"</span> width=<span class="tMagenta">"760"</span> height=<span class="tMagenta">"200"</span> style=<span class="tMagenta">"<span class="tBlue">border:</span> 1px solid tan; <span class="tBlue">border-radius:</span> 6px;"</span>><<span class="tDarkRed">/canvas</span>></cl-cd>
<cl-cd data-idx="2"> </cl-cd>
<cl-cd data-idx="3"><<span class="tDarkRed">script</span>></cl-cd>
<cl-cd data-idx="4"><span class="tBlue">var</span> skip = 4;</cl-cd>
<cl-cd data-idx="5"><span class="tBlue">var</span> text = <span class="tMagenta">'花潮論壇風光美'</span>;</cl-cd>
<cl-cd data-idx="6"><span class="tBlue">var</span> ww = mycanv.width, hh = mycanv.height;</cl-cd>
<cl-cd data-idx="7"><span class="tBlue">var</span> ctx = mycanv.getContext(<span class="tMagenta">'2d'</span>);</cl-cd>
<cl-cd data-idx="8"><span class="tGreen">//输出文本</span></cl-cd>
<cl-cd data-idx="9">ctx.fillStyle = <span class="tMagenta">'yellow'</span>;</cl-cd>
<cl-cd data-idx="10">ctx.font = <span class="tMagenta">'bold 100px sans-serif'</span>;</cl-cd>
<cl-cd data-idx="11">ctx.textAlign = <span class="tMagenta">'center'</span>;</cl-cd>
<cl-cd data-idx="12">ctx.textBaseline = <span class="tMagenta">'middle'</span>;</cl-cd>
<cl-cd data-idx="13">ctx.fillText(text, ww/2, hh/2);</cl-cd>
<cl-cd data-idx="14"><span class="tGreen">//获取像素信息</span></cl-cd>
<cl-cd data-idx="15"><span class="tBlue">var</span> tData = ctx.getImageData(0, 0, ww, hh);</cl-cd>
<cl-cd data-idx="16"><span class="tBlue">var</span> data = tData.data; <span class="tGreen">//rgba数据</span></cl-cd>
<cl-cd data-idx="17"><span class="tGreen">//按间隔设定循环像素集群并随机更改指定像素点颜色构成</span></cl-cd>
<cl-cd data-idx="18"><span class="tBlue">for</span> (<span class="tBlue">var</span> j = 0; j < data.length; j += skip) {</cl-cd>
<cl-cd data-idx="19"> <span class="tBlue">if</span>(data > 0) {</cl-cd>
<cl-cd data-idx="20"> data = `${<span class="tRed">Math</span>.floor(<span class="tRed">Math</span>.random() * 256)}`;</cl-cd>
<cl-cd data-idx="21"> data = `${<span class="tRed">Math</span>.floor(<span class="tRed">Math</span>.random() * 256)}`;</cl-cd>
<cl-cd data-idx="22"> data = `${<span class="tRed">Math</span>.floor(<span class="tRed">Math</span>.random() * 256)}`;</cl-cd>
<cl-cd data-idx="23"> data = `${<span class="tRed">Math</span>.floor(<span class="tRed">Math</span>.random() * 150 + 100)}`;</cl-cd>
<cl-cd data-idx="24"> }</cl-cd>
<cl-cd data-idx="25">}</cl-cd>
<cl-cd data-idx="26"><span class="tGreen">//将更改的数据写回画布</span></cl-cd>
<cl-cd data-idx="27">ctx.putImageData(tData, 0, 0);</cl-cd>
<cl-cd data-idx="28"><<span class="tDarkRed">/script</span>></cl-cd>
</div>
本帖最后由 马黑黑 于 2024-5-11 12:19 编辑
和昨天发布的颗粒化文本特效相比,这个貌似是给文本撒上彩色金粉,但它可以扩展:仅需修改像素间隔变量skip 的值便能产生差异性极大的特效。skip 取值必须为正整数,上限一般建议取文本的尺寸设定值(当然可以尝试突破以查看效果)。
实现原理:按 skip 指定的间隔读取画布像素集群,但凡被检测的像素点rgba数据中 a 不等于 0 即不为全透明则以随机数依次更改该像素点的 r、g、b、a 的数值,最后将已经变动了的数据写回画布覆盖原来的文本。 依据被检测像素 alpha 通道不为全透明原理,此法同样适合于处理画布中绘制的任何图像,得到的效果将是图像被随机撒上金粉。 去试了更改 skip 的值,得到的效果变化很大呢{:4_187:} 好像数值取得越大,越接近底色,4以下时,无论底色是什么,得到的效果都差不多呢。 红影 发表于 2024-5-11 19:09
好像数值取得越大,越接近底色,4以下时,无论底色是什么,得到的效果都差不多呢。
多尝试,体会 马黑黑 发表于 2024-5-11 19:56
多尝试,体会
嗯嗯,试一试也很有趣呢。 红影 发表于 2024-5-11 20:32
嗯嗯,试一试也很有趣呢。
那是的 skip 取值必须为正整数。。
数字大些有抽丝效果。。
金花字儿好看 南无月 发表于 2024-5-11 21:16
skip 取值必须为正整数。。
数字大些有抽丝效果。。
金花字儿好看
{:4_190:} 黑黑的新习惯,还没有尝试过 小辣椒 发表于 2024-5-11 23:12
黑黑的新习惯,还没有尝试过
{:4_203:} 马黑黑 发表于 2024-5-11 20:50
那是的
看各种效果在眼前滑过{:4_173:} 红影 发表于 2024-5-12 09:50
看各种效果在眼前滑过
感觉美妙 马黑黑 发表于 2024-5-11 21:27
{:4_187:} 南无月 发表于 2024-5-12 17:26
谢花 马黑黑 发表于 2024-5-12 10:39
感觉美妙
是的,很不错{:4_204:} 红影 发表于 2024-5-12 19:15
是的,很不错
可以玩出很多样式来 马黑黑 发表于 2024-5-12 18:00
谢花
谢春花{:4_199:}