画布,JS火炬效果:用图片填充背景

时间:2017-10-16 17:54:27

标签: javascript canvas

我在画布上画了一幅动画火焰。 它应该创建火炬效果,点亮页面的背景。 一切正常,直到我不想将画布的背景更改为图片。它根本不起作用。 当我通过css设置背景时 - 我的火焰颜色整个画布。 有人可以帮我改变画布背景而不破坏效果吗?

这是代码集的link

window.onload = function() {
  var canvas = document.getElementById("canvas");
  var ctx = canvas.getContext("2d");

  //Make the canvas occupy the full page
  var W = window.innerWidth,
    H = window.innerHeight;
  canvas.width = W;
  canvas.height = H;

  var particles = [];
  var mouse = {};

  //Lets create some particles now
  var particle_count = 100;
  for (var i = 0; i < particle_count; i++) {
    particles.push(new particle());
  }

  //finally some mouse tracking
  canvas.addEventListener('mousemove', track_mouse, false);

  function track_mouse(e) {
    //since the canvas = full page the position of the mouse 
    //relative to the document will suffice
    mouse.x = e.pageX;
    mouse.y = e.pageY;
  }

  function particle() {
    //speed, life, location, life, colors
    //speed.x range = -2.5 to 2.5 
    //speed.y range = -15 to -5 to make it move upwards
    //lets change the Y speed to make it look like a flame
    this.speed = {
      x: -2.5 + Math.random() * 5,
      y: -15 + Math.random() * 10
    };
    //location = mouse coordinates
    //Now the flame follows the mouse coordinates
    if (mouse.x && mouse.y) {
      this.location = {
        x: mouse.x,
        y: mouse.y
      };
    } else {
      this.location = {
        x: W / 2,
        y: H / 2
      };
    }
    //radius range = 10-30
    this.radius = 10 + Math.random() * 20;
    //life range = 20-30
    this.life = 20 + Math.random() * 10;
    this.remaining_life = this.life;
    //colors
    this.r = 74;
    this.g = 77;
    this.b = 84;
    //		this.r = Math.round(Math.random()*255);
    //		this.g = Math.round(Math.random()*255);
    //		this.b = Math.round(Math.random()*255);
  }


  function draw() {
    //Painting the canvas black
    //Time for lighting magic
    //particles are painted with "lighter"
    //In the next frame the background is painted normally without blending to the 
    //previous framevar im = new Image();

    ctx.globalCompositeOperation = "source-over";
    //		var im = new Image();
    //		im.src = "./background.jpg";
    //		im.onload = function (){
    //		ctx.drawImage(im, W, H);
    //		}

    ctx.fillStyle = "black";
    ctx.fillRect(0, 0, W, H);

    //		var src    = "../images/background.jpg";
    //	    var img    = new Image();
    //	    img.src    = src;
    //	    $(img).load(function() {
    //			var pattern = ctx.createPattern(img, 'repeat');
    //			ctx.fillStyle = pattern;
    //			ctx.fillRect(0, 0, W, H);
    //		  });

    ctx.globalCompositeOperation = "lighter";

    for (var i = 0; i < particles.length; i++) {
      var p = particles[i];
      ctx.beginPath();
      //changing opacity according to the life.
      //opacity goes to 0 at the end of life of a particle
      p.opacity = Math.round(p.remaining_life / p.life * 100) / 100
      //a gradient instead of white fill
      var gradient = ctx.createRadialGradient(p.location.x, p.location.y, 0, p.location.x, p.location.y, p.radius);
      //			p.r = 128;
      //			p.g = 34;
      //			p.b = 34;
      p.r = 255;
      p.g = 69;
      p.b = 0;
      gradient.addColorStop(0, "rgba(" + p.r + ", " + p.g + ", " + p.b + ", " + p.opacity + ")");
      gradient.addColorStop(0.2, "rgba(" + p.r + ", " + p.g + ", " + p.b + ", " + p.opacity + ")");
      gradient.addColorStop(1, "rgba(" + p.r + ", " + p.g + ", " + p.b + ", 0)");
      ctx.fillStyle = gradient;
      ctx.arc(p.location.x, p.location.y, p.radius, Math.PI * 2, false);
      ctx.fill();

      //lets move the particles
      p.remaining_life--;
      p.radius--;
      p.location.x += p.speed.x;
      p.location.y += p.speed.y;

      //regenerate particles
      if (p.remaining_life < 0 || p.radius < 0) {
        //a brand new particle replacing the dead one
        particles[i] = new particle();
      }
    }

    ctx.font = "30px Comic Sans MS";
    ctx.fillStyle = "white";
    ctx.textAlign = "center";
    ctx.fillText("Hello World", canvas.width / 2, canvas.height / 2);
  }

  setInterval(draw, 33);

  /****************************TORCH LIGHT*********************************/

  //
  //canvas.addEventListener('mouseout', function(e) {
  //  window.cancelAnimationFrame(raf);
  //  running = false;
  //});

  function update(e) {
    //set e as .torch class
    //var element = document.getElementsByClassName("torch"); 
    var x = e.clientX || e.touches[0].clientX
    var y = e.clientY || e.touches[0].clientY


    document.documentElement.style.setProperty('--cursorX', x + 'px')
    document.documentElement.style.setProperty('--cursorY', y + 'px')
  }

  document.addEventListener('mousemove', update)
  document.addEventListener('touchmove', update)

  // lets light up canvas element after click

  //	function change_the_before_attribute(other_background) {
  //	other_background.className="torch after-click";
  //}
  $(function() {
    $(".torch").click(function() {
      $(".torch").addClass(".torch .after-click");
    });
  });
  //changes background of body
  //$(function () {
  //    $("body").click(function () {
  //        $(this).css('background-color', 'rgba(255,0,0,.95)');
  //    });
  //});


}
* {
  margin: 0;
  padding: 0;
}

#canvas {
  display: block;
  /*	background: url("../images/background.jpg");*/
}

.torch {
  /*  cursor: none;*/
  --cursorX: 50vw;
  --cursorY: 50vh;
}

:root:before {
  content: '';
  display: block;
  width: 100%;
  height: 100%;
  position: fixed;
  pointer-events: none;
  background: radial-gradient( circle 10vmax at var(--cursorX) var(--cursorY), rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, .5) 50%, rgba(0, 0, 0, .95) 100%)
}

.torch .after-click:before {
  background: transparent;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="torch">
  <canvas id="canvas"></canvas>
</div>

1 个答案:

答案 0 :(得分:0)

设置ctx变量后添加以下代码:

 var base_image = new Image();
  base_image.src = 'https://images.unsplash.com/photo-1499955618064-79cd8e8d8672?ixlib=rb-0.3.5&q=85&fm=jpg&crop=entropy&cs=srgb&s=13c8ccb1b33e610c3e8d6a4094dc85fd';
  base_image.onload = function(){
    ctx.drawImage(base_image, 100, 100);
  }

然后在draw方法中添加以下行:

ctx.drawImage(base_image, 100, 100);

在纯CSS中将画布背景添加到画布中是行不通的。将其添加为图像对象将。此代码初始化图像并在加载时绘制到画布。在绘制方法中,我们每帧重新将图像重新绘制到画布上。

希望这有帮助!