From f5bac2f1e1a51b83d215a07f9d5d87db337873f3 Mon Sep 17 00:00:00 2001 From: Daniel Narvaez Date: Wed, 06 Feb 2013 14:30:36 +0000 Subject: Get the build to work --- (limited to 'apps/system/camera/js/filmstrip.js') diff --git a/apps/system/camera/js/filmstrip.js b/apps/system/camera/js/filmstrip.js deleted file mode 100644 index d428801..0000000 --- a/apps/system/camera/js/filmstrip.js +++ /dev/null @@ -1,568 +0,0 @@ -/* - * filmstrip.js: filmstrip, thumbnails and previews for the camera. - */ - -'use strict'; - -var Filmstrip = (function() { - - // This array holds all the data we need for image and video previews - var items = []; - var currentItemIndex; - - // Maximum number of thumbnails in the filmstrip - var MAX_THUMBNAILS = 5; - var THUMBNAIL_WIDTH = 46; // size of each thumbnail - var THUMBNAIL_HEIGHT = 46; - - // Timer for auto-hiding the filmstrip - var hideTimer = null; - - // Document elements we care about - var filmstrip = document.getElementById('filmstrip'); - var preview = document.getElementById('preview'); - var frameContainer = document.getElementById('frame-container'); - var mediaFrame = document.getElementById('media-frame'); - var cameraButton = document.getElementById('camera-button'); - var shareButton = document.getElementById('share-button'); - var deleteButton = document.getElementById('delete-button'); - var filmstripGalleryButton = - document.getElementById('filmstrip-gallery-button'); - - // Offscreen elements for generating thumbnails with - var offscreenImage = new Image(); - var offscreenVideo = document.createElement('video'); - - // Set up event handlers - cameraButton.onclick = returnToCameraMode; - deleteButton.onclick = deleteCurrentItem; - shareButton.onclick = shareCurrentItem; - filmstripGalleryButton.onclick = Camera.galleryBtnPressed; - mediaFrame.addEventListener('dbltap', handleDoubleTap); - mediaFrame.addEventListener('transform', handleTransform); - mediaFrame.addEventListener('pan', handlePan); - mediaFrame.addEventListener('swipe', handleSwipe); - - // Generate gesture events - var gestureDetector = new GestureDetector(mediaFrame); - gestureDetector.startDetecting(); - - // Create the MediaFrame for previews - var frame = new MediaFrame(mediaFrame); - - // Start off with it positioned correctly. - setOrientation(Camera._phoneOrientation); - - // If we're running in secure mode, we never want the user to see the - // gallery button or the share button. - filmstrip.removeChild(filmstripGalleryButton); - shareButton.parentNode.removeChild(shareButton); - - function isShown() { - return !filmstrip.classList.contains('hidden'); - } - - function hide() { - filmstrip.classList.add('hidden'); - if (hideTimer) { - clearTimeout(hideTimer); - hideTimer = null; - } - } - - /* - * With a time, show the filmstrip and then hide it after the time is up. - * Without time, show until hidden. - * Tapping in the camera toggles it. And if toggled on, it will be on - * without a timer. - * It is always on when a preview is shown. - * After recording a photo or video, it is shown for 5 seconds. - * And it is also shown for 5 seconds after leaving preview mode. - */ - function show(time) { - filmstrip.classList.remove('hidden'); - if (hideTimer) { - clearTimeout(hideTimer); - hideTimer = null; - } - if (time) - hideTimer = setTimeout(hide, time); - } - - filmstrip.onclick = function(event) { - var target = event.target; - if (!target || !target.classList.contains('thumbnail')) - return; - - var index = parseInt(target.dataset.index); - previewItem(index); - // If we're showing previews be sure we're showing the filmstrip - // with no timeout and be sure that the viewfinder video is paused. - show(); - Camera.viewfinder.pause(); - // If there is a preview shown, we want the gallery button in - // the filmstrip - filmstripGalleryButton.classList.remove('hidden'); - }; - - function previewItem(index) { - // Don't redisplay the item if it is already displayed - if (currentItemIndex === index) - return; - - var item = items[index]; - - if (item.isImage) { - frame.displayImage(item.blob, item.width, item.height, item.preview); - } - else if (item.isVideo) { - frame.displayVideo(item.blob, item.width, item.height, item.rotation); - } - - preview.classList.remove('offscreen'); - currentItemIndex = index; - - // Highlight the border of the thumbnail we're previewing - // and clear the highlight on all others - items.forEach(function(item, itemindex) { - if (itemindex === index) - item.element.classList.add('previewed'); - else - item.element.classList.remove('previewed'); - }); - } - - function returnToCameraMode() { - Camera.viewfinder.play(); // Restart the viewfinder - show(Camera.FILMSTRIP_DURATION); // Fade the filmstrip after a delay - // hide the gallery button in the filmstrip - filmstripGalleryButton.classList.add('hidden'); - preview.classList.add('offscreen'); - frame.clear(); - if (items.length > 0) - items[currentItemIndex].element.classList.remove('previewed'); - currentItemIndex = null; - } - - function deleteCurrentItem() { - var item = items[currentItemIndex]; - var msg, storage, filename; - - if (item.isImage) { - msg = navigator.mozL10n.get('delete-photo?'); - storage = Camera._pictureStorage; - filename = item.filename; - } - else { - msg = navigator.mozL10n.get('delete-video?'); - storage = Camera._videoStorage; - filename = item.filename; - } - - // The system app is not allowed to use confirm, I think - // so if we're running in secure mode, just delete the file without - // confirmation - if (Camera._secureMode || confirm(msg)) { - // Remove the item from the array of items - items.splice(currentItemIndex, 1); - - // Remove the thumbnail image from the filmstrip - filmstrip.removeChild(item.element); - URL.revokeObjectURL(item.element.src); - - // Renumber the item elements - items.forEach(function(item, index) { - item.element.dataset.index = index; - }); - - // If there are no more items, go back to the camera - if (items.length === 0) { - returnToCameraMode(); - } - else { - // Otherwise, switch the frame to display the next item. But if - // we just deleted the last item, then we'll need to display the - // previous item. - var newindex = currentItemIndex; - if (newindex >= items.length) - newindex = items.length - 1; - currentItemIndex = null; - previewItem(newindex); - } - - // Actually delete the file - storage.delete(filename).onerror = function(e) { - console.warn('Failed to delete', filename, - 'from DeviceStorage:', e.target.error); - } - } - } - - function shareCurrentItem() { - if (Camera._secureMode) - return; - var item = items[currentItemIndex]; - var type = item.isImage ? 'image/*' : 'video/*'; - var nameonly = item.filename.substring(item.filename.lastIndexOf('/') + 1); - var activity = new MozActivity({ - name: 'share', - data: { - type: type, - number: 1, - blobs: [item.blob], - filenames: [nameonly], - filepaths: [item.filename] /* temporary hack for bluetooth app */ - } - }); - activity.onerror = function(e) { - console.warn('Share activity error:', activity.error.name); - } - } - - function handleDoubleTap(e) { - if (!items[currentItemIndex].isImage) - return; - - var scale; - if (frame.fit.scale > frame.fit.baseScale) - scale = frame.fit.baseScale / frame.fit.scale; - else - scale = 2; - - // If the phone orientation is 0 (unrotated) then the gesture detector's - // event coordinates match what's on the screen, and we use them to - // specify a point to zoom in or out on. For other orientations we could - // calculate the correct point, but instead just use the midpoint. - var x, y; - if (Camera._phoneOrientation === 0) { - x = e.detail.clientX; - y = e.detail.clientY; - } - else { - x = mediaFrame.offsetWidth / 2; - y = mediaFrame.offsetHeight / 2; - } - - frame.zoom(scale, x, y, 200); - } - - function handleTransform(e) { - if (!items[currentItemIndex].isImage) - return; - - // If the phone orientation is 0 (unrotated) then the gesture detector's - // event coordinates match what's on the screen, and we use them to - // specify a point to zoom in or out on. For other orientations we could - // calculate the correct point, but instead just use the midpoint. - var x, y; - if (Camera._phoneOrientation === 0) { - x = e.detail.midpoint.clientX; - y = e.detail.midpoint.clientY; - } - else { - x = mediaFrame.offsetWidth / 2; - y = mediaFrame.offsetHeight / 2; - } - - frame.zoom(e.detail.relative.scale, x, y); - } - - function handlePan(e) { - if (!items[currentItemIndex].isImage) - return; - - // The gesture detector event does not take our CSS rotation into - // account, so we have to pan by a dx and dy that depend on how - // the MediaFrame is rotated - var dx, dy; - switch (Camera._phoneOrientation) { - case 0: - dx = e.detail.relative.dx; - dy = e.detail.relative.dy; - break; - case 90: - dx = -e.detail.relative.dy; - dy = e.detail.relative.dx; - break; - case 180: - dx = -e.detail.relative.dx; - dy = -e.detail.relative.dy; - break; - case 270: - dx = e.detail.relative.dy; - dy = -e.detail.relative.dx; - break; - } - - frame.pan(dx, dy); - } - - function handleSwipe(e) { - // Because the stuff around the media frame does not change position - // when the phone is rotated, we don't alter these directions based - // on orientation. To dismiss the preview, the user always swipes toward - // the filmstrip. - - switch (e.detail.direction) { - case 'up': // close the preview if the swipe is fast enough - if (e.detail.vy < -1) - returnToCameraMode(); - break; - case 'left': // go to next image if fast enough - if (e.detail.vx < -1 && currentItemIndex < items.length - 1) - previewItem(currentItemIndex + 1); - break; - case 'right': // go to previous image if fast enough - if (e.detail.vx > 1 && currentItemIndex > 0) - previewItem(currentItemIndex - 1); - break; - } - } - - function addImage(filename, blob) { - parseJPEGMetadata(blob, function getPreviewBlob(metadata) { - if (metadata.preview) { - var previewBlob = blob.slice(metadata.preview.start, - metadata.preview.end, - 'image/jpeg'); - - offscreenImage.src = URL.createObjectURL(previewBlob); - offscreenImage.onload = function() { - createThumbnailFromElement(offscreenImage, false, 0, - function(thumbnail) { - addItem({ - isImage: true, - filename: filename, - thumbnail: thumbnail, - blob: blob, - width: metadata.width, - height: metadata.height, - preview: metadata.preview - }); - }); - URL.revokeObjectURL(offscreenImage.src); - offscreenImage.onload = null; - offscreenImage.src = null; - }; - } - }, function logerr(msg) { console.warn(msg); }); - } - - function addVideo(filename) { - var request = Camera._videoStorage.get(filename); - request.onerror = function() { - console.warn('addVideo:', filename, request.error.name); - }; - request.onsuccess = function() { - var blob = request.result; - getVideoRotation(blob, function(rotation) { - if (typeof rotation !== 'number') { - console.warn('Unexpected rotation:', rotation); - rotation = 0; - } - - var url = URL.createObjectURL(blob); - - offscreenVideo.preload = 'metadata'; - offscreenVideo.style.width = THUMBNAIL_WIDTH + 'px'; - offscreenVideo.style.height = THUMBNAIL_HEIGHT + 'px'; - offscreenVideo.src = url; - - offscreenVideo.onerror = function() { - URL.revokeObjectURL(url); - offscreenVideo.onerror = null; - offscreenVideo.onloadedmetadata = null; - offscreenVideo.removeAttribute('src'); - offscreenVideo.load(); - console.warn('not a video file', filename); - } - - offscreenVideo.onloadedmetadata = function() { - createThumbnailFromElement(offscreenVideo, true, rotation, - function(thumbnail) { - addItem({ - isVideo: true, - filename: filename, - thumbnail: thumbnail, - blob: blob, - width: offscreenVideo.videoWidth, - height: offscreenVideo.videoHeight, - rotation: rotation - }); - }); - URL.revokeObjectURL(url); - offscreenVideo.onerror = null; - offscreenVideo.onloadedmetadata = null; - offscreenVideo.removeAttribute('src'); - offscreenVideo.load(); - }; - }); - }; - } - - // Add a thumbnail to the filmstrip. - // The details object contains everything we need to know - // to display the thumbnail and preview the image or video - function addItem(item) { - // Thumbnails go from most recent to least recent. - items.unshift(item); - - // Create an image element for this new thumbnail and display it - item.element = new Image(); - item.element.src = URL.createObjectURL(item.thumbnail); - item.element.classList.add('thumbnail'); - filmstrip.insertBefore(item.element, filmstrip.firstElementChild); - - // If we have too many thumbnails now, remove the oldest one from - // the array, and remove its element from the filmstrip and release - // its blob url - if (items.length > MAX_THUMBNAILS) { - var oldest = items.pop(); - filmstrip.removeChild(oldest.element); - URL.revokeObjectURL(oldest.element.src); - } - - // Now update the index associated with each of the remaining elements - // so that the click event handle knows which one it clicked on - items.forEach(function(item, index) { - item.element.dataset.index = index; - }); - } - - // Remove all items from the filmstrip. Don't delete the files, but - // forget all of our state. This also exits preview mode if we're in it. - function clear() { - if (!preview.classList.contains('offscreen')) - returnToCameraMode(); - items.forEach(function(item) { - filmstrip.removeChild(item.element); - URL.revokeObjectURL(item.element.src); - }); - items.length = 0; - } - - // Create a thumbnail size canvas, copy the or