1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-25 16:22:43 +01:00

When an image is too wide in Pholio, scale it down

Summary:
Currently, if an image is too wide for the viewport, we freak out. Instead, scale it down.

This means we must also scale down all the rectangles on it, which is why this is tricky. However, all the draw/load separation has made it reasonably straightforward.

We'll possibly need to add some kind of "view full size" thing. I'm planning to add an element which shows "85%" or whatever if it's currently scaled.

Test Plan:
Before:

{F33607}

After:

{F33608}

Reviewers: chad, ljalonen

Reviewed By: chad

CC: aran

Differential Revision: https://secure.phabricator.com/D5088
This commit is contained in:
epriestley 2013-02-23 06:28:34 -08:00
parent 8641ef3948
commit 26f8e76ee2
5 changed files with 109 additions and 56 deletions

View file

@ -133,7 +133,7 @@ JX.install('Event', {
var r = this.getRawEvent();
return r.which == 3 || r.button == 2;
},
/**
* Determine if a mouse event is a normal event (left mouse button, no
* modifier keys).
@ -142,14 +142,15 @@ JX.install('Event', {
* @task info
*/
isNormalMouseEvent : function() {
var supportedEvents = ['click','mouseup','mousedown'];
var supportedEvents = ['click', 'mouseup', 'mousedown'];
if (supportedEvents.indexOf(this.getType()) == -1) {
return false;
}
var r = this.getRawEvent();
if (r.metaKey || r.altKey || r.ctrlkey || r.shiftKey) {
if (r.metaKey || r.altKey || r.ctrlKey || r.shiftKey) {
return false;
}

View file

@ -1873,16 +1873,17 @@ celerity_register_resource_map(array(
),
'javelin-behavior-pholio-mock-view' =>
array(
'uri' => '/res/e2778b8e/rsrc/js/application/pholio/behavior-pholio-mock-view.js',
'uri' => '/res/b7c2b169/rsrc/js/application/pholio/behavior-pholio-mock-view.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
3 => 'javelin-vector',
4 => 'javelin-magical-init',
5 => 'javelin-request',
1 => 'javelin-util',
2 => 'javelin-stratcom',
3 => 'javelin-dom',
4 => 'javelin-vector',
5 => 'javelin-magical-init',
6 => 'javelin-request',
),
'disk' => '/rsrc/js/application/pholio/behavior-pholio-mock-view.js',
),
@ -3217,7 +3218,7 @@ celerity_register_resource_map(array(
),
'pholio-css' =>
array(
'uri' => '/res/ecd07cd8/rsrc/css/application/pholio/pholio.css',
'uri' => '/res/4ca7889f/rsrc/css/application/pholio/pholio.css',
'type' => 'css',
'requires' =>
array(

View file

@ -16,10 +16,12 @@ final class PholioMockImagesView extends AphrontView {
$mock = $this->mock;
$main_image_id = celerity_generate_unique_node_id();
require_celerity_resource('javelin-behavior-pholio-mock-view');
$images = array();
$panel_id = celerity_generate_unique_node_id();
$viewport_id = celerity_generate_unique_node_id();
foreach ($mock->getImages() as $image) {
$images[] = array(
'id' => $image->getID(),
@ -28,8 +30,9 @@ final class PholioMockImagesView extends AphrontView {
}
$config = array(
'mainID' => $main_image_id,
'mockID' => $mock->getID(),
'panelID' => $panel_id,
'viewportID' => $viewport_id,
'images' => $images,
);
@ -37,25 +40,22 @@ final class PholioMockImagesView extends AphrontView {
$mockview = '';
$main_image = head($mock->getImages());
$main_image_tag = javelin_tag(
'img',
array(
'id' => $main_image_id,
'sigil' => 'mock-image',
'class' => 'pholio-mock-image',
'style' => 'display: none;',
));
$main_image_tag = javelin_tag(
$mock_wrapper = phutil_tag(
'div',
array(
'id' => 'mock-wrapper',
'sigil' => 'mock-wrapper',
'class' => 'pholio-mock-wrapper'
'id' => $viewport_id,
'class' => 'pholio-mock-image-viewport'
),
$main_image_tag);
'');
$mock_wrapper = javelin_tag(
'div',
array(
'id' => $panel_id,
'sigil' => 'mock-panel',
'class' => 'pholio-mock-image-panel',
),
$mock_wrapper);
$inline_comments_holder = javelin_tag(
'div',
@ -72,7 +72,7 @@ final class PholioMockImagesView extends AphrontView {
'class' => 'pholio-mock-image-container',
'id' => 'pholio-mock-image-container'
),
array($main_image_tag, $inline_comments_holder));
array($mock_wrapper, $inline_comments_holder));
if (count($mock->getImages()) > 1) {
$thumbnails = array();

View file

@ -38,7 +38,8 @@
}
.pholio-mock-image {
display: inline-block;
margin: auto;
cursor: crosshair;
}
.pholio-mock-select-border {
@ -55,12 +56,15 @@
box-sizing: border-box;
}
.pholio-mock-wrapper {
.pholio-mock-image-panel {
padding: 20px;
margin-right: 320px;
}
.pholio-mock-image-viewport {
position: relative;
margin: 20px 340px 20px 20px;
margin: auto;
display: inline-block;
cursor: crosshair;
padding: 0px;
}
.pholio-mock-inline-comments {

View file

@ -1,6 +1,7 @@
/**
* @provides javelin-behavior-pholio-mock-view
* @requires javelin-behavior
* javelin-util
* javelin-stratcom
* javelin-dom
* javelin-vector
@ -10,9 +11,10 @@
JX.behavior('pholio-mock-view', function(config) {
var is_dragging = false;
var wrapper = JX.$('mock-wrapper');
var drag_begin;
var drag_end;
var panel = JX.$(config.panelID);
var viewport = JX.$(config.viewportID);
var selection_border;
var selection_fill;
@ -29,16 +31,38 @@ JX.behavior('pholio-mock-view', function(config) {
return null;
}
function onload_image(id) {
if (active_image.id != id) {
// The user has clicked another image before this one loaded, so just
// bail.
return;
}
// If the image is too wide for the viewport, scale it down so it fits.
// (If it is too tall, we just let the user scroll.)
var w = JX.Vector.getDim(panel);
w.x -= 40;
if (w.x < this.naturalWidth) {
var scale = w.x / this.naturalWidth;
this.width = Math.floor(scale * this.naturalWidth);
this.height = Math.floor(scale * this.naturalHeight);
}
active_image.tag = this;
// NOTE: This also clears inline comment reticles.
JX.DOM.setContent(viewport, this);
redraw_inlines(active_image.id);
}
function select_image(image_id) {
var image = get_image(image_id);
active_image = image;
active_image = get_image(image_id);
active_image.tag = null;
var main = JX.$(config.mainID);
main.src = image.fullURI;
JX.DOM.show(main);
// NOTE: This is to clear inline comment reticles.
JX.DOM.setContent(wrapper, main);
var img = JX.$N('img', {className: 'pholio-mock-image'});
img.onload = JX.bind(img, onload_image, active_image.id);
img.src = active_image.fullURI;
load_inline_comments();
}
@ -54,7 +78,7 @@ JX.behavior('pholio-mock-view', function(config) {
// Select and show the first image.
select_image(config.images[0].id);
JX.Stratcom.listen('mousedown', 'mock-wrapper', function(e) {
JX.Stratcom.listen('mousedown', 'mock-panel', function(e) {
if (!e.isNormalMouseEvent()) {
return;
}
@ -111,8 +135,8 @@ JX.behavior('pholio-mock-view', function(config) {
var dialog = JX.$('pholio-new-inline-comment-dialog');
var wrapperVector = JX.$V(wrapper);
var wrapperDimensions = JX.Vector.getDim(wrapper);
var viewportVector = JX.$V(viewport);
var viewportDimensions = JX.Vector.getDim(viewport);
JX.$V(
// TODO: This is a little funky for now.
@ -145,6 +169,13 @@ JX.behavior('pholio-mock-view', function(config) {
for (var ii = 0; ii < inlines.length; ii++) {
var inline = inlines[ii];
JX.DOM.appendContent(comment_holder, JX.$H(inline.contentHTML));
if (!active_image.tag) {
// The image itself hasn't loaded yet, so we can't draw the inline
// reticles.
continue;
}
var inlineSelection = JX.$N(
'div',
@ -158,9 +189,8 @@ JX.behavior('pholio-mock-view', function(config) {
{phid: inline.phid});
JX.Stratcom.addSigil(inlineSelection, "image_selection");
JX.DOM.appendContent(comment_holder, JX.$H(inline.contentHTML));
JX.DOM.appendContent(wrapper, inlineSelection);
JX.DOM.appendContent(viewport, inlineSelection);
position_inline_rectangle(inline, inlineSelection);
@ -180,22 +210,26 @@ JX.behavior('pholio-mock-view', function(config) {
{phid: inline.phid});
JX.Stratcom.addSigil(inlineDraft, "image_selection");
JX.DOM.appendContent(wrapper, inlineDraft);
JX.DOM.appendContent(viewport, inlineDraft);
}
}
}
function position_inline_rectangle(inline, rect) {
JX.$V(inline.x, inline.y).setPos(rect);
JX.$V(inline.width, inline.height).setDim(rect);
var scale = active_image.tag.width / active_image.tag.naturalWidth;
JX.$V(scale * inline.x, scale * inline.y).setPos(rect);
JX.$V(scale * inline.width, scale * inline.height).setDim(rect);
}
function get_image_xy(p) {
var main = JX.$(config.mainID);
var mainp = JX.$V(main);
var img = active_image.tag;
var imgp = JX.$V(img);
var x = Math.max(0, Math.min(p.x - mainp.x, main.naturalWidth));
var y = Math.max(0, Math.min(p.y - mainp.y, main.naturalHeight));
var scale = 1 / get_image_scale();
var x = scale * Math.max(0, Math.min(p.x - imgp.x, img.width));
var y = scale * Math.max(0, Math.min(p.y - imgp.y, img.height));
return {
x: x,
@ -203,6 +237,11 @@ JX.behavior('pholio-mock-view', function(config) {
};
}
function get_image_scale() {
var img = active_image.tag;
return img.width / img.naturalWidth;
}
function redraw_selection() {
selection_border = selection_border || JX.$N(
'div',
@ -220,10 +259,17 @@ JX.behavior('pholio-mock-view', function(config) {
Math.max(drag_begin.x, drag_end.x) - p.x,
Math.max(drag_begin.y, drag_end.y) - p.y);
var scale = get_image_scale();
p.x *= scale;
p.y *= scale;
d.x *= scale;
d.y *= scale;
var nodes = [selection_border, selection_fill];
for (var ii = 0; ii < nodes.length; ii++) {
var node = nodes[ii];
wrapper.appendChild(node);
viewport.appendChild(node);
p.setPos(node);
d.setDim(node);
}
@ -393,4 +439,5 @@ JX.behavior('pholio-mock-view', function(config) {
}
load_inline_comments();
});