page.title=Device Art Generator
@jd:body

<p>The device art generator allows you to quickly wrap your app screenshots in real device artwork.
This provides better visual context for your app screenshots on your web site or in other
promotional materials.</p>

<p class="note"><strong>Note</strong>: Do <em>not</em> use graphics created here in your 1024x500
feature image or screenshots for your Google Play app listing.</p>

<hr>

<div class="supported-browser">

<div class="layout-content-row">
  <div class="layout-content-col span-3">
    <h4>Step 1</h4>
    <p>Drag a screenshot from your desktop onto a device to the right.</p>
  </div>
  <div class="layout-content-col span-10">
    <ul class="device-list primary"></ul>
    <a href="#" id="archive-expando">Older devices</a>
    <ul class="device-list archive"></ul>
  </div>
</div>

<hr>

<div class="layout-content-row">
  <div class="layout-content-col span-3">
    <h4>Step 2</h4>
    <p>Customize the generated image and drag it to your desktop to save.</p>
    <p id="frame-customizations">
      <input type="checkbox" id="output-shadow" checked="checked" class="form-field-checkbutton">
      <label for="output-shadow">Shadow</label><br>
      <input type="checkbox" id="output-glare" checked="checked" class="form-field-checkbutton">
      <label for="output-glare">Screen Glare</label><br><br>
      <a class="button" id="rotate-button">Rotate</a>
    </p>
  </div>
  <div class="layout-content-col span-10">
    <!-- position:relative fixes an issue where dragging an image out of a inline-block container
         produced no drag feedback image in Chrome 28. -->
    <div id="output" style="position:relative">No input image.</div>
  </div>
</div>

</div>

<div class="unsupported-browser" style="display: none">
  <p class="warning"><strong>Error:</strong> This page requires 
    <span id="unsupported-browser-reason">certain features</span>, which your web browser
    doesn't support. To continue, navigate to this page on a supported web browser, such as
    <strong>Google Chrome</strong>.</p>
  <a href="https://www.google.com/chrome/" class="button">Get Google Chrome</a>
  <br><br>
</div>

<style>
  h4 {
    text-transform: uppercase;
  }

  .device-list {
    padding: 0;
    margin: 0;
  }

  .device-list li {
    display: inline-block;
    vertical-align: bottom;
    margin: 0;
    margin-right: 20px;
    text-align: center;
  }

  .device-list li .thumb-container {
    display: inline-block;
  }

  .device-list li .thumb-container img {
    margin-bottom: 8px;
    opacity: 0.6;

    -webkit-transition: -webkit-transform 0.2s, opacity 0.2s;
       -moz-transition:    -moz-transform 0.2s, opacity 0.2s;
            transition:         transform 0.2s, opacity 0.2s;
  }

  .device-list li.drag-hover .thumb-container img {
    opacity: 1;

    -webkit-transform: scale(1.1);
       -moz-transform: scale(1.1);
            transform: scale(1.1);
  }

  .device-list li .device-details {
    font-size: 13px;
    line-height: 16px;
    color: #888;
  }

  .device-list li .device-url {
    font-weight: bold;
  }

  #archive-expando {
    display: block;
    font-size: 13px;
    font-weight: bold;
    color: #333;
    text-transform: uppercase;
    margin-top: 16px;
    padding-top: 16px;
    padding-left: 28px;
    border-top: 1px solid transparent;
    background: transparent url({@docRoot}assets/images/styles/disclosure_down.png)
                no-repeat scroll 0 8px;
  }

  #archive-expando.expanded {
    background-image: url({@docRoot}assets/images/styles/disclosure_up.png);
    border-top: 1px solid #ccc;
  }

  #output {
    color: #f44;
    font-style: italic;
  }

  #output img {
    max-height: 500px;
  }
</style>
<script>
  // Global variables
  var g_currentImage;
  var g_currentDevice;
  var g_currentObjectURL;
  var g_currentBlob;

  // Global constants
  var MSG_INVALID_INPUT_IMAGE = 'Invalid screenshot provided. Screenshots must be PNG files '
      + 'matching the target device\'s screen aspect ratio in either portrait or landscape.';
  var MSG_NO_INPUT_IMAGE = 'Drag a screenshot (in PNG format) from your desktop onto a '
      + 'target device above.'
  var MSG_GENERATING_IMAGE = 'Generating device art&hellip;';

  var MAX_DISPLAY_HEIGHT = 126; // XOOM, to fit into 200px wide

  // Device manifest.
  var DEVICES = [
    {
      id: 'nexus_4',
      title: 'Nexus 4',
      url: 'http://www.google.com/nexus/4/',
      physicalSize: 4.7,
      physicalHeight: 5.23,
      density: 'XHDPI',
      landRes: ['shadow', 'back', 'fore'],
      landOffset: [349,214],
      portRes: ['shadow', 'back', 'fore'],
      portOffset: [213,350],
      portSize: [768,1280]
    },
    {
      id: 'nexus_7',
      title: 'Nexus 7',
      url: 'http://www.google.com/nexus/7/',
      physicalSize: 7,
      physicalHeight: 8,
      actualResolution: [1200,1920],
      density: 'XHDPI',
      landRes: ['shadow', 'back', 'fore'],
      landOffset: [326,245],
      portRes: ['shadow', 'back', 'fore'],
      portOffset: [244,326],
      portSize: [800,1280]
    },
    {
      id: 'nexus_10',
      title: 'Nexus 10',
      url: 'http://www.google.com/nexus/10/',
      physicalSize: 10,
      physicalHeight: 7,
      actualResolution: [1600,2560],
      density: 'XHDPI',
      landRes: ['shadow', 'back', 'fore'],
      landOffset: [227,217],
      portRes: ['shadow', 'back', 'fore'],
      portOffset: [217,223],
      portSize: [800,1280]
    },
    {
      id: 'xoom',
      title: 'Motorola XOOM',
      url: 'http://www.google.com/phone/detail/motorola-xoom',
      physicalSize: 10,
      physicalHeight: 6.61,
      density: 'MDPI',
      landRes: ['shadow', 'back', 'fore'],
      landOffset: [218,191],
      portRes: ['shadow', 'back', 'fore'],
      portOffset: [199,200],
      portSize: [800,1280],
      archived: true
    },
    {
      id: 'nexus_7_2012',
      title: 'Nexus 7 (2012)',
      url: 'http://www.google.com/nexus/7/',
      physicalSize: 7,
      physicalHeight: 7.81,
      density: '213dpi',
      landRes: ['shadow', 'back', 'fore'],
      landOffset: [315,270],
      portRes: ['shadow', 'back', 'fore'],
      portOffset: [264,311],
      portSize: [800,1280],
      archived: true
    },
    {
      id: 'galaxy_nexus',
      title: 'Galaxy Nexus',
      url: 'http://www.android.com/devices/detail/galaxy-nexus',
      physicalSize: 4.65,
      physicalHeight: 5.33,
      density: 'XHDPI',
      landRes: ['shadow', 'back', 'fore'],
      landOffset: [371,199],
      portRes: ['shadow', 'back', 'fore'],
      portOffset: [216,353],
      portSize: [720,1280],
      archived: true
    },
    {
      id: 'nexus_s',
      title: 'Nexus S',
      url: 'http://www.google.com/phone/detail/nexus-s',
      physicalSize: 4.0,
      physicalHeight: 4.88,
      density: 'HDPI',
      landRes: ['shadow', 'back', 'fore'],
      landOffset: [247,135],
      portRes: ['shadow', 'back', 'fore'],
      portOffset: [134,247],
      portSize: [480,800],
      archived: true
    }
  ];

  DEVICES = DEVICES.sort(function(x, y) { return x.physicalSize - y.physicalSize; });

  var MAX_HEIGHT = 0;
  for (var i = 0; i < DEVICES.length; i++) {
    MAX_HEIGHT = Math.max(MAX_HEIGHT, DEVICES[i].physicalHeight);
  }

  // Setup performed once the DOM is ready.
  $(document).ready(function() {
    if (!checkBrowser()) {
      return;
    }

    polyfillCanvasToBlob();
    setupUI();

    // Set up Chrome drag-out
    $.event.props.push("dataTransfer");
    document.body.addEventListener('dragstart', function(e) {
      var target = e.target;
      if (target.classList.contains('dragout')) {
        e.dataTransfer.setData('DownloadURL', target.dataset.downloadurl);
      }
    }, false);
  });

  /**
   * Returns the device from DEVICES with the given id.
   */
  function getDeviceById(id) {
    for (var i = 0; i < DEVICES.length; i++) {
      if (DEVICES[i].id == id)
        return DEVICES[i];
    }
    return;
  }

  /**
   * Checks to make sure the browser supports this page. If not,
   * updates the UI accordingly and returns false.
   */
  function checkBrowser() {
    // Check for browser support
    var browserSupportError = null;

    // Must have <canvas>
    var elem = document.createElement('canvas');
    if (!elem.getContext || !elem.getContext('2d')) {
      browserSupportError = 'HTML5 canvas.';
    }

    // Must have FileReader
    if (!window.FileReader) {
      browserSupportError = 'desktop file access';
    }

    if (browserSupportError) {
      $('.supported-browser').hide();

      $('#unsupported-browser-reason').html(browserSupportError);
      $('.unsupported-browser').show();
      return false;
    }

    return true;
  }

  function setupUI() {
    $('#output').html(MSG_NO_INPUT_IMAGE);

    $('#frame-customizations').hide();
    $('.device-list.archive').hide();

    $('#output-shadow, #output-glare').click(function() {
      createFrame();
    });

    // Build device list.
    $.each(DEVICES, function() {
      var resolution = this.actualResolution || this.portSize;
      var scaleFactorText = '';
      if (resolution[0] != this.portSize[0]) {
        scaleFactorText = '<br>' + (100 * (this.portSize[0] / resolution[0])).toFixed(0) +
            '% size output';
      } else {
        scaleFactorText = '<br>&nbsp;';
      }

      $('<li>')
          .append($('<div>')
              .addClass('thumb-container')
              .append($('<img>')
                  .attr('src', 'device-art-resources/' + this.id + '/thumb.png')
                  .attr('height',
                      Math.floor(MAX_DISPLAY_HEIGHT * this.physicalHeight / MAX_HEIGHT))))
          .append($('<div>')
              .addClass('device-details')
              .html((this.url
                  ? ('<a class="device-url" href="' + this.url + '">' + this.title + '</a>')
                  : this.title) +
                  '<br>' +  this.physicalSize + '" @ ' + this.density +
                  '<br>' + (resolution[0] + 'x' + resolution[1]) + scaleFactorText))
          .data('deviceId', this.id)
          .appendTo(this.archived ? '.device-list.archive' : '.device-list.primary');
    });

    // Set up "older devices" expando.
    $('#archive-expando').click(function() {
      if ($(this).hasClass('expanded')) {
        $(this).removeClass('expanded');
        $('.device-list.archive').hide();
      } else {
        $(this).addClass('expanded');
        $('.device-list.archive').show();
      }
      return false;
    });

    // Set up drag and drop.
    $('.device-list li')
        .live('dragover', function(evt) {
          $(this).addClass('drag-hover');
          evt.dataTransfer.dropEffect = 'link';
          evt.preventDefault();
        })
        .live('dragleave', function(evt) {
          $(this).removeClass('drag-hover');
        })
        .live('drop', function(evt) {
          $('#output').empty().html(MSG_GENERATING_IMAGE);
          $(this).removeClass('drag-hover');
          g_currentDevice = getDeviceById($(this).closest('li').data('deviceId'));
          evt.preventDefault();
          loadImageFromFileList(evt.dataTransfer.files, function(data) {
            if (data == null) {
              $('#output').html(MSG_INVALID_INPUT_IMAGE);
              return;
            }
            loadImageFromUri(data.uri, function(img) {
              g_currentFilename = data.name;
              g_currentImage = img;
              createFrame();
              // Send the event to Analytics
              _gaq.push(['_trackEvent', 'Distribute', 'Create Device Art', g_currentDevice.title]);
            });
          });
        });

    // Set up rotate button.
    $('#rotate-button').click(function() {
      if (!g_currentImage) {
        return;
      }

      var w = g_currentImage.naturalHeight;
      var h = g_currentImage.naturalWidth;
      var canvas = $('<canvas>')
          .attr('width', w)
          .attr('height', h)
          .get(0);

      var ctx = canvas.getContext('2d');
      ctx.rotate(-Math.PI / 2);
      ctx.translate(-h, 0);
      ctx.drawImage(g_currentImage, 0, 0);

      loadImageFromUri(canvas.toDataURL('image/png'), function(img) {
        g_currentImage = img;
        createFrame();
      });
    });
  }

  /**
   * Generates the frame from the current selections (g_currentImage and g_currentDevice).
   */
  function createFrame() {
    var port;

    var aspect1 = g_currentImage.naturalWidth / g_currentImage.naturalHeight;
    var aspect2 = g_currentDevice.portSize[0] / g_currentDevice.portSize[1];

    if (aspect1 == aspect2) {
      port = true;
    } else if (aspect1 == 1 / aspect2) {
      port = false;
    } else {
      alert('The screenshot must have an aspect ratio of ' +
          aspect2.toFixed(3) + ' or ' + (1 / aspect2).toFixed(3) +
          ' (ideally ' + g_currentDevice.portSize[0] + 'x' + g_currentDevice.portSize[1] +
          ' or ' + g_currentDevice.portSize[1] + 'x' + g_currentDevice.portSize[0] + ').');
      $('#output').html(MSG_INVALID_INPUT_IMAGE);
      return;
    }

    // Load image resources
    var res = port ? g_currentDevice.portRes : g_currentDevice.landRes;
    var resList = {};
    for (var i = 0; i < res.length; i++) {
      resList[res[i]] = 'device-art-resources/' + g_currentDevice.id + '/' +
          (port ? 'port_' : 'land_') + res[i] + '.png'
    }

    var resourceImages = {};
    loadImageResources(resList, function(r) {
      resourceImages = r;
      continueWithResources_();
    });

    function continueWithResources_() {
      var width = resourceImages['back'].naturalWidth;
      var height = resourceImages['back'].naturalHeight;
      var offset = port ? g_currentDevice.portOffset : g_currentDevice.landOffset;
      var size = port
          ? g_currentDevice.portSize
          : [g_currentDevice.portSize[1], g_currentDevice.portSize[0]];

      var canvas = document.createElement('canvas');
      canvas.width = width;
      canvas.height = height;

      var ctx = canvas.getContext('2d');
      if (resourceImages['shadow'] && $('#output-shadow').is(':checked')) {
        ctx.drawImage(resourceImages['shadow'], 0, 0);
      }
      ctx.drawImage(resourceImages['back'], 0, 0);
      ctx.fillStyle = '#000';
      ctx.fillRect(offset[0], offset[1], size[0], size[1]);
      ctx.drawImage(g_currentImage, offset[0], offset[1], size[0], size[1]);
      if (resourceImages['fore'] && $('#output-glare').is(':checked')) {
        ctx.drawImage(resourceImages['fore'], 0, 0);
      }

      window.URL = window.URL || window.webkitURL;
      if (canvas.toBlob && window.URL.createObjectURL) {
        if (g_currentObjectURL) {
          window.URL.revokeObjectURL(g_currentObjectURL);
          g_currentObjectURL = null;
        }
        if (g_currentBlob) {
          if (g_currentBlob.close) {
            g_currentBlob.close();
          }
          g_currentBlob = null;
        }

        canvas.toBlob(function(blob) {
          if (!blob) {
            continueWithFinalUrl_(canvas.toDataURL('image/png'));
            return;
          }
          g_currentBlob = blob;
          g_currentObjectURL = window.URL.createObjectURL(blob);
          continueWithFinalUrl_(g_currentObjectURL);
        }, 'image/png');
      } else {
        continueWithFinalUrl_(canvas.toDataURL('image/png'));
      }
    }

    function continueWithFinalUrl_(imageUrl) {
      var filename = g_currentFilename
          ? g_currentFilename.replace(/^(.+?)(\.\w+)?$/, '$1_framed.png')
          : 'framed_screenshot.png';

      var $link = $('<a>')
          .attr('download', filename)
          .attr('href', imageUrl)
          .append($('<img>')
              .addClass('dragout')
              .attr('src', imageUrl)
              .attr('draggable', true)
              .attr('data-downloadurl', ['image/png', filename, imageUrl].join(':')))
          .appendTo($('#output').empty());

      $('#frame-customizations').show();
    }
  }

  /**
   * Loads an image from a data URI. The callback will be called with the <img> once
   * it loads.
   */
  function loadImageFromUri(uri, callback) {
    callback = callback || function(){};

    var img = document.createElement('img');
    img.src = uri;
    img.onload = function() {
      callback(img);
    };
    img.onerror = function() {
      callback(null);
    }
  }

  /**
   * Loads a set of images (organized by ID). Once all images are loaded, the callback
   * is triggered with a dictionary of <img>'s, organized by ID.
   */
  function loadImageResources(images, callback) {
    var imageResources = {};

    var checkForCompletion_ = function() {
      for (var id in images) {
        if (!(id in imageResources))
          return;
      }
      (callback || function(){})(imageResources);
      callback = null;
    };

    for (var id in images) {
      var img = document.createElement('img');
      img.src = images[id];
      (function(img, id) {
        img.onload = function() {
          imageResources[id] = img;
          checkForCompletion_();
        };
        img.onerror = function() {
          imageResources[id] = null;
          checkForCompletion_();
        }
      })(img, id);
    }
  }

  /**
   * Loads the first valid image from a FileList (e.g. drag + drop source), as a data URI. This
   * method will throw an alert() in case of errors and call back with null.
   *
   * @param {FileList} fileList The FileList to load.
   * @param {Function} callback The callback to fire once image loading is done (or fails).
   * @return Returns an object containing 'uri' representing the loaded image. There will also be
   *      a 'name' field indicating the file name, if one is available.
   */
  function loadImageFromFileList(fileList, callback) {
    fileList = fileList || [];

    var file = null;
    for (var i = 0; i < fileList.length; i++) {
      if (fileList[i].type.toLowerCase().match(/^image\/(png|jpeg|jpg)/)) {
        file = fileList[i];
        break;
      }
    }

    if (!file) {
      alert('Please use a valid screenshot file (PNG or JPEG format).');
      callback(null);
      return;
    }

    var fileReader = new FileReader();

    // Closure to capture the file information.
    fileReader.onload = function(e) {
      callback({
        uri: e.target.result,
        name: file.name
      });
    };
    fileReader.onerror = function(e) {
      switch(e.target.error.code) {
        case e.target.error.NOT_FOUND_ERR:
          alert('File not found.');
          break;
        case e.target.error.NOT_READABLE_ERR:
          alert('File is not readable.');
          break;
        case e.target.error.ABORT_ERR:
          break; // noop
        default:
          alert('An error occurred reading this file.');
      }
      callback(null);
    };
    fileReader.onabort = function(e) {
      alert('File read cancelled.');
      callback(null);
    };

    fileReader.readAsDataURL(file);
  }

  /**
   * Adds a simple version of Canvas.toBlob if toBlob isn't available.
   */
  function polyfillCanvasToBlob() {
    if (!HTMLCanvasElement.prototype.toBlob && window.Blob) {
      HTMLCanvasElement.prototype.toBlob = function(callback, mimeType, quality) {
        if (typeof callback != 'function') {
          throw new TypeError('Function expected');
        }
        var dataURL = this.toDataURL(mimeType, quality);
        mimeType = dataURL.split(';')[0].split(':')[1];
        var bs = window.atob(dataURL.split(',')[1]);
        if (dataURL == 'data:,' || !bs.length) {
          callback(null);
          return;
        }
        for (var ui8arr = new Uint8Array(bs.length), i = 0; i < bs.length; ++i) {
          ui8arr[i] = bs.charCodeAt(i);
        }
        callback(new Blob([ui8arr.buffer /* req'd for Safari */ || ui8arr], {type: mimeType}));
      };
    }
  }
</script>
