为每个为 1 的位绘制矩形

Draw rectangle for each bit that is 1

我有一个 canvas,最多可以绘制 16 个矩形。

我从服务器收到这个二进制数:100101101(或十进制的 301)。

假装我想将我的矩形与这个二进制文件相关联(每位一个矩形),我需要为 0 的每个位隐藏每个矩形(或者为 0 的每个位绘制一个矩形=16=],随你喜欢)。

所以(如果我们查看 100101101)在我的 canvas 中,我会绘制第一个矩形,然后绘制一个 space,然后再绘制两个矩形,然后绘制另一个 space,等等

我为这个问题绞尽脑汁,因为我对按位运算和位掩码真的很陌生。我认为我需要为此使用按位运算和位掩码,但也许不需要...

这是我的基本代码(还没有操作我的位的功能):

    //Referencing canvas
    var canvas = document.getElementById("my-canvas");
  var ctx = canvas.getContext("2d");


    //Make Canvas fullscreen and responsive
     function resize() {
   canvas.width = window.innerWidth;
   canvas.height = window.innerHeight;
  }
  window.addEventListener('resize', resize, false); resize();
  
  

  //Default Y pos to center;
  var yPos = canvas.height - 70;
  //Default X position
  var xPos = canvas.width / 2.2;

  var maxRectangles = 16;

 function drawAllRectangles() {

   //Position, size.
   var rectWidth = 70;
   var rectHeigth = 25;
   var dy = rectHeigth + 15;
   ctx.fillStyle = "yellow";

   
   var newPos = yPos;
         var i;
         for (i = 0; i < maxRectangles; i++) {
             ctx.fillRect(xPos,newPos,rectWidth,rectHeigth);
             newPos -= dy;
         }
    }

  drawAllRectangles ();
canvas {background-color: #131217}

body { margin: 0; overflow: hidden; }
<!DOCTYPE html>
<html lang="en">
  
  <head>
    <meta charset="utf-8">
    <title>Draw Rect from bit</title>
    
  </head>


  <body>
  
  <canvas id="my-canvas"></canvas>
  
   </body>


</html>

你应该使用 2 个按位运算符,它们是“<<”-"LEFT SHIFT"、“&”-"AND",你可以看到解释你应该做什么

    var binaryVal;
var shiftVal;

var calculatedShiftVal =0;

binaryVal = 4; // 0000 0100
//I will try to explain that shiftVal it is basicall is 1(one) when you use "<<" operator with number that means it shifted from right to left
//Below code what happened after shift operator
shiftVal = 1;//0000 0001
calculatedShiftVal = shiftVal<<0;//0000 0000 0000 0001
console.log(calculatedShiftVal);
calculatedShiftVal = shiftVal<<1;//0000 0000 0000 0010
console.log(calculatedShiftVal);
calculatedShiftVal = shiftVal<<2;//0000 0000 0000 0100
console.log(calculatedShiftVal);
calculatedShiftVal = shiftVal<<3;//0000 0000 0000 1000
console.log(calculatedShiftVal);
calculatedShiftVal = shiftVal<<4;//0000 0000 0001 0000
console.log(calculatedShiftVal);
calculatedShiftVal = shiftVal<<5;//0000 0000 0010 0000
console.log(calculatedShiftVal);
calculatedShiftVal = shiftVal<<6;//0000 0000 0100 0000
console.log(calculatedShiftVal);
calculatedShiftVal = shiftVal<<7;//0000 0000 1000 0000
console.log(calculatedShiftVal);
calculatedShiftVal = shiftVal<<8;//0000 0001 0000 0000
console.log(calculatedShiftVal);
calculatedShiftVal = shiftVal<<9;//0000 0010 0000 0000
console.log(calculatedShiftVal);
calculatedShiftVal = shiftVal<<10;//0000 0100 0000 0000
console.log(calculatedShiftVal);
calculatedShiftVal = shiftVal<<11;//0000 1000 0000 0000
console.log(calculatedShiftVal);
calculatedShiftVal = shiftVal<<12;//0001 0000 0000 0000
console.log(calculatedShiftVal);
calculatedShiftVal = shiftVal<<13;//0010 0000 0000 0000
console.log(calculatedShiftVal);
calculatedShiftVal = shiftVal<<14;//0100 0000 0000 0000
console.log(calculatedShiftVal);
calculatedShiftVal = shiftVal<<15;//1000 0000 0000 0000
console.log(calculatedShiftVal);

//Then we use "&" "AND" operator with shiftVal and your number from server it is basically if your number and shiftVal gives to us "0" then you wont be draw your rectangle if it is grater than 0 then you can draw rectangle
//for example you want to check 4th rectangle value and your number is 17
//0000 0000 0001 0000  --> shiftVal<<4
//0000 0000 0001 0001  --> represent 17
//0000 0000 0001 0000  -->represent after &
var yourVal = 17;
console.log((shiftVal<<4)&yourVal); // result is 16 then you can draw it
//other example you want to check 3th rectangle value and your number is 17
//0000 0000 0000 1000  --> shiftVal<<3
//0000 0000 0001 0001  --> represent 17
//0000 0000 0000 0000  -->represent after & everthing is 0 now and your value is 0
console.log((shiftVal<<3)&yourVal); // result is 0 then you shouldn't draw it

享受

正如 Ferhat BAS 指出的那样,使用 & 按位与运算符和 << 左移运算符。

Bitwise AND - Returns a one in each bit position for which the corresponding bits of both operands are ones.

Left shift - Shifts a in binary representation b (< 32) bits to the left, shifting in zeroes from the right.

Here's 关于如何使用按位运算符操作数字位的非常好的答案。

现在,您需要在 drawAllRectangles 的 for 循环中测试一个条件,否则将绘制所有矩形 "unconditionally"。你可以使用这个:

if (mask & 1) ...

function drawAllRectangles(data) {

        //Position, size.
        var rectWidth = 70;
        var rectHeigth = 25;
        var dy = rectHeigth + 15;
        ctx.fillStyle = "yellow";


        var newPos = yPos;
        var i;
        for (i = 0; i < maxRectangles; i++) {
            var mask = 1 << i;
            // if mask & 1 == 1, then the if statement evaluates to true, as 1 is "truthy" in javascript
            if (mask & 1) ctx.fillRect(xPos,newPos,rectWidth,rectHeigth);
        }
}