如何使用CSS将画布与背景混合?

时间:2016-08-03 14:47:58

标签: css canvas

我有这个程序,使用户可以绘制。我希望您正在绘制的画布覆盖在背景上。

这适用于firefox,但不适用于chrome。

http://codepen.io/anon/pen/RRBywo

这是我尝试使用的CSS:

body {

  background-image: url('http://previews.123rf.com/images/pyzata/pyzata1307/pyzata130700105/20855013-black-and-white-brick-abstract-texture-background-Stock-Photo.jpg');

  mix-blend-mode: normal;

}


canvas {

  mix-blend-mode: overlay;

}

以下是我的画布的P5JS代码:

function setup() {

  c = createCanvas(window.innerWidth, window.innerHeight);

  c.position(0, 0);

}

var oldX = 0;

var oldY = 0;


function draw() {


  if (mouseIsPressed) {

    strokeWeight(10);

    stroke(random(0,255),random(0,255),random(0,255));

    if (mouseX == oldX && mouseY == oldY) {

      point(mouseX, mouseY);

    } else {graffitiLine(mouseX, mouseY, oldX, oldY);

    }

  }

  oldX = mouseX;

  oldY = mouseY;

}

function graffitiLine(x0, y0, x1, y1) {

  line(x0, y0, x1, y1);

}

function disBetween(x0,y0,x1,y1){

  return sqrt(((x0-x1)*(x0-x1))+((y0-y1)*(y0-y1)));

}

并且是的,我确实知道图像是丑陋的并带有水印,我稍后会改变它。

2 个答案:

答案 0 :(得分:0)

我不太了解p5,但是如果没有CSS,你想要的是可以实现的:

  • 首先,用香草色替换你的p5画布。
  • 在您的绘图中,像往常一样在p5画布上(现在在屏幕外),然后绘制背景图像,将可见画布globalCompositeOperation更改为'multiply',填充红色矩形,最后在可见的画布上画出你的p5画布,gCO设置为'overlay'

瞧!

(这里我将草图转换为“实例模式”草图,但可能没有必要......)

var c, // your p5 canvas
  main, ctx, // the main canvas where we'll draw everything
  img; // the background-image

// we need to start the sketch in "instance mode" so we can have the background-image loaded
var s = function(p) {
  p.setup = function setup() {
    c = p.createCanvas(window.innerWidth, window.innerHeight);
    c.position(0, 0);
    main = c.elt.cloneNode(true);
    document.body.replaceChild(main, c.elt); // replace the p5 canvas with our own
    ctx = main.getContext('2d');
  }

  p.draw = function draw() {

    if (p.mouseIsPressed) {
      p.strokeWeight(10);
      p.stroke(p.random(0, 255), p.random(0, 255), p.random(0, 255), p.random(0, 255));
      if (p.mouseX == p.oldX && p.mouseY == p.oldY) {
        p.point(p.mouseX, p.mouseY);
      } else {
        graffitiLine(p.mouseX, p.mouseY, p.oldX, p.oldY);
      }
    }
    p.oldX = p.mouseX;
    p.oldY = p.mouseY;

    drawToMain();
  }

  function drawToMain() {

    ctx.globalCompositeOperation = 'source-over';
    ctx.drawImage(img, 0, 0);
    ctx.globalCompositeOperation = 'multiply';
    ctx.fillStyle = "red";
    ctx.fillRect(0, 0, main.width, main.height);
    ctx.globalCompositeOperation = 'overlay';
    ctx.drawImage(c.elt, 0, 0);

  }

  function graffitiLine(x0, y0, x1, y1) {
    p.line(x0, y0, x1, y1);
  }
};

function init() {
  var myp5 = new p5(s);
}

img = new Image();
img.onload = init;
img.src = "http://previews.123rf.com/images/pyzata/pyzata1307/pyzata130700105/20855013-black-and-white-brick-abstract-texture-background-Stock-Photo.jpg"
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.0/p5.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.0/addons/p5.dom.min.js"></script>

Ps:我不知道为什么CSS不能用于chrome,也许你应该在bugzilla中打开一个问题。

答案 1 :(得分:0)

试试这个CSS:

body{
        background: url('http://previews.123rf.com/images/pyzata/pyzata1307/pyzata130700105/20855013-black-and-white-brick-abstract-texture-background-Stock-Photo.jpg') red;
  background-blend-mode: multiply;
}

它似乎适用于Chrome中的codepen代码段。

修改

我误解了这个问题。这是一个简单的HTML5画布小提琴:https://jsfiddle.net/hrivas/t2204vxh/ - 我还不太了解P5JS。

基本上,您需要绘制图像并将其与所需的背景颜色混合,并且在绘制时间时,您可以更改混合模式(有几种可供选择):

var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var img = document.createElement('IMG');

img.src = 'http://previews.123rf.com/images/pyzata/pyzata1307/pyzata130700105/20855013-black-and-white-brick-abstract-texture-background-Stock-Photo.jpg';

// compose the image and the background when the image is loaded
img.onload = function () {
    context.globalCompositeOperation = "multiply";
    context.drawImage(img, 0, 0);

    context.fillStyle = "rgba(255, 0, 0, 1)";
    context.fillRect(0, 0, canvas.width, canvas.height);
}

document.onmousemove = function() {
  var x = event.offsetX;
  var y = event.offsetY;

  // grafitti brush
  var r = 0;//parseInt(255 * Math.random());
  var g = 0;//parseInt(255 * Math.random());
  var b = parseInt(255 * Math.random());
  var a = Math.random();

  context.fillStyle = "rgba(" + r + "," + g + "," + b + ", " + a;
  context.globalCompositeOperation = "lighten";

  context.moveTo(x, y);
  context.arc(x, y, 7, 0, 2 * Math.PI);

  context.fill();
}

除此之外,关闭一个或两个颜色通道会产生不同的强度效果。

我希望这有帮助!