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:
parent
8641ef3948
commit
26f8e76ee2
5 changed files with 109 additions and 56 deletions
7
externals/javelinjs/src/core/Event.js
vendored
7
externals/javelinjs/src/core/Event.js
vendored
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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();
|
||||
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue