summaryrefslogtreecommitdiffstats
path: root/docs/html/distribute
diff options
context:
space:
mode:
authorRoman Nurik <romannurik@google.com>2012-07-31 14:08:59 -0700
committerRoman Nurik <romannurik@google.com>2012-08-01 09:05:37 -0700
commit37eecc7e924513f1653b874af9d52e14c1bc9757 (patch)
tree1248afbaf7dd11422b8250df1292b5b30de3b60d /docs/html/distribute
parent971c05a07b42018fa994d0f48d559838de7ed1a0 (diff)
downloadframeworks_base-37eecc7e924513f1653b874af9d52e14c1bc9757.zip
frameworks_base-37eecc7e924513f1653b874af9d52e14c1bc9757.tar.gz
frameworks_base-37eecc7e924513f1653b874af9d52e14c1bc9757.tar.bz2
docs: Add Device Art Generator for Nexus devices to d.a.c/distribute.
Most of this code is adapted from my code.google.com/p/android-ui-utils project. Change-Id: If6763bc7a490e53bd31d5a713158577fa74cfd7b
Diffstat (limited to 'docs/html/distribute')
-rw-r--r--docs/html/distribute/distribute_toc.cs2
-rw-r--r--docs/html/distribute/promote/device-art-resources/galaxy_nexus/land_back.pngbin0 -> 83440 bytes
-rw-r--r--docs/html/distribute/promote/device-art-resources/galaxy_nexus/land_fore.pngbin0 -> 31701 bytes
-rw-r--r--docs/html/distribute/promote/device-art-resources/galaxy_nexus/land_shadow.pngbin0 -> 43499 bytes
-rw-r--r--docs/html/distribute/promote/device-art-resources/galaxy_nexus/port_back.pngbin0 -> 71907 bytes
-rw-r--r--docs/html/distribute/promote/device-art-resources/galaxy_nexus/port_fore.pngbin0 -> 26942 bytes
-rw-r--r--docs/html/distribute/promote/device-art-resources/galaxy_nexus/port_shadow.pngbin0 -> 40335 bytes
-rw-r--r--docs/html/distribute/promote/device-art-resources/galaxy_nexus/thumb.pngbin0 -> 7803 bytes
-rw-r--r--docs/html/distribute/promote/device-art-resources/nexus_7/land_back.pngbin0 -> 29977 bytes
-rw-r--r--docs/html/distribute/promote/device-art-resources/nexus_7/land_fore.pngbin0 -> 30153 bytes
-rw-r--r--docs/html/distribute/promote/device-art-resources/nexus_7/land_shadow.pngbin0 -> 33797 bytes
-rw-r--r--docs/html/distribute/promote/device-art-resources/nexus_7/port_back.pngbin0 -> 30267 bytes
-rw-r--r--docs/html/distribute/promote/device-art-resources/nexus_7/port_fore.pngbin0 -> 32982 bytes
-rw-r--r--docs/html/distribute/promote/device-art-resources/nexus_7/port_shadow.pngbin0 -> 41554 bytes
-rw-r--r--docs/html/distribute/promote/device-art-resources/nexus_7/thumb.pngbin0 -> 8163 bytes
-rw-r--r--docs/html/distribute/promote/device-art-resources/nexus_s/land_back.pngbin0 -> 113962 bytes
-rw-r--r--docs/html/distribute/promote/device-art-resources/nexus_s/land_fore.pngbin0 -> 20781 bytes
-rw-r--r--docs/html/distribute/promote/device-art-resources/nexus_s/land_shadow.pngbin0 -> 23374 bytes
-rw-r--r--docs/html/distribute/promote/device-art-resources/nexus_s/port_back.pngbin0 -> 107435 bytes
-rw-r--r--docs/html/distribute/promote/device-art-resources/nexus_s/port_fore.pngbin0 -> 16162 bytes
-rw-r--r--docs/html/distribute/promote/device-art-resources/nexus_s/port_shadow.pngbin0 -> 21240 bytes
-rw-r--r--docs/html/distribute/promote/device-art-resources/nexus_s/thumb.pngbin0 -> 10042 bytes
-rw-r--r--docs/html/distribute/promote/device-art-resources/xoom/land_back.pngbin0 -> 27199 bytes
-rw-r--r--docs/html/distribute/promote/device-art-resources/xoom/land_fore.pngbin0 -> 28252 bytes
-rw-r--r--docs/html/distribute/promote/device-art-resources/xoom/land_shadow.pngbin0 -> 26575 bytes
-rw-r--r--docs/html/distribute/promote/device-art-resources/xoom/port_back.pngbin0 -> 26085 bytes
-rw-r--r--docs/html/distribute/promote/device-art-resources/xoom/port_fore.pngbin0 -> 27070 bytes
-rw-r--r--docs/html/distribute/promote/device-art-resources/xoom/port_shadow.pngbin0 -> 31541 bytes
-rw-r--r--docs/html/distribute/promote/device-art-resources/xoom/thumb.pngbin0 -> 9124 bytes
-rw-r--r--docs/html/distribute/promote/device-art.jd517
30 files changed, 519 insertions, 0 deletions
diff --git a/docs/html/distribute/distribute_toc.cs b/docs/html/distribute/distribute_toc.cs
index bc028e5..f11e965 100644
--- a/docs/html/distribute/distribute_toc.cs
+++ b/docs/html/distribute/distribute_toc.cs
@@ -74,6 +74,8 @@
<span class="en">Google Play Badges</a></li>
<li><a href="<?cs var:toroot ?>distribute/googleplay/promote/brand.html">
<span class="en">Brand Assets and Guidelines</a></li>
+ <li><a href="<?cs var:toroot ?>distribute/promote/device-art.html">
+ <span class="en">Device Art Generator</a></li>
</ul>
</li>
diff --git a/docs/html/distribute/promote/device-art-resources/galaxy_nexus/land_back.png b/docs/html/distribute/promote/device-art-resources/galaxy_nexus/land_back.png
new file mode 100644
index 0000000..f340a62
--- /dev/null
+++ b/docs/html/distribute/promote/device-art-resources/galaxy_nexus/land_back.png
Binary files differ
diff --git a/docs/html/distribute/promote/device-art-resources/galaxy_nexus/land_fore.png b/docs/html/distribute/promote/device-art-resources/galaxy_nexus/land_fore.png
new file mode 100644
index 0000000..2a4e595
--- /dev/null
+++ b/docs/html/distribute/promote/device-art-resources/galaxy_nexus/land_fore.png
Binary files differ
diff --git a/docs/html/distribute/promote/device-art-resources/galaxy_nexus/land_shadow.png b/docs/html/distribute/promote/device-art-resources/galaxy_nexus/land_shadow.png
new file mode 100644
index 0000000..f3a3120
--- /dev/null
+++ b/docs/html/distribute/promote/device-art-resources/galaxy_nexus/land_shadow.png
Binary files differ
diff --git a/docs/html/distribute/promote/device-art-resources/galaxy_nexus/port_back.png b/docs/html/distribute/promote/device-art-resources/galaxy_nexus/port_back.png
new file mode 100644
index 0000000..c40b37c
--- /dev/null
+++ b/docs/html/distribute/promote/device-art-resources/galaxy_nexus/port_back.png
Binary files differ
diff --git a/docs/html/distribute/promote/device-art-resources/galaxy_nexus/port_fore.png b/docs/html/distribute/promote/device-art-resources/galaxy_nexus/port_fore.png
new file mode 100644
index 0000000..aae684b
--- /dev/null
+++ b/docs/html/distribute/promote/device-art-resources/galaxy_nexus/port_fore.png
Binary files differ
diff --git a/docs/html/distribute/promote/device-art-resources/galaxy_nexus/port_shadow.png b/docs/html/distribute/promote/device-art-resources/galaxy_nexus/port_shadow.png
new file mode 100644
index 0000000..61a0da9
--- /dev/null
+++ b/docs/html/distribute/promote/device-art-resources/galaxy_nexus/port_shadow.png
Binary files differ
diff --git a/docs/html/distribute/promote/device-art-resources/galaxy_nexus/thumb.png b/docs/html/distribute/promote/device-art-resources/galaxy_nexus/thumb.png
new file mode 100644
index 0000000..e21a421
--- /dev/null
+++ b/docs/html/distribute/promote/device-art-resources/galaxy_nexus/thumb.png
Binary files differ
diff --git a/docs/html/distribute/promote/device-art-resources/nexus_7/land_back.png b/docs/html/distribute/promote/device-art-resources/nexus_7/land_back.png
new file mode 100644
index 0000000..2999f35
--- /dev/null
+++ b/docs/html/distribute/promote/device-art-resources/nexus_7/land_back.png
Binary files differ
diff --git a/docs/html/distribute/promote/device-art-resources/nexus_7/land_fore.png b/docs/html/distribute/promote/device-art-resources/nexus_7/land_fore.png
new file mode 100644
index 0000000..cefdd35
--- /dev/null
+++ b/docs/html/distribute/promote/device-art-resources/nexus_7/land_fore.png
Binary files differ
diff --git a/docs/html/distribute/promote/device-art-resources/nexus_7/land_shadow.png b/docs/html/distribute/promote/device-art-resources/nexus_7/land_shadow.png
new file mode 100644
index 0000000..8f7aec7
--- /dev/null
+++ b/docs/html/distribute/promote/device-art-resources/nexus_7/land_shadow.png
Binary files differ
diff --git a/docs/html/distribute/promote/device-art-resources/nexus_7/port_back.png b/docs/html/distribute/promote/device-art-resources/nexus_7/port_back.png
new file mode 100644
index 0000000..b2908a8
--- /dev/null
+++ b/docs/html/distribute/promote/device-art-resources/nexus_7/port_back.png
Binary files differ
diff --git a/docs/html/distribute/promote/device-art-resources/nexus_7/port_fore.png b/docs/html/distribute/promote/device-art-resources/nexus_7/port_fore.png
new file mode 100644
index 0000000..7f4b0b4
--- /dev/null
+++ b/docs/html/distribute/promote/device-art-resources/nexus_7/port_fore.png
Binary files differ
diff --git a/docs/html/distribute/promote/device-art-resources/nexus_7/port_shadow.png b/docs/html/distribute/promote/device-art-resources/nexus_7/port_shadow.png
new file mode 100644
index 0000000..c10bd53
--- /dev/null
+++ b/docs/html/distribute/promote/device-art-resources/nexus_7/port_shadow.png
Binary files differ
diff --git a/docs/html/distribute/promote/device-art-resources/nexus_7/thumb.png b/docs/html/distribute/promote/device-art-resources/nexus_7/thumb.png
new file mode 100644
index 0000000..8b5cc5a
--- /dev/null
+++ b/docs/html/distribute/promote/device-art-resources/nexus_7/thumb.png
Binary files differ
diff --git a/docs/html/distribute/promote/device-art-resources/nexus_s/land_back.png b/docs/html/distribute/promote/device-art-resources/nexus_s/land_back.png
new file mode 100644
index 0000000..f525e8e
--- /dev/null
+++ b/docs/html/distribute/promote/device-art-resources/nexus_s/land_back.png
Binary files differ
diff --git a/docs/html/distribute/promote/device-art-resources/nexus_s/land_fore.png b/docs/html/distribute/promote/device-art-resources/nexus_s/land_fore.png
new file mode 100644
index 0000000..e26bfe1
--- /dev/null
+++ b/docs/html/distribute/promote/device-art-resources/nexus_s/land_fore.png
Binary files differ
diff --git a/docs/html/distribute/promote/device-art-resources/nexus_s/land_shadow.png b/docs/html/distribute/promote/device-art-resources/nexus_s/land_shadow.png
new file mode 100644
index 0000000..ea26b73
--- /dev/null
+++ b/docs/html/distribute/promote/device-art-resources/nexus_s/land_shadow.png
Binary files differ
diff --git a/docs/html/distribute/promote/device-art-resources/nexus_s/port_back.png b/docs/html/distribute/promote/device-art-resources/nexus_s/port_back.png
new file mode 100644
index 0000000..ed4ad0c
--- /dev/null
+++ b/docs/html/distribute/promote/device-art-resources/nexus_s/port_back.png
Binary files differ
diff --git a/docs/html/distribute/promote/device-art-resources/nexus_s/port_fore.png b/docs/html/distribute/promote/device-art-resources/nexus_s/port_fore.png
new file mode 100644
index 0000000..74bd077
--- /dev/null
+++ b/docs/html/distribute/promote/device-art-resources/nexus_s/port_fore.png
Binary files differ
diff --git a/docs/html/distribute/promote/device-art-resources/nexus_s/port_shadow.png b/docs/html/distribute/promote/device-art-resources/nexus_s/port_shadow.png
new file mode 100644
index 0000000..bb4bec8
--- /dev/null
+++ b/docs/html/distribute/promote/device-art-resources/nexus_s/port_shadow.png
Binary files differ
diff --git a/docs/html/distribute/promote/device-art-resources/nexus_s/thumb.png b/docs/html/distribute/promote/device-art-resources/nexus_s/thumb.png
new file mode 100644
index 0000000..8b9a3d9
--- /dev/null
+++ b/docs/html/distribute/promote/device-art-resources/nexus_s/thumb.png
Binary files differ
diff --git a/docs/html/distribute/promote/device-art-resources/xoom/land_back.png b/docs/html/distribute/promote/device-art-resources/xoom/land_back.png
new file mode 100644
index 0000000..e1eb075
--- /dev/null
+++ b/docs/html/distribute/promote/device-art-resources/xoom/land_back.png
Binary files differ
diff --git a/docs/html/distribute/promote/device-art-resources/xoom/land_fore.png b/docs/html/distribute/promote/device-art-resources/xoom/land_fore.png
new file mode 100644
index 0000000..15e5f50
--- /dev/null
+++ b/docs/html/distribute/promote/device-art-resources/xoom/land_fore.png
Binary files differ
diff --git a/docs/html/distribute/promote/device-art-resources/xoom/land_shadow.png b/docs/html/distribute/promote/device-art-resources/xoom/land_shadow.png
new file mode 100644
index 0000000..885508a
--- /dev/null
+++ b/docs/html/distribute/promote/device-art-resources/xoom/land_shadow.png
Binary files differ
diff --git a/docs/html/distribute/promote/device-art-resources/xoom/port_back.png b/docs/html/distribute/promote/device-art-resources/xoom/port_back.png
new file mode 100644
index 0000000..290ca35
--- /dev/null
+++ b/docs/html/distribute/promote/device-art-resources/xoom/port_back.png
Binary files differ
diff --git a/docs/html/distribute/promote/device-art-resources/xoom/port_fore.png b/docs/html/distribute/promote/device-art-resources/xoom/port_fore.png
new file mode 100644
index 0000000..8b3dca3
--- /dev/null
+++ b/docs/html/distribute/promote/device-art-resources/xoom/port_fore.png
Binary files differ
diff --git a/docs/html/distribute/promote/device-art-resources/xoom/port_shadow.png b/docs/html/distribute/promote/device-art-resources/xoom/port_shadow.png
new file mode 100644
index 0000000..895b75e
--- /dev/null
+++ b/docs/html/distribute/promote/device-art-resources/xoom/port_shadow.png
Binary files differ
diff --git a/docs/html/distribute/promote/device-art-resources/xoom/thumb.png b/docs/html/distribute/promote/device-art-resources/xoom/thumb.png
new file mode 100644
index 0000000..8fd08a4
--- /dev/null
+++ b/docs/html/distribute/promote/device-art-resources/xoom/thumb.png
Binary files differ
diff --git a/docs/html/distribute/promote/device-art.jd b/docs/html/distribute/promote/device-art.jd
new file mode 100644
index 0000000..af36625
--- /dev/null
+++ b/docs/html/distribute/promote/device-art.jd
@@ -0,0 +1,517 @@
+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 id="device-list"></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">
+ <div id="output">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;
+ }
+
+ #output {
+ color: #f44;
+ font-style: italic;
+ }
+
+ #output img {
+ max-height: 500px;
+ }
+</style>
+<script>
+ // Global variables
+ var g_currentImage;
+ var g_currentDevice;
+
+ // Global constants
+ var MSG_INVALID_INPUT_IMAGE = 'Invalid screenshot provided. Screenshots must be PNG files '
+ + 'matching the target device\'s screen resolution 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_7',
+ title: 'Nexus 7',
+ url: 'http://www.android.com/devices/detail/nexus-7',
+ physicalSize: 7,
+ physicalHeight: 7.81,
+ density: 213,
+ landRes: ['shadow', 'back', 'fore'],
+ landOffset: [363,260],
+ portRes: ['shadow', 'back', 'fore'],
+ portOffset: [265,341],
+ portSize: [800,1280],
+ },
+ {
+ id: 'xoom',
+ title: 'Motorola XOOM',
+ url: 'http://www.google.com/phone/detail/motorola-xoom',
+ physicalSize: 10,
+ physicalHeight: 6.61,
+ density: 160,
+ landRes: ['shadow', 'back', 'fore'],
+ landOffset: [218,191],
+ portRes: ['shadow', 'back', 'fore'],
+ portOffset: [199,200],
+ portSize: [800,1280],
+ },
+ {
+ id: 'galaxy_nexus',
+ title: 'Galaxy Nexus',
+ url: 'http://www.android.com/devices/detail/galaxy-nexus',
+ physicalSize: 4.65,
+ physicalHeight: 5.33,
+ density: 320,
+ landRes: ['shadow', 'back', 'fore'],
+ landOffset: [371,199],
+ portRes: ['shadow', 'back', 'fore'],
+ portOffset: [216,353],
+ portSize: [720,1280],
+ },
+ {
+ id: 'nexus_s',
+ title: 'Nexus S',
+ url: 'http://www.google.com/phone/detail/nexus-s',
+ physicalSize: 4.0,
+ physicalHeight: 4.88,
+ density: 240,
+ landRes: ['shadow', 'back', 'fore'],
+ landOffset: [247,135],
+ portRes: ['shadow', 'back', 'fore'],
+ portOffset: [134,247],
+ portSize: [480,800],
+ }
+ ];
+
+ 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;
+ }
+
+ setupUI();
+
+ // Set up Chrome drag-out
+ $.event.props.push("dataTransfer");
+ document.body.addEventListener('dragstart', function(e) {
+ var a = e.target;
+ if (a.classList.contains('dragout')) {
+ e.dataTransfer.setData('DownloadURL', a.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();
+
+ $('#output-shadow, #output-glare').click(function() {
+ createFrame(g_currentDevice, g_currentImage);
+ });
+
+ // Build device list.
+ $.each(DEVICES, function() {
+ $('<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 + 'dpi' +
+ '<br>' + this.portSize[0] + 'x' + this.portSize[1]))
+ .data('deviceId', this.id)
+ .appendTo('#device-list');
+ });
+
+ // 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();
+ });
+ });
+ });
+
+ // 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(), function(img) {
+ g_currentImage = img;
+ createFrame();
+ });
+ });
+ }
+
+ /**
+ * Generates the frame from the current selections (g_currentImage and g_currentDevice).
+ */
+ function createFrame() {
+ var port;
+ if (g_currentImage.naturalWidth == g_currentDevice.portSize[0] &&
+ g_currentImage.naturalHeight == g_currentDevice.portSize[1]) {
+ if (!g_currentDevice.portRes) {
+ alert('No portrait frame is currently available for this device.');
+ $('#output').html(MSG_NO_INPUT_IMAGE);
+ return;
+ }
+ port = true;
+ } else if (g_currentImage.naturalWidth == g_currentDevice.portSize[1] &&
+ g_currentImage.naturalHeight == g_currentDevice.portSize[0]) {
+ if (!g_currentDevice.landRes) {
+ alert('No landscape frame is currently available for this device.');
+ $('#output').html(MSG_NO_INPUT_IMAGE);
+ return;
+ }
+ port = false;
+ } else {
+ alert('Screenshots for ' + g_currentDevice.title + ' must be ' +
+ 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;
+ continuation_();
+ });
+
+ function continuation_() {
+ var width = resourceImages['back'].naturalWidth;
+ var height = resourceImages['back'].naturalHeight;
+ var offset = port ? g_currentDevice.portOffset : g_currentDevice.landOffset;
+
+ 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.drawImage(g_currentImage, offset[0], offset[1]);
+ if (resourceImages['fore'] && $('#output-glare').is(':checked')) {
+ ctx.drawImage(resourceImages['fore'], 0, 0);
+ }
+
+ var dataUrl = canvas.toDataURL();
+ var filename = g_currentFilename
+ ? ('framed_' + g_currentFilename)
+ : 'framed_screenshot.png';
+
+ var $link = $('<a>')
+ .attr('download', filename)
+ .attr('href', dataUrl)
+ .attr('draggable', true)
+ .attr('data-downloadurl', ['image/png', filename, dataUrl].join(':'))
+ .append($('<img>').attr('src', dataUrl))
+ .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/)) {
+ file = fileList[i];
+ break;
+ }
+ }
+
+ if (!file) {
+ alert('Please use a valid screenshot file (PNG 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);
+ }
+</script>