2

Here is the code:

var $win = $(window),
    w = 0,h = 0,
    rgb = [],
    getWidth = function() {
        w = $win.width();
        h = $win.height();
    };

$win.resize(getWidth).mousemove(function(e) {

    rgb = [
        Math.round(e.pageX/w * 255),
        Math.round(e.pageY/h * 255),
        150
    ];

    $(document.body).css('background','rgb('+rgb.join(',')+')');
    //top center: rgb(85, 209, 79)
    //right middle: rgb(104, 129, 197)
    //bottom center: rgb(40,129,255)
    //left middle: rgb(255, 184, 0)
    //very center: rgb(15, 175, 168)
}).resize();

I would like to change the background colour depends of the mouse position, but I can't figure out how can I specify the colour of the 5 points (top, right, bottom, left, center).

###################
#        O        #
#                 #
#                 #
# O      O      O #
#                 #
#                 #
#        O        #
###################

So these five points, where I have the colours, and when I move the mouse between these points, I want to change it from one to another. http://jsfiddle.net/710r4gaj/

levipadre
  • 569
  • 7
  • 31

1 Answers1

5

You have to use an interpolation method. Bilinear interpolation is very popular.

What I would do would be to specify colors at the points of interest(top, left, right, bottom and center). Then define colors in the corners by being the average of the closest colors defined (which is not really good, the best would be to specify them as well).

Once done, given a point in the screen, I would compute in which subsquare the point is, and compute a bilinear interpolation between vertices of this square (as explained in the picture)

enter image description here

Here is a fiddle:

var $win = $(window),
  w = 0,
  h = 0,
  rgb = [],
  getWidth = function() {
    w = $win.width();
    h = $win.height();
  };


var average = function(a, b) {
  return [0.5 * (a[0] + b[0]), 0.5 * (a[1] + b[1]), 0.5 * (a[1] + b[1])];
}

var center = [255, 255, 255]; // white
var topMiddle = [0, 0, 0]; // black
var leftMiddle = [255, 0, 0]; // red
var rightMiddle = [0, 255, 0]; // green;
var bottomMiddle = [0, 0, 255]; // blue;


var topLeft = average(leftMiddle, topMiddle);
var topRight = average(topMiddle, rightMiddle);
var bottomLeft = average(leftMiddle, bottomMiddle);
var bottomRight = average(bottomMiddle, rightMiddle);


var interpolate2D = function(x00, x01, x10, x11, x, y) {
  return x00 * (1 - x) * (1 - y) + x10 * x * (1 - y) + x01 * (1 - x) * y + x11 * x * y;
}

var interpolateArray = function(x00, x01, x10, x11, x, y) {
  var result = [0, 0, 0];
  for (var i = 0; i < 3; ++i) {
    result[i] = Math.floor(interpolate2D(x00[i], x01[i], x10[i], x11[i], x, y));
  }
  return result;
}


$win.resize(getWidth).mousemove(function(e) {
  var positionX = e.pageX / w;
  var positionY = e.pageY / h;
  var x00, x01, x11, x10;

  if (positionX > 0.5 && positionY > 0.5) {
    x00 = center;
    x01 = bottomMiddle;
    x10 = rightMiddle;
    x11 = bottomRight;
    positionX = 2.0 * (positionX - 0.5); // scale position back to [0, 1]
    positionY = 2.0 * (positionY - 0.5);
  } else if (positionX > 0.5 && positionY <= 0.5) {
    x00 = topMiddle;
    x01 = center;
    x10 = topRight;
    x11 = rightMiddle;
    positionX = 2.0 * (positionX - 0.5);
    positionY = 2.0 * (positionY);
  } else if (positionX <= 0.5 && positionY <= 0.5) {
    x00 = topLeft;
    x01 = leftMiddle;
    x10 = topMiddle;
    x11 = center;
    positionX = 2.0 * (positionX);
    positionY = 2.0 * (positionY);
  } else if (positionX <= 0.5 && positionY > 0.5) {
    x00 = leftMiddle;
    x01 = bottomLeft;
    x10 = center;
    x11 = bottomMiddle;
    positionX = 2.0 * (positionX);
    positionY = 2.0 * (positionY - 0.5);
  } else {
    // can't happen
  }



  rgb = interpolateArray(x00, x01, x10, x11, positionX, positionY);


  $(document.body).css('background', 'rgb(' + rgb.join(',') + ')');
  //top: rgb(85, 209, 79)
  //right: rgb(104, 129, 197)
  //bottom: rgb(40,129,255)
  //left: rgb(255, 184, 0)
}).resize();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Regis Portalez
  • 4,675
  • 1
  • 29
  • 41
  • OMG! Did you just wrote it! Very-very appreciate it! – levipadre May 10 '16 at 14:55
  • You're very welcome. It was funny, and now it will be possible to mark plenty of questions like your as duplicate of this one :) – Regis Portalez May 10 '16 at 14:56
  • Hi @Regis Portalez. I was wondering maybe you can help me a bit with another similar problem. I have 4 elements on this page (top, right, bottom, left) center. All element have 0 opacity. I would like to make it visible/hidden depends of the mouse position. For example, when the mouse on the (miidleTop,topRight) section, the top element is starting visible, when the mouse on the (center,middlRight) section, the right arrow is starting visible and the top one hidden. The opacity value depends of the mouse position. Do you think it's possible? – levipadre May 12 '16 at 21:17
  • It looks I can manage with positionX and positionY value, like this: `$('.nav.top').css('opacity', positionX);` – levipadre May 12 '16 at 23:31