'Rainbow Scratch Page'使用Javascript,html canvas API

时间:2016-03-01 18:23:19

标签: javascript canvas

所以我正在尝试重新创建rainbow scratch paper effect。 它分为两层:一张彩虹纸,顶部有黑色涂层。 我认为最简单的方法是创建两个画布 - 一个黑色,分层在一条彩虹之上。有更简单的方法吗?我有几个问题:

  • 我的黑色帆布can没有出现!
  • 对于我的彩虹画布can2,我找到了一个渐变制作者here,但我不确定如何让它填满整个页面。

以下是代码:

    <style>
      body{ margin: 0; } canvas {position: absolute;}
    </style>

<body>

  <canvas id ="can"></canvas>
  <canvas id ="can2"></canvas>

  <script>

    var can = document.getElementsByTagName('canvas')[0];
        can.width = window.innerWidth;
        can.height = window.innerHeight;
    var ctx = can.getContext('2d');
    var fillBlack = can.getElementById("can");
    fillBlack.style.color = "black";

    var can2 = document.getElementsByTagName('canvas')[1];
        can2.width = window.innerWidth;
        can2.height = window.innerHeight;
    var ctx2 = can2.getContext('2d');

        colorScratch(.1, .2, .3, 0, 0, 0, 128, 127, 50);

    var canBox = can.getBoundingClientRect();

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

    function colorScratch(freq1, freq2, freq3, phase1, phase2, phase3, center, width, len) {
      for (var x = 0; x < len; x++){
        for (var y = 0; y < width; y++){
         var red = Math.sin(freq1 * x + phase1) * y + center);
         var grn = Math.sin(freq2 * x + phase2) * y + center);
         var blu = Math.sin(freq3 * x + phase3) * y + center);
         ctx2.fill( '<div color="' + RGB2Color(red,grn,blu) + '">&#9608;</div>');
        }
      }
    }

    var stamp_shape = function(color, pos, size) {
      ctx.beginPath();
      ctx.arc(pos[0], pos[1], size, 0, 2*Math.PI);
      ctx.fillStyle = color;
    };

    var stamp = function(x, y, size) {
      var center = size / 2;
      ctx.save();
      ctx.globalAlpha = 0.6;
      var grd = ctx.createRadialGradient(x, y, size, x, y, 0);
      grd.addColorStop(1, 'rgba(255, 200, 200, 0.2)');
      grd.addColorStop(0, 'rgba(255, 255, 255, 0)');
      stamp_shape(grd, [x-center, y-center], size);
      ctx.restore();
    };

    function getCoords(event) {
      return {
        x: event.pageX - canBox.left,
        y: event.pageY - canBox.top
      };
    }

    var drawing = false;

    can2.onmousedown = function() {
      drawing = true;
    }

    can2.onmouseup = function() {
      drawing = false;
    }

    can2.onmousemove = function(e) {
      var mousePos = getCoords(e);
      if (!drawing) {
        drawCursor(mousePos.x, mousePos.y, 50);
        console.log(mousePos);
        return;
      }
      clearCursor();
      stamp(mousePos.x, mousePos.y, 50);
    }

    function drawCursor(x, y, size) {
      ctx2.clearRect(0, 0, ctx2.canvas.width, ctx2.canvas.height);
      ctx2.strokeStyle = '#F66';
      ctx2.strokeRect(x - size / 2, y - size / 2, size, size);
    }

    function clearCursor() {
      ctx2.clearRect(0, 0, ctx2.canvas.width, ctx2.canvas.height);
    }

  </script>
</body>

非常感谢能够看一眼的人! XX

2 个答案:

答案 0 :(得分:0)

我试图在JSFiddle上运行它,但RGB2Color()未定义。

ctx2.fill( '<div color="' + RGB2Color(red,grn,blu) + '">&#9608;</div>');

我有点得到你,你想在这里做,但你不能用div填充画布。你必须找到其他方法。

无论如何,就我所看到的方式而言,如果它是固定的图像,彩虹并不一定需要是画布。它可以是div或图像。如果彩虹随着时间的推移而变化,它可能需要成为画布。

然后,您可以将黑色画布层叠在其上,以获得所需的效果。

答案 1 :(得分:0)

您想要将纯色不透明画布直接放在渐变图像(或画布)上是个好主意。

然后,当用户拖动时,您可以使用context.globalCompositeOperation='destination-out'“擦除”纯色并显示下面的渐变

以下是示例代码和演示:

var canvas=document.getElementById("canvasTop");
var ctx=canvas.getContext("2d");
var canvas2=document.getElementById("canvasBottom");
var ctx2=canvas2.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
function reOffset(){
  var BB=canvas.getBoundingClientRect();
  offsetX=BB.left;
  offsetY=BB.top;        
}
var offsetX,offsetY;
reOffset();
window.onscroll=function(e){ reOffset(); }
window.onresize=function(e){ reOffset(); }

var isDown=false;
var startX,startY;

var img=new Image();
img.onload=start;
img.src="https://dl.dropboxusercontent.com/u/139992952/multple/rainbowGradient.jpg";
function start(){
  cw=canvas.width=canvas2.width=img.width;
  ch=canvas.height=canvas2.height=img.height;
  ctx2.drawImage(img,0,0);
  ctx.lineWidth=10;
  ctx.lineCap = "round";
  ctx.lineJoin = "round";
  ctx.fillStyle="skyblue";
  ctx.fillRect(0,0,canvas.width,canvas.height);
  ctx.globalCompositeOperation="destination-out";

  $("#canvasTop").mousedown(function(e){handleMouseDown(e);});
  $("#canvasTop").mousemove(function(e){handleMouseMove(e);});
  $("#canvasTop").mouseup(function(e){handleMouseUpOut(e);});
  $("#canvasTop").mouseout(function(e){handleMouseUpOut(e);});
}

function handleMouseDown(e){
  // tell the browser we're handling this event
  e.preventDefault();
  e.stopPropagation();

  startX=parseInt(e.clientX-offsetX);
  startY=parseInt(e.clientY-offsetY);

  // Put your mousedown stuff here
  isDown=true;
}

function handleMouseUpOut(e){
  // tell the browser we're handling this event
  e.preventDefault();
  e.stopPropagation();
  // Put your mouseup stuff here
  isDown=false;
}

function handleMouseMove(e){
  if(!isDown){return;}
  // tell the browser we're handling this event
  e.preventDefault();
  e.stopPropagation();

  mouseX=parseInt(e.clientX-offsetX);
  mouseY=parseInt(e.clientY-offsetY);

  // Put your mousemove stuff here
  ctx.beginPath();
  ctx.moveTo(startX,startY);
  ctx.lineTo(mouseX,mouseY);
  ctx.stroke();
  startX=mouseX;
  startY=mouseY;
}
body{ background-color: ivory; }
#wrapper{
  position:relative;
}
#canvasTop,#canvasBottom{
  position:absolute; top:0px; left:0px;
  border:1px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h4>Drag to reveal gradient.</h4>
<div id="wrapper">
  <canvas id="canvasBottom" width=300 height=300></canvas>
  <canvas id="canvasTop" width=300 height=300></canvas>
</div>