为了账号安全,请及时绑定邮箱和手机立即绑定

如何更改 Javascript 对象的不透明度

如何更改 Javascript 对象的不透明度

慕虎7371278 2024-01-18 10:44:10
在这里找到使用普通 JavaScript 的元球代码。有什么方法可以改变元球的不透明度吗?我认为这应该是一个快速解决方案,但我不太确定。我尝试更改为 CSS 类气泡,但这不起作用,所以我假设需要在 Javascript 中。有什么帮助,谢谢。在这里找到使用普通 JavaScript 的元球代码。有什么方法可以改变元球的不透明度吗?我认为这应该是一个快速解决方案,但我不太确定。我尝试更改为 CSS 类气泡,但这不起作用,所以我假设需要在 Javascript 中。有什么帮助,谢谢。body {  margin: 0;}.wrap {  overflow: hidden;  position: relative;  height: 100vh;}canvas {  width: 100%;  height: 100%;}<div class="wrap">  <canvas id="bubble"></canvas></div>
查看完整描述

2 回答

?
当年话下

TA贡献1890条经验 获得超9个赞

您可以通过使用 RGBA 更改上下文 alpha 通道来实现此目的(请参阅最底部ctx.fillStyle = 'rgba(0, 0, 255, 0.5)' // NEW!,其中 0.5 是不透明度级别 - 请参阅):

;

(function() {

  'use strict'


  var lava0

  var ge1doot = {

    screen: {

      elem: null,

      callback: null,

      ctx: null,

      width: 0,

      height: 0,

      left: 0,

      top: 0,

      init: function(id, callback, initRes) {

        this.elem = document.getElementById(id)

        this.callback = callback || null

        if (this.elem.tagName == 'CANVAS') this.ctx = this.elem.getContext('2d')

        window.addEventListener(

          'resize',

          function() {

            this.resize()

          }.bind(this),

          false

        )

        this.elem.onselectstart = function() {

          return false

        }

        this.elem.ondrag = function() {

          return false

        }

        initRes && this.resize()

        return this

      },

      resize: function() {

        var o = this.elem

        this.width = o.offsetWidth

        this.height = o.offsetHeight

        for (this.left = 0, this.top = 0; o != null; o = o.offsetParent) {

          this.left += o.offsetLeft

          this.top += o.offsetTop

        }

        if (this.ctx) {

          this.elem.width = this.width

          this.elem.height = this.height

        }

        this.callback && this.callback()

      },

    },

  }


  // Point constructor

  var Point = function(x, y) {

    this.x = x

    this.y = y

    this.magnitude = x * x + y * y

    this.computed = 0

    this.force = 0

  }

  Point.prototype.add = function(p) {

    return new Point(this.x + p.x, this.y + p.y)

  }


  // Ball constructor

  var Ball = function(parent) {

    var min = 0.1

    var max = 1.5

    this.vel = new Point(

      (Math.random() > 0.5 ? 1 : -1) * (0.2 + Math.random() * 0.25),

      (Math.random() > 0.5 ? 1 : -1) * (0.2 + Math.random())

    )

    this.pos = new Point(

      parent.width * 0.2 + Math.random() * parent.width * 0.6,

      parent.height * 0.2 + Math.random() * parent.height * 0.6

    )

    this.size = parent.wh / 15 + (Math.random() * (max - min) + min) * (parent.wh / 15)

    this.width = parent.width

    this.height = parent.height

  }


  // move balls

  Ball.prototype.move = function() {

    // bounce borders

    if (this.pos.x >= this.width - this.size) {

      if (this.vel.x > 0) this.vel.x = -this.vel.x

      this.pos.x = this.width - this.size

    } else if (this.pos.x <= this.size) {

      if (this.vel.x < 0) this.vel.x = -this.vel.x

      this.pos.x = this.size

    }


    if (this.pos.y >= this.height - this.size) {

      if (this.vel.y > 0) this.vel.y = -this.vel.y

      this.pos.y = this.height - this.size

    } else if (this.pos.y <= this.size) {

      if (this.vel.y < 0) this.vel.y = -this.vel.y

      this.pos.y = this.size

    }


    // velocity

    this.pos = this.pos.add(this.vel)

  }


  // lavalamp constructor

  var LavaLamp = function(width, height, numBalls, c0, c1) {

    this.step = 5

    this.width = width

    this.height = height

    this.wh = Math.min(width, height)

    this.sx = Math.floor(this.width / this.step)

    this.sy = Math.floor(this.height / this.step)

    this.paint = false

    this.metaFill = createRadialGradient(width, height, width, c0, c1)

    this.plx = [0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0]

    this.ply = [0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1]

    this.mscases = [0, 3, 0, 3, 1, 3, 0, 3, 2, 2, 0, 2, 1, 1, 0]

    this.ix = [1, 0, -1, 0, 0, 1, 0, -1, -1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1]

    this.grid = []

    this.balls = []

    this.iter = 0

    this.sign = 1


    // init grid

    for (var i = 0; i < (this.sx + 2) * (this.sy + 2); i++) {

      this.grid[i] = new Point((i % (this.sx + 2)) * this.step, Math.floor(i / (this.sx + 2)) * this.step)

    }


    // create metaballs

    for (var k = 0; k < numBalls; k++) {

      this.balls[k] = new Ball(this)

    }

  }

  // compute cell force

  LavaLamp.prototype.computeForce = function(x, y, idx) {

    var force

    var id = idx || x + y * (this.sx + 2)


    if (x === 0 || y === 0 || x === this.sx || y === this.sy) {

      force = 0.6 * this.sign

    } else {

      force = 0

      var cell = this.grid[id]

      var i = 0

      var ball

      while ((ball = this.balls[i++])) {

        force +=

          (ball.size * ball.size) /

          (-2 * cell.x * ball.pos.x - 2 * cell.y * ball.pos.y + ball.pos.magnitude + cell.magnitude)

      }

      force *= this.sign

    }

    this.grid[id].force = force

    return force

  }

  // compute cell

  LavaLamp.prototype.marchingSquares = function(next) {

    var x = next[0]

    var y = next[1]

    var pdir = next[2]

    var id = x + y * (this.sx + 2)

    if (this.grid[id].computed === this.iter) {

      return false

    }

    var dir,

      mscase = 0


    // neighbors force

    for (var i = 0; i < 4; i++) {

      var idn = x + this.ix[i + 12] + (y + this.ix[i + 16]) * (this.sx + 2)

      var force = this.grid[idn].force

      if ((force > 0 && this.sign < 0) || (force < 0 && this.sign > 0) || !force) {

        // compute force if not in buffer

        force = this.computeForce(x + this.ix[i + 12], y + this.ix[i + 16], idn)

      }

      if (Math.abs(force) > 1) mscase += Math.pow(2, i)

    }

    if (mscase === 15) {

      // inside

      return [x, y - 1, false]

    } else {

      // ambiguous cases

      if (mscase === 5) dir = pdir === 2 ? 3 : 1

      else if (mscase === 10) dir = pdir === 3 ? 0 : 2

      else {

        // lookup

        dir = this.mscases[mscase]

        this.grid[id].computed = this.iter

      }

      // draw line

      var ix =

        this.step /

        (Math.abs(

            Math.abs(this.grid[x + this.plx[4 * dir + 2] + (y + this.ply[4 * dir + 2]) * (this.sx + 2)].force) - 1

          ) /

          Math.abs(

            Math.abs(this.grid[x + this.plx[4 * dir + 3] + (y + this.ply[4 * dir + 3]) * (this.sx + 2)].force) - 1

          ) +

          1)

      ctx.lineTo(

        this.grid[x + this.plx[4 * dir] + (y + this.ply[4 * dir]) * (this.sx + 2)].x + this.ix[dir] * ix,

        this.grid[x + this.plx[4 * dir + 1] + (y + this.ply[4 * dir + 1]) * (this.sx + 2)].y + this.ix[dir + 4] * ix

      )

      this.paint = true

      // next

      return [x + this.ix[dir + 4], y + this.ix[dir + 8], dir]

    }

  }


  LavaLamp.prototype.renderMetaballs = function() {

    var i = 0,

      ball

    while ((ball = this.balls[i++])) ball.move()

    // reset grid

    this.iter++

      this.sign = -this.sign

    this.paint = false

    ctx.fillStyle = this.metaFill

    ctx.beginPath()

    // compute metaballs

    i = 0

    //ctx.shadowBlur = 50;

    //ctx.shadowColor = "green";

    while ((ball = this.balls[i++])) {

      // first cell

      var next = [Math.round(ball.pos.x / this.step), Math.round(ball.pos.y / this.step), false]

      // marching squares

      do {

        next = this.marchingSquares(next)

      } while (next)

      // fill and close path

      if (this.paint) {

        ctx.fill()

        ctx.closePath()

        ctx.beginPath()

        this.paint = false

      }

    }

  }


  // gradients

  var createRadialGradient = function(w, h, r, c0, c1) {

    var gradient = ctx.createRadialGradient(w / 1, h / 1, 0, w / 1, h / 1, r)

    gradient.addColorStop(0, c0)

    gradient.addColorStop(1, c1)

  }


  // main loop

  var run = function() {

    requestAnimationFrame(run)

    ctx.clearRect(0, 0, screen.width, screen.height)

    ctx.fillStyle = 'rgba(0, 0, 255, 0.5)' // NEW!

    lava0.renderMetaballs()

  }

  // canvas

  var screen = ge1doot.screen.init('bubble', null, true),

    ctx = screen.ctx

  screen.resize()

  // create LavaLamps

  lava0 = new LavaLamp(screen.width, screen.height, 6, '#FF9298', '#E4008E')


  run()

})()

body {

  margin: 0;

}


.wrap {

  overflow: hidden;

  position: relative;

  height: 100vh;

}


canvas {

  width: 100%;

  height: 100%;

}

<div class="wrap">

  <canvas id="bubble"></canvas>

</div>



查看完整回答
反对 回复 2024-01-18
?
冉冉说

TA贡献1877条经验 获得超1个赞

您的 Lava 构造函数采用两种颜色,可以修改这些颜色以满足您的颜色需求。通过使用rgba()颜色版本,您可以设置 alpha(即不透明度)或气泡/肉丸。但是,在执行此操作之前,您需要返回gradient创建的 颜色createRadialGradient,以便可以使用颜色:


var createRadialGradient = function(w, h, r, c0, c1) {

  // ... code ...

  return gradient; // add this line

};

现在您可以修改调用构造函数的方式:


// rgba versions of your colors -----------------------\/

lava0 = new LavaLamp(screen.width, screen.height, 6, "rgba(255, 146, 152, 0.5)", "rgba(228, 0, 142, 0.5)");

;(function() {


  "use strict";


  var lava0;

  var ge1doot = {

    screen: {

      elem:     null,

      callback: null,

      ctx:      null,

      width:    0,

      height:   0,

      left:     0,

      top:      0,

      init: function (id, callback, initRes) {

        this.elem = document.getElementById(id);

        this.callback = callback || null;

        if (this.elem.tagName == "CANVAS") this.ctx = this.elem.getContext("2d");

        window.addEventListener('resize', function () {

          this.resize();

        }.bind(this), false);

        this.elem.onselectstart = function () { return false; }

        this.elem.ondrag        = function () { return false; }

        initRes && this.resize();

        return this;

      },

      resize: function () {

        var o = this.elem;

        this.width  = o.offsetWidth;

        this.height = o.offsetHeight;

        for (this.left = 0, this.top = 0; o != null; o = o.offsetParent) {

          this.left += o.offsetLeft;

          this.top  += o.offsetTop;

        }

        if (this.ctx) {

          this.elem.width  = this.width;

          this.elem.height = this.height;

        }

        this.callback && this.callback();

      }

    }

  }


  // Point constructor

  var Point = function(x, y) {

    this.x = x;

    this.y = y;

    this.magnitude = x * x + y * y;

    this.computed = 0;

    this.force = 0;

  };

  Point.prototype.add = function(p) {

    return new Point(this.x + p.x, this.y + p.y);

  };


  // Ball constructor

  var Ball = function(parent) {

    var min = .1;

    var max = 1.5;

    this.vel = new Point(

      (Math.random() > 0.5 ? 1 : -1) * (0.2 + Math.random() * 0.25), (Math.random() > 0.5 ? 1 : -1) * (0.2 + Math.random())

    );

    this.pos = new Point(

      parent.width * 0.2 + Math.random() * parent.width * 0.6,

      parent.height * 0.2 + Math.random() * parent.height * 0.6

    );

    this.size = (parent.wh / 15) + ( Math.random() * (max - min) + min ) * (parent.wh / 15);

    this.width = parent.width;

    this.height = parent.height;

  };


  // move balls

  Ball.prototype.move = function() {


    // bounce borders

    if (this.pos.x >= this.width - this.size) {

      if (this.vel.x > 0) this.vel.x = -this.vel.x;

      this.pos.x = this.width - this.size;

    } else if (this.pos.x <= this.size) {

      if (this.vel.x < 0) this.vel.x = -this.vel.x;

      this.pos.x = this.size;

    }


    if (this.pos.y >= this.height - this.size) {

      if (this.vel.y > 0) this.vel.y = -this.vel.y;

      this.pos.y = this.height - this.size;

    } else if (this.pos.y <= this.size) {

      if (this.vel.y < 0) this.vel.y = -this.vel.y;

      this.pos.y = this.size;

    }


    // velocity

    this.pos = this.pos.add(this.vel);


  };


  // lavalamp constructor

  var LavaLamp = function(width, height, numBalls, c0, c1) {

    this.step = 5;

    this.width = width;

    this.height = height;

    this.wh = Math.min(width, height);

    this.sx = Math.floor(this.width / this.step);

    this.sy = Math.floor(this.height / this.step);

    this.paint = false;

    this.metaFill = createRadialGradient(width, height, width, c0, c1);

    this.plx = [0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0];

    this.ply = [0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1];

    this.mscases = [0, 3, 0, 3, 1, 3, 0, 3, 2, 2, 0, 2, 1, 1, 0];

    this.ix = [1, 0, -1, 0, 0, 1, 0, -1, -1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1];

    this.grid = [];

    this.balls = [];

    this.iter = 0;

    this.sign = 1;


    // init grid

    for (var i = 0; i < (this.sx + 2) * (this.sy + 2); i++) {

      this.grid[i] = new Point(

        (i % (this.sx + 2)) * this.step, (Math.floor(i / (this.sx + 2))) * this.step

      )

    }


    // create metaballs

    for (var k = 0; k < numBalls; k++) {

      this.balls[k] = new Ball(this);

    }

  };

  // compute cell force

  LavaLamp.prototype.computeForce = function(x, y, idx) {


    var force;

    var id = idx || x + y * (this.sx + 2);


    if (x === 0 || y === 0 || x === this.sx || y === this.sy) {

      force = 0.6 * this.sign;

    } else {

      force = 0;

      var cell = this.grid[id];

      var i = 0;

      var ball;

      while (ball = this.balls[i++]) {

        force += ball.size * ball.size / (-2 * cell.x * ball.pos.x - 2 * cell.y * ball.pos.y + ball.pos.magnitude + cell.magnitude);

      }

      force *= this.sign

    }

    this.grid[id].force = force;

    return force;

  };

  // compute cell

  LavaLamp.prototype.marchingSquares = function(next) {

    var x = next[0];

    var y = next[1];

    var pdir = next[2];

    var id = x + y * (this.sx + 2);

    if (this.grid[id].computed === this.iter) {

      return false;

    }

    var dir, mscase = 0;


    // neighbors force

    for (var i = 0; i < 4; i++) {

      var idn = (x + this.ix[i + 12]) + (y + this.ix[i + 16]) * (this.sx + 2);

      var force = this.grid[idn].force;

      if ((force > 0 && this.sign < 0) || (force < 0 && this.sign > 0) || !force) {

        // compute force if not in buffer

        force = this.computeForce(

          x + this.ix[i + 12],

          y + this.ix[i + 16],

          idn

        );

      }

      if (Math.abs(force) > 1) mscase += Math.pow(2, i);

    }

    if (mscase === 15) {

      // inside

      return [x, y - 1, false];

    } else {

      // ambiguous cases

      if (mscase === 5) dir = (pdir === 2) ? 3 : 1;

      else if (mscase === 10) dir = (pdir === 3) ? 0 : 2;

      else {

        // lookup

        dir = this.mscases[mscase];

        this.grid[id].computed = this.iter;

      }

      // draw line

      var ix = this.step / (

          Math.abs(Math.abs(this.grid[(x + this.plx[4 * dir + 2]) + (y + this.ply[4 * dir + 2]) * (this.sx + 2)].force) - 1) /

          Math.abs(Math.abs(this.grid[(x + this.plx[4 * dir + 3]) + (y + this.ply[4 * dir + 3]) * (this.sx + 2)].force) - 1) + 1

        );

      ctx.lineTo(

        this.grid[(x + this.plx[4 * dir]) + (y + this.ply[4 * dir]) * (this.sx + 2)].x + this.ix[dir] * ix,

        this.grid[(x + this.plx[4 * dir + 1]) + (y + this.ply[4 * dir + 1]) * (this.sx + 2)].y + this.ix[dir + 4] * ix

      );

      this.paint = true;

      // next

      return [

        x + this.ix[dir + 4],

        y + this.ix[dir + 8],

        dir

      ];

    }

  };


  LavaLamp.prototype.renderMetaballs = function() {

    var i = 0, ball;

    while (ball = this.balls[i++]) ball.move();

    // reset grid

    this.iter++;

    this.sign = -this.sign;

    this.paint = false;

    ctx.fillStyle = this.metaFill;

    ctx.beginPath();

    // compute metaballs

    i = 0;

    //ctx.shadowBlur = 50;

    //ctx.shadowColor = "green";

    while (ball = this.balls[i++]) {

      // first cell

      var next = [

        Math.round(ball.pos.x / this.step),

        Math.round(ball.pos.y / this.step), false

      ];

      // marching squares

      do {

        next = this.marchingSquares(next);

      } while (next);

      // fill and close path

      if (this.paint) {

        ctx.fill();

        ctx.closePath();

        ctx.beginPath();

        this.paint = false;

      }

    }

  };


  // gradients

  var createRadialGradient = function(w, h, r, c0, c1) {

    var gradient = ctx.createRadialGradient(

      w / 1, h / 1, 0,

      w / 1, h / 1, r

    );

    gradient.addColorStop(0, c0);

    gradient.addColorStop(1, c1);

    return gradient;

  };


  // main loop

  var run = function() {

    requestAnimationFrame(run);

    ctx.clearRect(0, 0, screen.width, screen.height);

    lava0.renderMetaballs();

  };

  // canvas

  var screen = ge1doot.screen.init("bubble", null, true),

      ctx = screen.ctx;

  screen.resize();

  // create LavaLamps

  lava0 = new LavaLamp(screen.width, screen.height, 6, "rgba(255, 146, 152, 0.5)", "rgba(228, 0, 142, 0.5)");


  run();


})();

body {

  margin: 0;

}


.wrap {

  overflow: hidden;

  position: relative;

  height: 100vh;

}


canvas {

  width: 100%;

  height: 100%;

}

<div class="wrap">

  <canvas id="bubble"></canvas>

</div>


查看完整回答
反对 回复 2024-01-18
  • 2 回答
  • 0 关注
  • 29 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信