开灯(邶风·静女)
本帖最后由 马黑黑 于 2024-4-11 11:53 编辑 <br /><br /><style>#canv { display: block; position: relative; margin: 20px auto; background: url('https://638183.freep.cn/638183/t24/webp/girl.webp') no-repeat center/cover; cursor: crosshair; }
</style>
<canvas id="canv" width="628" height="667"></canvas>
<audio src="https://music.163.com/song/media/outer/url?id=864823940" id="aud" autoplay loop></audio>
<script>
let ww = canv.width, hh = canv.height, rr = 60;
let radius = rr;
let ctx = canv.getContext('2d');
let mask = () => {
ctx.clearRect(0, 0, ww, hh);
ctx.save();
ctx.fillStyle = 'rgba(0,0,0,.8)';
ctx.fillRect(0, 0, ww, hh);
ctx.restore();
};
let lighting = (x,y) => {
ctx.clearRect(0, 0, ww, hh);
mask();
ctx.save();
ctx.globalCompositeOperation ='xor';
ctx.fillStyle = 'green';
ctx.beginPath();
ctx.arc(x, y, radius, 0, 2*Math.PI);
ctx.fill();
ctx.restore();
};
canv.onpointermove = (e) => {
if(radius < rr) radius = rr;
lighting(e.offsetX, e.offsetY);
}
canv.onpointerout = () => {
mask();
radius = rr;
}
canv.onwheel = (e) => {
e.preventDefault();
radius += e.deltaY * 0.25;
if(radius < 0) radius = 0;
lighting(e.offsetX, e.offsetY, radius);
};
canv.onclick = () => aud.paused ? aud.play() : aud.pause();
mask();
</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">style</span>></cl-cd>
<cl-cd data-idx="2"> #canv { <span class="tBlue">display:</span> block; <span class="tBlue">position:</span> relative; <span class="tBlue">margin:</span> 20px auto; <span class="tBlue">background:</span> url(<span class="tMagenta">'https://638183.freep.cn/638183/t24/webp/girl.webp'</span>) no-repeat center/cover; <span class="tBlue">cursor:</span> crosshair; }</cl-cd>
<cl-cd data-idx="3"><<span class="tDarkRed">/style</span>></cl-cd>
<cl-cd data-idx="4"> </cl-cd>
<cl-cd data-idx="5"><<span class="tDarkRed">canvas</span> <span class="tRed">id</span>=<span class="tMagenta">"canv"</span> width=<span class="tMagenta">"628"</span> height=<span class="tMagenta">"667"</span>><<span class="tDarkRed">/canvas</span>></cl-cd>
<cl-cd data-idx="6"><<span class="tDarkRed">audio</span> src=<span class="tMagenta">"https://music.163.com/song/media/outer/url?<span class="tRed">id</span>=864823940"</span> <span class="tRed">id</span>=<span class="tMagenta">"aud"</span> autoplay loop><<span class="tDarkRed">/audio</span>></cl-cd>
<cl-cd data-idx="7"> </cl-cd>
<cl-cd data-idx="8"><<span class="tDarkRed">script</span>></cl-cd>
<cl-cd data-idx="9"> </cl-cd>
<cl-cd data-idx="10"><span class="tBlue">let</span> ww = canv.width, hh = canv.height, rr = 60;</cl-cd>
<cl-cd data-idx="11"><span class="tBlue">let</span> radius = rr;</cl-cd>
<cl-cd data-idx="12"><span class="tBlue">let</span> ctx = canv.getContext(<span class="tMagenta">'2d'</span>);</cl-cd>
<cl-cd data-idx="13"> </cl-cd>
<cl-cd data-idx="14"><span class="tBlue">let</span> mask = () => {</cl-cd>
<cl-cd data-idx="15"> ctx.clearRect(0, 0, ww, hh);</cl-cd>
<cl-cd data-idx="16"> ctx.save();</cl-cd>
<cl-cd data-idx="17"> ctx.fillStyle = <span class="tMagenta">'rgba(0,0,0,.8)'</span>;</cl-cd>
<cl-cd data-idx="18"> ctx.fillRect(0, 0, ww, hh);</cl-cd>
<cl-cd data-idx="19"> ctx.restore();</cl-cd>
<cl-cd data-idx="20">};</cl-cd>
<cl-cd data-idx="21"> </cl-cd>
<cl-cd data-idx="22"><span class="tBlue">let</span> lighting = (x,y) => {</cl-cd>
<cl-cd data-idx="23"> ctx.clearRect(0, 0, ww, hh);</cl-cd>
<cl-cd data-idx="24"> mask();</cl-cd>
<cl-cd data-idx="25"> ctx.save();</cl-cd>
<cl-cd data-idx="26"> ctx.globalCompositeOperation =<span class="tMagenta">'xor'</span>;</cl-cd>
<cl-cd data-idx="27"> ctx.fillStyle = <span class="tMagenta">'green'</span>;</cl-cd>
<cl-cd data-idx="28"> ctx.beginPath();</cl-cd>
<cl-cd data-idx="29"> ctx.arc(x, y, radius, 0, 2*<span class="tRed">Math</span>.PI);</cl-cd>
<cl-cd data-idx="30"> ctx.fill();</cl-cd>
<cl-cd data-idx="31"> ctx.restore();</cl-cd>
<cl-cd data-idx="32">};</cl-cd>
<cl-cd data-idx="33"> </cl-cd>
<cl-cd data-idx="34">canv.onpointermove = (e) => {</cl-cd>
<cl-cd data-idx="35"> <span class="tBlue">if</span>(radius < rr) radius = rr;</cl-cd>
<cl-cd data-idx="36"> lighting(e.offsetX, e.offsetY);</cl-cd>
<cl-cd data-idx="37">}</cl-cd>
<cl-cd data-idx="38"> </cl-cd>
<cl-cd data-idx="39">canv.onpointerout = () => {</cl-cd>
<cl-cd data-idx="40"> mask();</cl-cd>
<cl-cd data-idx="41"> radius = rr;</cl-cd>
<cl-cd data-idx="42">}</cl-cd>
<cl-cd data-idx="43"> </cl-cd>
<cl-cd data-idx="44">canv.onwheel = (e) => {</cl-cd>
<cl-cd data-idx="45"> e.preventDefault();</cl-cd>
<cl-cd data-idx="46"> radius += e.deltaY * 0.25;</cl-cd>
<cl-cd data-idx="47"> <span class="tBlue">if</span>(radius < 0) radius = 0;</cl-cd>
<cl-cd data-idx="48"> lighting(e.offsetX, e.offsetY, radius);</cl-cd>
<cl-cd data-idx="49">};</cl-cd>
<cl-cd data-idx="50"> </cl-cd>
<cl-cd data-idx="51">canv.onclick = () => aud.paused ? aud.play() : aud.pause();</cl-cd>
<cl-cd data-idx="52"> </cl-cd>
<cl-cd data-idx="53">mask();</cl-cd>
<cl-cd data-idx="54"> </cl-cd>
<cl-cd data-idx="55"><<span class="tDarkRed">/script</span>></cl-cd>
</div>
实现原理简述:
画布通过CSS设置背景图片,然后在其上绘制0.8不透明度的黑色遮罩层,令背景图片若隐若现。再通过JS指针事件绘制圆形“光照”,即利用 xor 合成方式局部“抹掉”遮罩层形成光照变亮的效果,“光照”圈可以伸缩,方式是通过滑动鼠标或类似设备滑轮加以实现。
缺点:对手机支持度不好。 黑黑老师,复制你的代码在HTML编辑器上为什么不显示图片,开灯不见人影?
老谟深虑 发表于 2024-4-11 12:13
黑黑老师,复制你的代码在HTML编辑器上为什么不显示图片,开灯不见人影?
代码和一楼的代码是完全一样,理论上不会有问题。不知你用的什么浏览器。 马黑黑 发表于 2024-4-11 12:17
代码和一楼的代码是完全一样,理论上不会有问题。不知你用的什么浏览器。
我用的是360浏览器。
360浏览器有两种模式,使用极速模式应该没问题,如果还有,应该更新一下浏览器了 老谟深虑 发表于 2024-4-11 15:09
我用的是360浏览器。
看8楼 马黑黑 发表于 2024-4-11 15:39
看8楼
我用一楼的代码就能看到,真奇怪。
这个非常有意思。而且评分后,就完全开灯了。
刷新,就又变成朦胧的画面了,需要鼠标去弄亮{:4_173:} 下班了,等回去了接着看着神奇的效果{:4_187:} 马黑黑 发表于 2024-4-11 11:55
滑动鼠标滚轮可更改灯光大小
变大变小试过了,这灯可以调节强弱 南无月 发表于 2024-4-11 17:29
变大变小试过了,这灯可以调节强弱
关于光源,有平行光源(比如太阳光),有点光源。这些,PS也有的。 红影 发表于 2024-4-11 17:06
下班了,等回去了接着看着神奇的效果
{:4_190:} 红影 发表于 2024-4-11 17:05
这个非常有意思。而且评分后,就完全开灯了。
刷新,就又变成朦胧的画面了,需要鼠标去弄亮
评论辛苦,开个灯奖励一下 马黑黑 发表于 2024-4-11 12:06
实现原理简述:
画布通过CSS设置背景图片,然后在其上绘制0.8不透明度的黑色遮罩层,令背景图片若隐若现 ...
手机试了下,如你所说,没玩成。。
评分后只看到美人。。没有鼠标和暗光效果。。需刷新后出现 老谟深虑 发表于 2024-4-11 16:07
我用一楼的代码就能看到,真奇怪。
代码是一样的。可能是别的原因。要不,如果方便,你把二楼代码放到这里运行一下看看:
http://mhh.52qingyin.cn/api/pcode/ 南无月 发表于 2024-4-11 17:32
手机试了下,如你所说,没玩成。。
评分后只看到美人。。没有鼠标和暗光效果。。需刷新后出现
适配手机,需要更多的代码,可能比这里多近两倍 《邶风·静女》标题文绉绉的,原来是 诗经里的一首诗。。