RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 922230
Accepted
Alexandr_TT
Alexandr_TT
Asked:2020-12-18 03:13:48 +0000 UTC2020-12-18 03:13:48 +0000 UTC 2020-12-18 03:13:48 +0000 UTC

如何在太空中创造动画星星?

  • 772

我正在制作太阳系行星旋转的动画。

https://ru.stackoverflow.com/a/918238/28748

缺少逼真的星空动画背景,如下图所示。

在此处输入图像描述

恒星的大小、亮度、相对位置应该是随机的。

最好添加更大的星星闪烁。

使用 svg,我不能做类似的效果,因为在这种语言中没有类似的东西,如JS Math.random()

如何实现这样的动画Javascript?

javascript
  • 3 3 个回答
  • 10 Views

3 个回答

  • Voted
  1. Misha Saidov
    2020-12-24T08:54:35Z2020-12-24T08:54:35Z

    尽可能接近原件关闭。天上的星星在做什么?好吧,它们最多会跳动或消失一段时间。通过应用具有不同持续时间的相同动画,我们获得了相当逼真的效果。星星的大小从 1 到 5 个像素不等,但我们以 10% 的概率生成一颗大小相同的星星giant——它们比其余的小十倍,稍大一点。您#root>div可以取消注释blur以获得更真实的效果,但一切都会滞后。建议展开到整页。

    const params = {
      amount: 200,
      size: {
        min: 1,
        max: 5,
        giant: 9
      },
      duration: {
        min: 5,
        max: 25,
      }
    }
    const randomBetween = (a, b) => {
      return (a + (Math.random() * (b - a)));
    }
    
    for (let i = 0; i < params.amount; i++) {
      let star = $("<div></div>");
      let size = Math.round(Math.random() * 10) === 0 ? params.size.giant : randomBetween(params.size.min, params.size.max);
      star.css({
        "width": size + "px",
        "height": size + "px",
        "left": randomBetween(0, 100) + "%",
        "top": randomBetween(0, 100) + "%",
        "box-shadow": "0 0 " + size + "px " + size / 2 + "px #043668",
        "animation-duration": randomBetween(params.duration.min, params.duration.max) + "s"
      });
    
      $("#root").append(star);
    }
    body,
    html {
      margin: 0;
      width: 100%;
      height: 100%;
      background: radial-gradient(ellipse at center, rgba(8, 25, 42, 1) 19%, rgba(1, 4, 6, 1) 100%);
    }
    
    #root {
      position: absolute;
      width: 100%;
      height: 100%;
      overflow: hidden;
    }
    
    #root>div {
      position: absolute;
      background: radial-gradient(ellipse at center, rgba(177, 198, 219, 1) 2%, rgba(5, 63, 118, 1) 100%);
      border-radius: 100%;
      /* filter:blur(1px); */
      animation: shine infinite alternate;
    }
    
    @keyframes shine {
      0% {
        transform: scale(1);
        opacity: 1;
      }
      20% {
        transform: scale(.9);
        opacity: .8;
      }
      40% {
        transform: scale(1);
        opacity: .9;
      }
      40% {
        transform: scale(.2);
        opacity: .2;
      }
      60% {
        transform: scale(.2);
        opacity: .1;
      }
      80% {
        transform: scale(.5);
        opacity: .5;
      }
      100% {
        transform: scale(.9);
        opacity: .9;
      }
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    
    <div id="root"></div>

    • 14
  2. Best Answer
    Grundy
    2020-12-18T04:42:29Z2020-12-18T04:42:29Z

    作为一种选择,您可以创建一堆将成为星星的元素,给它们一个随机的位置和大小。

    有的,比如大于设定值的,加个css类,增加闪烁。

    例如像这样:

    function createStar(center, radius, animation) {
      var star = document.createElement('div');
      star.className = 'star';
      star.style.width = `${radius}px`;
      star.style.height = `${radius}px`;
      star.style.top = `${center.top-radius/2}px`;
      star.style.left = `${center.left-radius/2}px`;
      star.style.animationDelay = `${animation.delay}s`;
      star.style.animationDuration = `${animation.duration}s`;
      if (radius > 6) {
        star.classList.add('shine');
      }
      return star;
    }
    var container = document.getElementById("d");
    for (var i = 0; i < 200; i++) {
      container.appendChild(createStar({
        top: getRandom(0, container.offsetHeight),
        left: getRandom(0, container.offsetWidth)
      }, getRandom(2, 7), {
        duration: getRandom(3, 15, false),
        delay: getRandom(0, 7, false)
      }));
    }
    
    function getRandom(min, max, notFloor) {
      return (!notFloor && Math.floor || (a => a))(Math.random() * (max - min + 1) + min);
    }
    html,
    body {
      margin: 0;
      padding: 0;
    }
    
    #d {
      width: 100vw;
      height: 100vh;
      background: #040e17;
      position: relative;
      overflow: hidden;
    }
    
    .star::before {
      content: '';
      background-color: #fff;
      position: absolute;
      border-radius: 50%;
      background-color: rgba(255, 255, 255, 1);
      position: absolute;
      top: 50%;
      left: 50%;
      width: 50%;
      height: 50%;
      transform: translate(-50%, -50%);
    }
    
    .star {
      border-radius: 50%;
      background-color: rgba(255, 255, 255, 0.7);
      position: absolute;
      box-shadow: 0px 0px 2px 1px rgba(255, 255, 255, .5);
    }
    
    .shine {
      animation: shine infinite alternate;
    }
    
    @keyframes shine {
      from {
        box-shadow: 0px 0px 2px 1px rgba(255, 255, 255, .5);
      }
      to {
        box-shadow: 0px 0px 5px 10px rgba(255, 255, 255, .5);
      }
    }
    <div id="d"></div>

    除了常规元素,您还可以使用带有自定义动画的 svg 元素,甚至更好。

    • 10
  3. Stranger in the Q
    2020-04-09T08:36:52Z2020-04-09T08:36:52Z

    我在 WebGL 上的 5 美分 =)

    要在现实生活中使用它,您至少需要用纹理替换数学噪声。


    可以在此行中更改噪声的种子

     #define r(x)     fract(1e4*sin((x) * 541.121))  
    

    星星的排列方式会改变

    <style>body{ margin:0;background-color:black;overflow:hidden}</style>
    <canvas></canvas>
    <script>
    let fragCode = `
      precision highp float;
    
      uniform float time;
      uniform vec2 res;
    
      // вращающийся гексагон 
      // https://www.shadertoy.com/view/4scXWS
      float star( vec2 uv ) {	
         vec2 r = sin(vec2(0, 1.57) + time);
         uv = abs( uv * mat2(r, -r.y, r.x) ) * mat2(2, 0, 1, 1.57); 
         return .1 / max(uv.x, uv.y);
      }
    
      // простенькие 1D 2D и 3D шумы
      #define r(x)     fract(1e4*sin((x) * 541.121))  
      #define sr2(x)   ( r(vec2(x,x+.1)) *2.-1. )
      #define sr3(x)   ( r(vec4(x,x+.1,x+.2,0)) *2.-1. )
    
      void main(void) {
        // текстурные координаты (от 0 до 1) и инверсия по y
        vec2 uv = 2. * gl_FragCoord.xy/res.x - 1.; 
        
      for (float i = 0.; i < 131.; i++) {
            gl_FragColor += 
                star (uv - sr2(i)*res/res.xy )  // звезда в случайном месте
                * r(i+.2)                       // случайный масштаб    
                * (1.+sin(time+r(i+.3)*5.))*.1  // масштаб от времени   
                * (1.+.1*sr3(i+.4));            // случайный цвет
        }
    
        gl_FragColor -= 1.;  // иначе ярко слишком =)
        gl_FragColor.a = 1.; // все не прозрачное
      }
    `;
    
    let canvas = document.querySelector('canvas')
    let gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
    let pid = gl.createProgram();
    
    shader(`
      attribute vec2 coords;
      void main(void) {
        gl_Position = vec4(coords.xy, 0.0, 1.0);
      }
    `, gl.VERTEX_SHADER);
    
    shader(fragCode, gl.FRAGMENT_SHADER);
    
    gl.linkProgram(pid);
    gl.useProgram(pid);
    
    let array = new Float32Array([-1,  3, -1, -1, 3, -1]);
    gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());
    gl.bufferData(gl.ARRAY_BUFFER, array, gl.STATIC_DRAW);
    
    let al = gl.getAttribLocation(pid, "coords");
    gl.vertexAttribPointer(al, 2, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(al);
    
    var time = gl.getUniformLocation(pid, 'time');
    var res = gl.getUniformLocation(pid, 'res');
    
    window.addEventListener('resize', resize, resize());
    requestAnimationFrame(animate);
    
    function animate(dt) {    
        gl.uniform1f(time,dt/1000);
        gl.uniform2f(res, gl.drawingBufferWidth, gl.drawingBufferHeight);
        gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
        gl.clearColor(0, 0, 0, 0);
        gl.drawArrays(gl.TRIANGLES, 0, 3);
        requestAnimationFrame(animate);
    }
    
    function shader(src, type) {
      let sid = gl.createShader(type);
      gl.shaderSource(sid, src);
      gl.compileShader(sid);
      gl.attachShader(pid, sid);
    }
    
    function resize() {
      canvas.width = window.innerWidth;
      canvas.height = window.innerHeight;
    }
    
    
    </script>


    该选项更简单,着色器中循环的迭代次数更少,星星和刹车更少。

    <style>body{ margin:0;background-color:black;overflow:hidden}</style>
    <canvas></canvas>
    <script>
    let fragCode = `
      precision highp float;
    
      uniform float time;
      uniform vec2 res;
    
      // вращающийся гексагон 
      // https://www.shadertoy.com/view/4scXWS
      float star( vec2 uv ) {	
         vec2 r = sin(vec2(0, 1.57) + time);
         uv = abs( uv * mat2(r, -r.y, r.x) ) * mat2(2, 0, 1, 1.57); 
         return .2 / max(uv.x, uv.y);
      }
    
      // простенькие 1D 2D и 3D шумы
      #define r(x)     fract(1e4*sin((x) * 541.121))  
      #define sr2(x)   ( r(vec2(x,x+.1)) *2.-1. )
      #define sr3(x)   ( r(vec4(x,x+.1,x+.2,0)) *2.-1. )
    
      void main(void) {
        // текстурные координаты (от 0 до 1) и инверсия по y
        vec2 uv = 2. * gl_FragCoord.xy/res.x - 1.; 
        
        for (int i = 0; i < 44; i++) {
            float s = float(i);
            gl_FragColor += 
                star(uv - sr2(s))                     // звезда в случайном месте
                * (2.0 + sin(time + r(s + 0.2)))*.04  // масштаб от времени   
                * (1.0 + 0.1*sr3(s + 0.1));           // случайный цвет
        }
    
        gl_FragColor -= 1.;  // иначе ярко слишком =)
        gl_FragColor.a = 1.; // все не прозрачное
      }
    `;
    
    let canvas = document.querySelector('canvas')
    let gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
    let pid = gl.createProgram();
    
    shader(`
      attribute vec2 coords;
      void main(void) {
        gl_Position = vec4(coords.xy, 0.0, 1.0);
      }
    `, gl.VERTEX_SHADER);
    
    shader(fragCode, gl.FRAGMENT_SHADER);
    
    gl.linkProgram(pid);
    gl.useProgram(pid);
    
    let array = new Float32Array([-1,  3, -1, -1, 3, -1]);
    gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());
    gl.bufferData(gl.ARRAY_BUFFER, array, gl.STATIC_DRAW);
    
    let al = gl.getAttribLocation(pid, "coords");
    gl.vertexAttribPointer(al, 2, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(al);
    
    var time = gl.getUniformLocation(pid, 'time');
    var res = gl.getUniformLocation(pid, 'res');
    
    window.addEventListener('resize', resize, resize());
    requestAnimationFrame(animate);
    
    function animate(dt) {    
        gl.uniform1f(time,dt/1000);
        gl.uniform2f(res, gl.drawingBufferWidth, gl.drawingBufferHeight);
        gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
        gl.clearColor(0, 0, 0, 0);
        gl.drawArrays(gl.TRIANGLES, 0, 3);
        requestAnimationFrame(animate);
    }
    
    function shader(src, type) {
      let sid = gl.createShader(type);
      gl.shaderSource(sid, src);
      gl.compileShader(sid);
      gl.attachShader(pid, sid);
    }
    
    function resize() {
      canvas.width = window.innerWidth;
      canvas.height = window.innerHeight;
    }
    
    
    </script>

    • 6

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    是否可以在 C++ 中继承类 <---> 结构?

    • 2 个回答
  • Marko Smith

    这种神经网络架构适合文本分类吗?

    • 1 个回答
  • Marko Smith

    为什么分配的工作方式不同?

    • 3 个回答
  • Marko Smith

    控制台中的光标坐标

    • 1 个回答
  • Marko Smith

    如何在 C++ 中删除类的实例?

    • 4 个回答
  • Marko Smith

    点是否属于线段的问题

    • 2 个回答
  • Marko Smith

    json结构错误

    • 1 个回答
  • Marko Smith

    ServiceWorker 中的“获取”事件

    • 1 个回答
  • Marko Smith

    c ++控制台应用程序exe文件[重复]

    • 1 个回答
  • Marko Smith

    按多列从sql表中选择

    • 1 个回答
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Suvitruf - Andrei Apanasik 什么是空? 2020-08-21 01:48:09 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5