在Hobbit's网站上偶然发现了一个漂亮的射击效果。这种效果我实际上只在游戏中看到。
在left
和right
边有两个块(evil
和good
)
当您将鼠标悬停在其中一个方块上时,会有一个圆形的火圈
像在底部
FROM
要
我创建了类似的内容,但实际上我的火势并没有像上面的站点中那样平稳显示。我需要与站点中完全相同的效果,请帮忙。
.good {
height:200px;
width:200px;
background-image: url(https://image.ibb.co/gapib8/good_icon.png);
background-size:cover;
box-sizing:border-box;
padding:10px;
}
.good .ring {
overflow:hidden;
transition: 1s opacity;
transition-timing-function:easeInOut;
opacity:0;
height:100%;
width:100%;
background-image: url(https://image.ibb.co/eJCQpT/fire_ring.png);
background-repeat:no-repeat;
background-size:cover;
}
.good:hover .ring {
opacity:1;
}
<div class="good">
<div class="ring">
</div>
</div>
答案 0 :(得分:2)
这是使用片段着色器的重量级WebGL解决方案
<img src="https://image.ibb.co/gapib8/good_icon.png">
<div class="zone"></div>
<canvas width="335" height="335" id="canvas"/>
<script type="glsl">
precision highp float;
uniform float time;
uniform vec2 resolution;
uniform float fill; // fill of fire ring (0-1)
vec3 firePalette(float i) {
float T = 1400. + 1300.*i;
vec3 L = vec3(7.4, 5.6, 4.4);
L = pow(L,vec3(5.0)) * (exp(1.43876719683e5/(T*L))-1.0);
return 1.0-exp(-5e8/L);
}
vec3 hash33(vec3 p) {
float n = sin(dot(p, vec3(7, 157, 113)));
return fract(vec3(2097152, 262144, 32768)*n);
}
float voronoi(vec3 p) {
// https://www.iquilezles.org/www/articles/voronoilines/voronoilines.htm
vec3 b, r, g = floor(p);
p = fract(p);
float d = 1.;
for(int j = -1; j <= 1; j++) {
for(int i = -1; i <= 1; i++) {
b = vec3(i, j, -1);
r = b - p + hash33(g+b);
d = min(d, dot(r,r));
b.z = 0.0;
r = b - p + hash33(g+b);
d = min(d, dot(r,r));
b.z = 1.;
r = b - p + hash33(g+b);
d = min(d, dot(r,r));
}
}
return d;
}
// https://www.iquilezles.org/www/articles/warp/warp.htm
float noiseLayers(in vec3 p) {
vec3 t = vec3(0., 0., p.z+time*1.5);
const int iter = 5;
float tot = 0., sum = 0., amp = 1.;
for (int i = 0; i < iter; i++) {
tot += voronoi(p + t) * amp;
p *= 2.0;
t *= 1.5;
sum += amp;
amp *= 0.5;
}
return tot/sum;
}
float sdPie( in vec2 p, in vec2 c, in float r ) {
p.x = abs(p.x);
float l = length(p) - r;
float m = length(p - c*clamp(dot(p,c),0.0,r) );
return max(l,m*sign(c.y*p.x-c.x*p.y));
}
void main(void) {
float f = (1.-fill)*3.1415;
vec2 uv = (gl_FragCoord.xy - resolution.xy*0.5)/ resolution.y;
float cs = cos(f-time/4.), si = sin(f-time/4.);
uv.xy *= mat2(cs, -si, si, cs);
vec3 rd = normalize(vec3(uv.x, uv.y, 3.1415/8.));
float c = noiseLayers(rd*2.);
float d = dot(uv, uv);
float ts = 0.105 + sin(time)*0.001;
float ring = 1. - min(smoothstep(d, 0.11, ts), smoothstep(d, ts, 0.11));
vec3 col = sqrt(clamp((firePalette(c*ring)-0.03)*1.5, 0., 1.));
if (fill<1.)
col *= sdPie(uv,vec2(sin(f+0.001),cos(f+0.001)), 0.5)*3.1;
gl_FragColor = vec4(col, ring);
}
</script>
<script>
let gl = canvas.getContext('webgl');
gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1,3,-1,-1,3,-1]), gl.STATIC_DRAW);
let pid = gl.createProgram();
shader(`attribute vec2 v;void main(void){gl_Position=vec4(v,0.,1.);}`,gl.VERTEX_SHADER);
shader(document.querySelector(`script[type="glsl"]`).textContent,gl.FRAGMENT_SHADER);
gl.linkProgram(pid);
gl.useProgram(pid);
let v = gl.getAttribLocation(pid, "v");
gl.vertexAttribPointer(v, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(v);
let resolution = gl.getUniformLocation(pid, 'resolution');
let time = gl.getUniformLocation(pid, 'time');
let fill = gl.getUniformLocation(pid, 'fill');
requestAnimationFrame(draw);
function draw(t) {
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
gl.clearColor(0, 0, 0, 0);
gl.uniform1f(time, t/1000);
gl.uniform1f(fill, getComputedStyle(canvas).opacity);
gl.uniform2f(resolution, gl.drawingBufferWidth, gl.drawingBufferHeight);
gl.drawArrays(gl.TRIANGLES, 0, 3);
requestAnimationFrame(draw);
}
function shader(src, type) {
let sid = gl.createShader(type);
gl.shaderSource(sid, src);
gl.compileShader(sid);
var message = gl.getShaderInfoLog(sid);
gl.attachShader(pid, sid);
if (message.length > 0) {
console.log(src.split("\n").map((s, i) => (""+(1+i)).padStart(4, 0)+": "+s).join("\n"));
throw message;
}
}
</script>
<style>
canvas {
position: absolute;
top: -29px;
pointer-events: none;
left: -26px;
opacity: 0;
transition: 1s;
}
.zone {
position: absolute;
top: 16px;
left: 19px;
border-radius: 50%;
width: 245px;
height: 245px;
}
div.zone:hover + canvas{
opacity: 1;
}
</style>
答案 1 :(得分:1)
这是我的解决方案。它应该在网站上复制动画。
编辑:已更新以提供循环显示效果的剪辑,它也可在Firefox上使用:) 它没有使用与原始网站相同的资产,因此公认的效果不佳。通过替换资产,您应该能够获得相同的资产,包括在显示效果结束时发出的火花。
.good {
height: 150px;
width: 150px;
background-image: url(https://image.ibb.co/gapib8/good_icon.png);
background-size: cover;
position:
}
.good .ring {
position: relative;
overflow: hidden;
height: 100%;
width: 100%;
}
.good .ring img {
position: absolute;
top: -1px;
opacity: 0;
height: 100%;
width: 100%;
transition: opacity 0.2s;
}
.good .ring .fire-reveal {
position: absolute;
top: 4.2%;
left: 3.6%;
width: 90%;
height: 90%;
background-image: url(https://preview.ibb.co/cNZZG8/fire_ring_complete.png);
background-size: 588px auto;
background-repeat: no-repeat;
background-position: -150px -300px;
opacity: 0;
transition: 0.2s opacity;
}
.good:hover .ring .fire-reveal {
opacity: 1;
transition: opacity 0.1s;
transform: rotate(5deg);
animation: reveal 0.4s cubic-bezier(0,0,1,1);
}
@keyframes reveal {
0% {
clip-path: polygon(100% 100%, 51% 63%, 100% 30%, 100% 45%, 100% 57%, 100% 100%, 100% 57%, 51% 63%);
}
12.5% {
clip-path: polygon(100% 100%, 51% 63%, 100% 30%, 100% 45%, 100% 57%, 100% 100%, 100% 100%, 51% 63%);
}
25% {
clip-path: polygon(49% 37%, 49% 30%, 100% 30%, 100% 45%, 100% 57%, 100% 100%, 51% 100%, 51% 50%);
}
37.5% {
clip-path: polygon(50% 63%, 51% 63%, 100% 30%, 100% 45%, 100% 57%, 100% 100%, 0 100%, 51% 63%);
}
50% {
clip-path: polygon(0 50%, 50% 54%, 100% 30%, 100% 45%, 100% 57%, 100% 100%, 0 100%, 0 50%);
}
62.5% {
clip-path: polygon(0 0, 52% 53%, 100% 30%, 100% 45%, 100% 57%, 100% 100%, 0 100%, 0 42%);
}
75% {
clip-path: polygon(48% 0, 49% 50%, 100% 30%, 100% 45%, 100% 57%, 100% 100%, 0 100%, 0 0);
}
87.5% {
clip-path: polygon(100% 0, 46% 30%, 100% 30%, 100% 45%, 100% 57%, 100% 100%, 0 100%, 0 0);
}
100% {
clip-path: polygon(100% 0, 100% 0, 100% 30%, 100% 45%, 100% 57%, 100% 100%, 0 100%, 0 0);
}
}
.good:hover .ring img {
opacity:1;
transition: opacity 0.3s;
transition-delay: 0.2s;
animation: rotation 20s linear both infinite;
}
@keyframes rotation {
from {
transform: rotate(0deg) scale(0.9);
}
to {
transform: rotate(360deg) scale(0.9);
}
}
<div class="good">
<div class="ring">
<div class="fire-reveal"></div>
<img src="https://image.ibb.co/eJCQpT/fire_ring.png">
</div>
</div>
答案 2 :(得分:-1)
这是我的解决方案 它不像网站一样。
您可以随意修改动画的时间值
我将旋转动画添加到了火中
.good {
height: 200px;
width: 200px;
background-image: url(https://image.ibb.co/gapib8/good_icon.png);
background-size: cover;
box-sizing: border-box;
padding: 10px;
}
.good .ring {
overflow: hidden;
transition: 1s opacity;
transition-timing-function: easeInOut;
opacity: 0;
height: 100%;
width: 100%;
background-image: url(https://image.ibb.co/eJCQpT/fire_ring.png);
background-repeat: no-repeat;
background-size: cover;
}
.good:hover .ring {
opacity:1;
animation: spin 2800ms linear 0ms infinite;
}
@keyframes spin {
0% {
transform: rotate(0deg);
/* opacity: 0; */
}
50% {
transform: rotate(360deg);
/* opacity: 0; */
}
100% {
transform: rotate(720deg);
/* opacity: 0; */
}
}
<div class="good">
<div class="ring">
</div>
</div>