Изменить цвет "экранных" волн - PullRequest
0 голосов
/ 21 января 2019

Я застрял на том, чтобы волны выглядели так, как я хочу. Я пытаюсь понять, как получить основание волны, чтобы оно было того цвета, который мне нужен. Я могу сделать желаемый цвет, но он блокирует фон. Я ничего не вижу за этим, потому что я использовал как отражение. Может быть, кто-то может понять это, потому что у меня возникают трудности с тем, чтобы заставить его работать ... Я планирую сделать, чтобы волна падала и поднималась. Вот ссылка на код ручки: ЗДЕСЬ

Вот где у меня вертикальное отражение:

var x = $.cx - $.length / 2 + $.length / $.count * i,
    y = height + $.simplex.noise2D($.xoff, $.yoff) * amp + sway;
    $.ctx[i === 0 ? 'moveTo' : 'lineTo'](x, y);
  }

  $.ctx.lineTo($.w, $.h); // -$.h - Vertically reflection
  $.ctx.lineTo(0, $.h); // -$.h - Vertically reflection
  $.ctx.closePath();
  $.ctx.fillStyle = color;

  if (comp) {
    $.ctx.globalCompositeOperation = comp;
  }

  $.ctx.fill();

Мой желаемый вид волн ниже:

The way I want it to look

Вот то, что я получил с успешным прозрачным верхом, но не правильной окраски Not my desired look

1 Ответ

0 голосов
/ 21 января 2019

Ваша проблема в том, что при смешивании трех цветов screen получается белый цвет, поэтому вся нижняя часть холста становится белой.

Здесь я сильно упростил ситуацию, всего с 3 прямоугольниками. Твой низ холста - мой центральный белый квадрат:

const c2 = canvas.cloneNode();

const ctx = canvas.getContext("2d");

ctx.globalCompositeOperation = 'screen';
ctx.fillStyle = '#fb0000';
ctx.fillRect(0,0,50,50);
ctx.fillStyle = "#00ff8e";
ctx.fillRect(12,12,50,50);
ctx.fillStyle = "#6F33FF";
ctx.fillRect(25,25,50,50);
body {
  background: #CCC;
}
<canvas id="canvas"></canvas>

Итак, нам нужен способ сделать этот центральный квадрат прозрачным, чтобы мы могли нарисовать фон позади.

Для этого нам нужно будет нарисовать наши фигуры как минимум два раза:

  • один раз в обычном режиме композитинга, чтобы мы получили полное перекрытие.
  • еще раз как source-in режим компоновки, так что мы получаем только там, где все наши фигуры перекрываются.

const ctx = canvas.getContext("2d");

function drawShapes(mode) {
  ctx.globalCompositeOperation = mode;
  ctx.fillStyle = '#fb0000';
  ctx.fillRect(0,0,50,50);
  ctx.fillStyle = "#00ff8e";
  ctx.fillRect(12,12,50,50);
  ctx.fillStyle = "#6F33FF";
  ctx.fillRect(25,25,50,50);
}

drawShapes('screen');
drawShapes('source-in');
body {
  background: #CCC;
}
<canvas id="canvas"></canvas>

Теперь у нас есть область перекрытия, и мы сможем использовать ее в качестве режущей фигуры в третьей операции. Но чтобы сделать это, нам понадобится второй закадровый холст, чтобы выполнить объединение двух состояний:

const c2 = canvas.cloneNode();

const ctx = canvas.getContext("2d");
const ctx2 = c2.getContext("2d");

function drawShapes(ctx, comp) {
  ctx.globalCompositeOperation = comp;
  ctx.fillStyle = '#fb0000';
  ctx.fillRect(0, 0, 50, 50);
  ctx.fillStyle = "#00ff8e";
  ctx.fillRect(12, 12, 50, 50);
  ctx.fillStyle = "#6F33FF";
  ctx.fillRect(25, 25, 50, 50);
}
// first draw our screen, with unwanted white square
drawShapes(ctx, 'screen');
// draw it on the offscreen canvas
ctx2.drawImage(ctx.canvas, 0, 0)
// draw the shapes once again on the offscreen canvas to get the cutting shape
drawShapes(ctx2, 'source-in');
// cut the visible canvas
ctx.globalCompositeOperation = 'destination-out'
ctx.drawImage(ctx2.canvas, 0, 0);
body {
  background: #CCC
}
<canvas id="canvas"></canvas>

И вуаля, наш белый квадрат теперь прозрачен, мы можем рисовать все, что хотим, за нашей сценой, используя destination-over составную операцию.

...