Computing a realistic shadow using JavaScript

I am creating a bookbook library with books being dragged between shelves.

Applying box-shadowto books made them a little more realistic, but I wondered if I could continue and dynamically calculate the values box-shadowfor each book by its position relative to one selected "light source point", for example, in a game I’ll make an engine.

Thus, if we select the upper center point for the light source, there will be a lower left shadow at the bottom left and a lower right right shadow. Books below will have shadows of greater height, etc. We may need to indicate the depth (z-coordinate) for the light source, as well as its position.

While it box-shadowdoes not allow complex realistic shadows, I suspect that it would be more than enough to adjust the size and angle of the shadow with respect to their position for rectangular objects such as books to make them much more realistic.

Has anyone already studied the implementation of this in JavaScript? Do you know of any open source libraries that calculate values box-shadowfor a specific point in a light source? If not, is the idea inherently erroneous in some way that I did not think about, or is it that no one has yet tried to do this?

+3
source share
2 answers

The guy named Jeff Pamer experimented about it.

jQuery jQuery UI Draggable (. )

html:

<div id="light_source">Light Source<br />(drag me)</div>
<div id="div1" class="needs_shadow">(drag me)</div>
<div id="div2" class="needs_shadow">(drag me)</div>

JavaScript

$(document).ready(function() {
  $("div").draggable({
    drag: function() { make_shade() }
  });
  make_shade();  
});

function make_shade() {
  var light = $("div#light_source");
  var light_pos = light.position();
  var light_x = light_pos.left + (light.width() / 2);
  var light_y = light_pos.top + (light.height() / 2);

  $(".needs_shadow").each(function() {
    var div1 = $(this);
    var div1_pos = div1.position();

    var div_x = div1_pos.left + (div1.width() / 2);
    var div_y = div1_pos.top + (div1.height() / 2);

    var left_diff = light_x - div_x;
    var top_diff = light_y - div_y;

    var left = (left_diff / 10) * -1;
    var top = (top_diff / 10) * -1;

    var distance = Math.sqrt(Math.pow(left_diff, 2) + Math.pow(top_diff, 2));
    distance = distance / 10;

    shadow_style = left + "px " + top + "px " + distance + "px #3f3f3f";
    div1.css("-moz-box-shadow", shadow_style);
    div1.css("-webkit-box-shadow", shadow_style);
    div1.css("box-shadow", shadow_style);
  });
}
+4

, , , upvotes, .: D.

var source = [0, 0], faktor = [10, 20];

, ([0] , [1] ).

function addShadows() {
    var i, j, position, sizeE, distance; for(i=0,j=arguments.length;i<j;++i) {
        position = offset(arguments[i]); // Get position from element

        sizeE = size(arguments[i]); // Get width and height from element

        distance = parseInt(Math.sqrt(Math.pow(position[0] + sizeE[0] / 2 - source[0], 2) + Math.pow(position[1] + sizeE[1] / 2 - source[1], 2))) / faktor[1]; // calculate a distance for bluring (middle of element to source)

        arguments[i].style.cssText += 'box-shadow: ' + ((position[0] + sizeE[0] - source[0]) / faktor[0]) + 'px ' + ((position[1] + sizeE[1] - source[1]) / faktor[0]) + 'px ' + distance + 'px #555555'; // add the shadow
    }
}

addShadows .

function getStyle(element, attribut) {
    var style;

    if(window.getComputedStyle) {
        style = window.getComputedStyle(element, null);
    } else {
        style = element.currentStyle;
    }

    return style[attribut];
}
function offset(element) {
    var pos = [parseInt(getStyle(element, 'border-top')), parseInt(getStyle(element, 'border-top'))];

    while(element !== null) {
        pos[0] += element.offsetLeft;
        pos[1] += element.offsetTop;

        element = element.offsetParent;
    }

    return pos;
}
function size(element) {
    return [element.offsetWidth, element.offsetHeight];
}
function id(idE) {
    return document.getElementById(idE);
}

.

JSfiddle: http://jsfiddle.net/R5UbL/1/

+1

All Articles