image mode

This commit is contained in:
Emi Matchu 2011-06-27 15:33:34 -04:00
parent 714f2fddf5
commit 443b144f29
9 changed files with 420 additions and 179 deletions

View file

@ -1,3 +1,10 @@
class ApplicationController < ActionController::Base
protect_from_forgery
helper_method :can_use_image_mode?
def can_use_image_mode?
user_signed_in? && current_user.image_mode_tester?
end
end

View file

@ -14,6 +14,10 @@ module ApplicationHelper
end
end
def donate_url
'/donate'
end
def flashes
raw(flash.inject('') do |html, pair|
key, value = pair

View file

@ -20,6 +20,10 @@ $outfit-header-padding: 24px
$outfit-content-width: $sidebar-unit-inner-width - $outfit-thumbnail-size - $outfit-thumbnail-margin - 32px
$outfit-content-inner-width: $outfit-content-width - $outfit-header-padding
=active-mode
color: $text-color
font-weight: bold
=outfit
+outfit-star-shifted
padding: .25em 0
@ -187,6 +191,51 @@ body.outfits-edit
z-index: 1000
&.waiting-on-0
display: none
#preview-mode
margin-right: 1em
position: absolute
right: 100%
text-align: center
top: 0
width: 7em
&.flash-active
#preview-mode-flash
+active-mode
&.image-active
#preview-mode-image
+active-mode
&.can-download
#preview-download-image
display: inline-block
#preview-mode-toggle
+border-radius(.5em)
border: 1px solid $module-border-color
color: $soft-text-color
font-size: 85%
list-style: none
margin: 0 auto .5em
text-align: center
width: 5em
li
border-top: 1px solid $soft-border-color
cursor: pointer
padding: .125em 0
width: 100%
&:first-child
border-top: 0
#preview-download-image
display: none
font-size: 85%
margin: 0 auto
#preview-mode-image-access-denied
display: block
font-size: 75%
text-align: center
text-decoration: none
width: 100%
em
font-style: normal
text-decoration: underline
#preview-sidebar
+border-radius(10px)
border: 1px solid $soft-border-color

View file

@ -36,6 +36,19 @@
%p Flash and Javascript (but not Java!) are required to preview outfits.
%p If this message stays after the page is done loading, check those first.
#preview-image-container
#preview-mode
%ul#preview-mode-toggle
%li#preview-mode-flash.active Flash
- if can_use_image_mode?
%li#preview-mode-image Image
- unless can_use_image_mode?
= link_to(donate_url, :id => 'preview-mode-image-access-denied', :target => '_blank') do
%strong Image mode
is available for early beta testing to users who
%em donate
at least $5 to help upgrade the server. Thanks!
- if can_use_image_mode?
%button#preview-download-image Download
#preview-sidebar
#outfit-not-found Outfit not found
#save-success Outfit successfully saved

View file

@ -0,0 +1,10 @@
class AddImageModeTesterToUsers < ActiveRecord::Migration
def self.up
add_column :users, :image_mode_tester, :boolean, :default => false, :null => false
end
def self.down
remove_column :users, :image_mode_tester
end
end

View file

@ -10,7 +10,7 @@
#
# It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20110515134542) do
ActiveRecord::Schema.define(:version => 20110626202605) do
create_table "auth_servers", :force => true do |t|
t.string "short_name", :limit => 10, :null => false
@ -168,6 +168,7 @@ ActiveRecord::Schema.define(:version => 20110515134542) do
t.datetime "remember_created_at"
t.boolean "forum_admin", :default => false, :null => false
t.boolean "forum_moderator"
t.boolean "image_mode_tester", :default => false, :null => false
end
create_table "zones", :force => true do |t|

View file

@ -822,6 +822,32 @@ View.PreviewAdapterForm = function (wardrobe) {
preview.toggleAdapter();
}
konami.load();
var modeWrapper = $('#preview-mode').addClass('flash-active');
var modeOptions = $('#preview-mode-toggle li');
function activate(el, modeOn, modeOff) {
modeWrapper.removeClass(modeOff + '-active').addClass(modeOn + '-active');
$(el).addClass('active');
}
$('#preview-mode-flash').click(function () {
activate(this, 'flash', 'image');
preview.useSWFAdapter();
});
$('#preview-mode-image').click(function () {
activate(this, 'image', 'flash');
preview.useImageAdapter();
});
$('#preview-download-image').click(function () {
preview.adapter.saveImage();
});
if(document.createElement('canvas').getContext) {
// If browser supports canvas
modeWrapper.addClass('can-download');
}
}
View.Search = function (wardrobe) {

View file

@ -1249,6 +1249,48 @@ Wardrobe.getStandardView = function (options) {
preview_el.removeClass('swf-adapter').addClass('image-adapter');
pendingMessageEl.appendTo(previewImageContainer);
var exportIframe = $('#preview-export-iframe');
if(exportIframe.length == 0) {
exportIframe = $('<iframe/>',
{
id: 'preview-export-iframe',
src: 'about:blank',
css: {
left: -1000,
position: 'absolute',
top: -1000,
width: 300,
height: 300
}
}
).appendTo(document.body);
}
this.saveImage = function () {
/*
Since browser security policy denies access to canvas image data
if we include assets from other domains, and our assets are on S3,
we pass the job to an HTML file on S3 called preview_export.html.
It expects the following query string:
?WIDTH,HEIGHT,IMAGEURL0[,IMAGEURL1,...]
It then prompts the user to download a WIDTHxHEIGHT image of the
IMAGEURLs layered in order.
*/
var size = bestSize();
var url = Wardrobe.IMAGE_CONFIG.base_url + "preview_export.html?" +
size[0] + "," + size[1];
previewImageContainer.children('img').each(function () {
url += "," + encodeURIComponent(this.src);
});
exportIframe.attr('src', url);
}
this.updateAssets = function () {
var assets = wardrobe.outfit.getVisibleAssets(), asset,
availableAssets = [];
@ -1269,15 +1311,38 @@ Wardrobe.getStandardView = function (options) {
}
function addToView(asset) {
$(
/*
Instead of sorting these assets by zIndex later when we're putting
them on the canvas, we just sort them as they get inserted.
Find the first asset with a higher zIndex, then insert the new asset
before that one. If there is no asset with a higher zIndex, just
put it at the very end.
*/
var newZIndex = asset.depth, nextHighestAsset;
previewImageContainer.children('img').each(function () {
var el = $(this);
if(el.css('zIndex') > newZIndex) {
nextHighestAsset = el;
return false;
}
});
var el = $(
'<img/>',
{
css: {
zIndex: asset.depth
zIndex: newZIndex
},
src: asset.imageURL(bestSize())
}
).appendTo(previewImageContainer);
);
if(nextHighestAsset) {
el.insertBefore(nextHighestAsset);
} else {
el.appendTo(previewImageContainer);
}
}
// TODO: choose new best size on window resize

File diff suppressed because it is too large Load diff