WEBDOOD.COM

Safari-Specific

Javascript extractedWebkitTranslate3DProperty WebKitCSSMatrix

by webdood on Jul.04, 2012, under CSS3, Safari-Specific, Software Development, WebKitCSSMatrix

For me, there are many times where I need to get at the x, y or z value of a -webkit-transform: translate3d({x}, {y}, {z}) property.

I had originally written the below method using .style.webkitTransform and then doing some fancy manipulations to extract out the x, y or z values from the style. However, you will find that elements will not have webkitTransform applied as a “style” to them when it is being set from a css class.

Therefore, I rewrote the method to use getComputedStyle and using its return value for ‘-webkit-transform’.

The interesting thing about this is that it returns a string representation of a WebKitCSSMatrix. Now I had to figure out how to get at the values of x, y and z from this structure.

With some trial and error, I found the following property correspondence:

.m41 – corresponds to the ‘x’ value of a WebKitCSSMatrix
.m42 – corresponds to the ‘y’ value of a WebKitCSSMatrix
.m43 – corresponds to the ‘z’ value of a WebKitCSSMatrix

Here is the main extractedWebkitTranslate3DProperty method, followed by its helper method getStyle:

extractedWebkitTranslate3DProperty

    ///////////////////////////////////////////////////////////////////////////////////////
    // extractedWebkitTranslate3DProperty([object|string] oHTMLElement, string property) //
    // ================================================================================= //
    // Extracts x,y,or z value from a webkitTranslate3D style. Returns a string value.    //
    ///////////////////////////////////////////////////////////////////////////////////////
    function extractedWebkitTranslate3DProperty( oHTMLElement, property ) {
      var retVal = 0;
      if (typeof(oHTMLElement)=="string")  { oHTMLElement = document.getElementById(oHTMLElement); }
      if (property !== undefined) {
        var webkitTransform = getStyle(oHTMLElement,'-webkit-transform');
        if (webkitTransform && webkitTransform!=='none' && webkitTransform.indexOf('matrix') > -1) {
          switch (property.toLowerCase()) {
            case "x" :
              retVal = new WebKitCSSMatrix(webkitTransform).m41;
              break;
            case "y" :
              retVal = new WebKitCSSMatrix(webkitTransform).m42;
              break;
            case "z" :
              retVal = new WebKitCSSMatrix(webkitTransform).m43;
              break;
          }
        }
      }
      return parseFloat(retVal);
    }

getStyle

    ////////////////////////////////////////////////////////////////////////////////
    // getStyle([object|string] oHTMLElement, string cssProperty)                 //
    // ==========================================================                 //
    // Returns value of a cssProperty                                             //
    ////////////////////////////////////////////////////////////////////////////////
    function getStyle(oHTMLElement, cssProperty) {
      if (typeof(oHTMLElement)=="string")  { oHTMLElement = document.getElementById(oHTMLElement); }
      var retVal = "";
      if(document.defaultView && document.defaultView.getComputedStyle){
        retVal = document.defaultView.getComputedStyle(oHTMLElement, null).getPropertyValue(cssProperty);
      } else {
        if (oHTMLElement.currentStyle){
          cssProperty = cssProperty.replace(/\-(\w)/g, function (strMatch, p1){
            return p1.toUpperCase();
          });
          retVal = oHTMLElement.currentStyle[cssProperty];
        }
      }
      return retVal;
    }
Leave a Comment :, , , , more...

HTML5 Green Screen Technique using <VIDEO> and <CANVAS>

by webdood on Sep.09, 2011, under Canvas, HTML5, Safari-Specific, Software Development

This technique allows you to composite a green-screen video over a web page.
The basic setup consists of a hidden <VIDEO> tag, another hidden <CANVAS> tag, where each frame of video is captured for further processing and a visible <CANVAS> tag where each processed frame is displayed.
When a frame of video is captured and placed into our “canvasProcessor”, each pixel is analyzed in turn. A pixel is represented by a CanvasPixelArray consisting of four values: (R)ed, (G)reen, (B)lue and (A)lpha.
When we find a pixel that fits in the range of “green”, we change that one to have a 0 (A)lpha value (and thus it becomes invisible).

Here is link to a working example.

<!DOCTYPE HTML><
<html>
<head>
  <title>Green Screen Test</title>
  <script type="text/javascript">
    greenScreenEngine = {
      _animator : null,
      _canvasProcessorContext : null,
      _canvasTargetContext : null,
      _height : 0,
      _width : 0,
      _video : null,
      handlerFor : {
        pause : function() {
          clearTimeout( this._animator );
        },
        play : function() {
          greenScreenEngine.parseAndProcessFrame();
        }
      },
      parseAndProcessFrame : function() {
        if (this._video.paused || this._video.ended) {
          return;
        }
        this._canvasProcessorContext.drawImage(this._video,0,0,this._width,this._height)
        var videoFrame     = this._canvasProcessorContext.getImageData(0,0,this._width,this._height),
            numberOfPixels = videoFrame.data.length / 4;
        for (var i=0;i 100 && b < 100) {      // Here we look for what we perceive to be a green pixel
            videoFrame.data[i * 4 + 3] = 0;        // If we find one, make its alpha channel transparent
          }
        }
        this._canvasTargetContext.putImageData(videoFrame,0,0);
        this._animator = setTimeout( function() { greenScreenEngine.parseAndProcessFrame() },0);
      },
      setCanvasProcessor : function( canvasProcessorID, scale ) {
        scale = (scale!==undefined) ? scale : 1;
        this._height = this._video.videoHeight * scale;
        this._width  = this._video.videoWidth * scale;
        var oCanvas = document.getElementById(canvasProcessorID);
        oCanvas.height = this._height;
        oCanvas.width  = this._width;
        this._canvasProcessorContext = oCanvas.getContext("2d");
        this._canvasProcessorContext.drawImage(this._video,0,0,this._width,this._height)
      },
      setCanvasTarget : function( canvasTargetID ) {
        var oCanvas = document.getElementById(canvasTargetID);
        oCanvas.height = this._height;
        oCanvas.width  = this._width;
        this._canvasTargetContext =  oCanvas.getContext("2d");
      },
      setSourceVideo : function( videoID ) {
        this._video = document.getElementById( videoID );
        this._video.addEventListener("play", greenScreenEngine.handlerFor.play)
        this._video.addEventListener("pause", greenScreenEngine.handlerFor.pause)
      }
    }
    function setup() {
      greenScreenEngine.setSourceVideo("video-green-screen");
      greenScreenEngine.setCanvasProcessor("canvas-processor",.5);
      greenScreenEngine.setCanvasTarget("canvas-target");
      greenScreenEngine._video.play();
    }
  </script>
</head>
<body>
  <div>
    <video id="video-green-screen" src="talkingHead.mp4" controls="true" tabindex="0" oncanplay="setup()" style="display:none;"></video>
  </div>
  <div>
    <canvas id="canvas-processor" style="display:none;"></canvas>
    <canvas id="canvas-target" style="-webkit-transform:rotate(90deg);position:absolute;bottom:79px;"></canvas>
  </div>
</body>
</html>>

Note - For the video I've used here, I had to play with the values a bit to find just the right range of values that mean "green." Also, the source video was rotated -90deg, so I had to apply a webkit-transform to it. To see how everything works, just comment out the display:none CSS.

Shannon Norrell

1 Comment more...

Detect Safari 3

by webdood on Aug.26, 2010, under Javascript, Safari-Specific, Software Development

Today I needed a quick way to detect Safari3 for some specific markup tricks, so I wrote this function.
Thought it might be helpful to someone else.

<script type="text/javascript">
  var isSafari3 = (function() {
    var retval = false;
    if (navigator.vendor && navigator.vendor.indexOf('Apple') > -1) {
      var index=navigator.appVersion.indexOf('Version');
      if (index > -1) {
        retval = (parseInt(navigator.appVersion.substring(index+8))==3);
      }
    }
  return retval;
  })();
alert(isSafari3);
</script>

Shannon Norrell

Leave a Comment :, , more...

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!

Blogroll

A few highly recommended websites...

  • A List Apart
  • Dive into HTML5
  • Javascript: The Good Parts
  • QuirksMode.org