mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-26 00:32:42 +01:00
PHUIImageMask
Summary: Adds a PHUI class for display images on a center point, with or without a mask. Test Plan: I am bad a math, so like, check that for me please. I tested using Photoshop. Class may need tweaked depending how we store the inline-comment coords. {F167829} Reviewers: epriestley Reviewed By: epriestley Subscribers: epriestley, Korvin Differential Revision: https://secure.phabricator.com/D9614
This commit is contained in:
parent
47964077ef
commit
ca801c7ad4
10 changed files with 283 additions and 12 deletions
|
@ -81,7 +81,7 @@ return array(
|
|||
'rsrc/css/application/phame/phame.css' => '19ecc703',
|
||||
'rsrc/css/application/pholio/pholio-edit.css' => '3ad9d1ee',
|
||||
'rsrc/css/application/pholio/pholio-inline-comments.css' => '95004a57',
|
||||
'rsrc/css/application/pholio/pholio.css' => '6f87390f',
|
||||
'rsrc/css/application/pholio/pholio.css' => 'd0502625',
|
||||
'rsrc/css/application/phortune/phortune-credit-card-form.css' => 'b25b4beb',
|
||||
'rsrc/css/application/phrequent/phrequent.css' => 'ffc185ad',
|
||||
'rsrc/css/application/phriction/phriction-document-css.css' => '7d7f0071',
|
||||
|
@ -131,6 +131,7 @@ return array(
|
|||
'rsrc/css/phui/phui-form.css' => 'b78ec020',
|
||||
'rsrc/css/phui/phui-header-view.css' => 'a2071a67',
|
||||
'rsrc/css/phui/phui-icon.css' => 'd8526aa1',
|
||||
'rsrc/css/phui/phui-image-mask.css' => '5f4a6d5d',
|
||||
'rsrc/css/phui/phui-info-panel.css' => '27ea50a1',
|
||||
'rsrc/css/phui/phui-list.css' => '43ed2d93',
|
||||
'rsrc/css/phui/phui-object-box.css' => 'ce92d8ec',
|
||||
|
@ -230,6 +231,7 @@ return array(
|
|||
'rsrc/image/credit_cards.png' => '72b8ede8',
|
||||
'rsrc/image/darkload.gif' => '1ffd3ec6',
|
||||
'rsrc/image/divot.png' => '94dded62',
|
||||
'rsrc/image/examples/hero.png' => '979a86ae',
|
||||
'rsrc/image/grippy_texture.png' => 'aca81e2f',
|
||||
'rsrc/image/icon/fatcow/arrow_branch.png' => '2537c01c',
|
||||
'rsrc/image/icon/fatcow/arrow_merge.png' => '21b660e0',
|
||||
|
@ -750,7 +752,7 @@ return array(
|
|||
'phabricator-uiexample-reactor-sendproperties' => '551add57',
|
||||
'phabricator-zindex-css' => 'efb673ac',
|
||||
'phame-css' => '19ecc703',
|
||||
'pholio-css' => '6f87390f',
|
||||
'pholio-css' => 'd0502625',
|
||||
'pholio-edit-css' => '3ad9d1ee',
|
||||
'pholio-inline-comments-css' => '95004a57',
|
||||
'phortune-credit-card-form' => '2290aeef',
|
||||
|
@ -771,6 +773,7 @@ return array(
|
|||
'phui-form-view-css' => 'ed856191',
|
||||
'phui-header-view-css' => 'a2071a67',
|
||||
'phui-icon-view-css' => 'd8526aa1',
|
||||
'phui-image-mask-css' => '5f4a6d5d',
|
||||
'phui-info-panel-css' => '27ea50a1',
|
||||
'phui-list-view-css' => '43ed2d93',
|
||||
'phui-object-box-css' => 'ce92d8ec',
|
||||
|
|
|
@ -1026,6 +1026,8 @@ phutil_register_library_map(array(
|
|||
'PHUIHeaderView' => 'view/phui/PHUIHeaderView.php',
|
||||
'PHUIIconExample' => 'applications/uiexample/examples/PHUIIconExample.php',
|
||||
'PHUIIconView' => 'view/phui/PHUIIconView.php',
|
||||
'PHUIImageMaskExample' => 'applications/uiexample/examples/PHUIImageMaskExample.php',
|
||||
'PHUIImageMaskView' => 'view/phui/PHUIImageMaskView.php',
|
||||
'PHUIInfoPanelExample' => 'applications/uiexample/examples/PHUIInfoPanelExample.php',
|
||||
'PHUIInfoPanelView' => 'view/phui/PHUIInfoPanelView.php',
|
||||
'PHUIListExample' => 'applications/uiexample/examples/PHUIListExample.php',
|
||||
|
@ -3793,6 +3795,8 @@ phutil_register_library_map(array(
|
|||
'PHUIHeaderView' => 'AphrontView',
|
||||
'PHUIIconExample' => 'PhabricatorUIExample',
|
||||
'PHUIIconView' => 'AphrontTagView',
|
||||
'PHUIImageMaskExample' => 'PhabricatorUIExample',
|
||||
'PHUIImageMaskView' => 'AphrontTagView',
|
||||
'PHUIInfoPanelExample' => 'PhabricatorUIExample',
|
||||
'PHUIInfoPanelView' => 'AphrontView',
|
||||
'PHUIListExample' => 'PhabricatorUIExample',
|
||||
|
|
|
@ -100,6 +100,7 @@ final class PholioMockViewController extends PholioController {
|
|||
|
||||
$xaction_view = id(new PholioTransactionView())
|
||||
->setUser($this->getRequest()->getUser())
|
||||
->setMock($mock)
|
||||
->setObjectPHID($mock->getPHID())
|
||||
->setTransactions($xactions)
|
||||
->setMarkupEngine($engine);
|
||||
|
|
|
@ -6,6 +6,17 @@
|
|||
final class PholioTransactionView
|
||||
extends PhabricatorApplicationTransactionView {
|
||||
|
||||
private $mock;
|
||||
|
||||
public function setMock($mock) {
|
||||
$this->mock = $mock;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getMock() {
|
||||
return $this->mock;
|
||||
}
|
||||
|
||||
protected function shouldGroupTransactions(
|
||||
PhabricatorApplicationTransaction $u,
|
||||
PhabricatorApplicationTransaction $v) {
|
||||
|
@ -87,12 +98,31 @@ final class PholioTransactionView
|
|||
|
||||
private function renderInlineContent(PholioTransaction $inline) {
|
||||
$comment = $inline->getComment();
|
||||
$mock = $this->getMock();
|
||||
$images = $mock->getAllImages();
|
||||
$images = mpull($images, null, 'getID');
|
||||
|
||||
$thumb = phutil_tag(
|
||||
'img',
|
||||
array(
|
||||
'src' => '/pholio/inline/thumb/'.$comment->getImageID(),
|
||||
));
|
||||
$image = idx($images, $comment->getImageID());
|
||||
if (!$image) {
|
||||
throw new Exception('No image attached!');
|
||||
}
|
||||
|
||||
$file = $image->getFile();
|
||||
if (!$file->isViewableImage()) {
|
||||
throw new Exception('File is not viewable.');
|
||||
}
|
||||
|
||||
$image_uri = $file->getBestURI();
|
||||
|
||||
$thumb = id(new PHUIImageMaskView())
|
||||
->addClass('mrl')
|
||||
->setImage($image_uri)
|
||||
->setDisplayHeight(100)
|
||||
->setDisplayWidth(200)
|
||||
->withMask(true)
|
||||
->centerViewOnPoint(
|
||||
$comment->getX(), $comment->getY(),
|
||||
$comment->getHeight(), $comment->getWidth());
|
||||
|
||||
$link = phutil_tag(
|
||||
'a',
|
||||
|
|
|
@ -114,5 +114,5 @@ final class PHUIBoxExample extends PhabricatorUIExample {
|
|||
$head4,
|
||||
$obj4,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
88
src/applications/uiexample/examples/PHUIImageMaskExample.php
Normal file
88
src/applications/uiexample/examples/PHUIImageMaskExample.php
Normal file
|
@ -0,0 +1,88 @@
|
|||
<?php
|
||||
|
||||
final class PHUIImageMaskExample extends PhabricatorUIExample {
|
||||
|
||||
public function getName() {
|
||||
return 'Image Masks';
|
||||
}
|
||||
|
||||
public function getDescription() {
|
||||
return 'Display images with crops.';
|
||||
}
|
||||
|
||||
public function renderExample() {
|
||||
|
||||
$image = celerity_get_resource_uri('/rsrc/image/examples/hero.png');
|
||||
$display_height = 100;
|
||||
$display_width = 200;
|
||||
|
||||
$mask1 = id(new PHUIImageMaskView())
|
||||
->addClass('ml')
|
||||
->setImage($image)
|
||||
->setDisplayHeight($display_height)
|
||||
->setDisplayWidth($display_width)
|
||||
->centerViewOnPoint(265, 185, 30, 140);
|
||||
|
||||
$mask2 = id(new PHUIImageMaskView())
|
||||
->addClass('ml')
|
||||
->setImage($image)
|
||||
->setDisplayHeight($display_height)
|
||||
->setDisplayWidth($display_width)
|
||||
->centerViewOnPoint(18, 18, 40, 80);
|
||||
|
||||
$mask3 = id(new PHUIImageMaskView())
|
||||
->addClass('ml')
|
||||
->setImage($image)
|
||||
->setDisplayHeight($display_height)
|
||||
->setDisplayWidth($display_width)
|
||||
->centerViewOnPoint(265, 185, 30, 140)
|
||||
->withMask(true);
|
||||
|
||||
$mask4 = id(new PHUIImageMaskView())
|
||||
->addClass('ml')
|
||||
->setImage($image)
|
||||
->setDisplayHeight($display_height)
|
||||
->setDisplayWidth($display_width)
|
||||
->centerViewOnPoint(18, 18, 40, 80)
|
||||
->withMask(true);
|
||||
|
||||
$mask5 = id(new PHUIImageMaskView())
|
||||
->addClass('ml')
|
||||
->setImage($image)
|
||||
->setDisplayHeight($display_height)
|
||||
->setDisplayWidth($display_width)
|
||||
->centerViewOnPoint(254, 272, 60, 240)
|
||||
->withMask(true);
|
||||
|
||||
$box1 = id(new PHUIObjectBoxView())
|
||||
->setHeaderText(pht('Center is in the middle'))
|
||||
->appendChild($mask1);
|
||||
|
||||
$box2 = id(new PHUIObjectBoxView())
|
||||
->setHeaderText(pht('Center is on an edge'))
|
||||
->appendChild($mask2);
|
||||
|
||||
$box3 = id(new PHUIObjectBoxView())
|
||||
->setHeaderText(pht('Center Masked'))
|
||||
->appendChild($mask3);
|
||||
|
||||
$box4 = id(new PHUIObjectBoxView())
|
||||
->setHeaderText(pht('Edge Masked'))
|
||||
->appendChild($mask4);
|
||||
|
||||
$box5 = id(new PHUIObjectBoxView())
|
||||
->setHeaderText(pht('Wide Masked'))
|
||||
->appendChild($mask5);
|
||||
|
||||
return phutil_tag(
|
||||
'div',
|
||||
array(),
|
||||
array(
|
||||
$box1,
|
||||
$box2,
|
||||
$box3,
|
||||
$box4,
|
||||
$box5
|
||||
));
|
||||
}
|
||||
}
|
116
src/view/phui/PHUIImageMaskView.php
Normal file
116
src/view/phui/PHUIImageMaskView.php
Normal file
|
@ -0,0 +1,116 @@
|
|||
<?php
|
||||
|
||||
final class PHUIImageMaskView extends AphrontTagView {
|
||||
|
||||
private $image;
|
||||
private $withMask;
|
||||
|
||||
private $displayWidth;
|
||||
private $displayHeight;
|
||||
|
||||
private $centerX;
|
||||
private $centerY;
|
||||
private $maskH;
|
||||
private $maskW;
|
||||
|
||||
public function setImage($image) {
|
||||
$this->image = $image;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setDisplayWidth($width) {
|
||||
$this->displayWidth = $width;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setDisplayHeight($height) {
|
||||
$this->displayHeight = $height;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function centerViewOnPoint($x, $y, $h, $w) {
|
||||
$this->centerX = $x;
|
||||
$this->centerY = $y;
|
||||
$this->maskH = $h;
|
||||
$this->maskW = $w;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withMask($mask) {
|
||||
$this->withMask = $mask;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getTagName() {
|
||||
return 'div';
|
||||
}
|
||||
|
||||
public function getTagAttributes() {
|
||||
require_celerity_resource('phui-image-mask-css');
|
||||
|
||||
$classes = array();
|
||||
$classes[] = 'phui-image-mask';
|
||||
|
||||
$styles = array();
|
||||
$styles[] = 'height: '.$this->displayHeight.'px;';
|
||||
$styles[] = 'width: '.$this->displayWidth.'px;';
|
||||
|
||||
return array(
|
||||
'class' => implode(' ', $classes),
|
||||
'styles' => implode(' ', $styles),
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
public function getTagContent() {
|
||||
|
||||
/* Center it in the middle of the selected area */
|
||||
$center_x = round($this->centerX + ($this->maskW / 2));
|
||||
$center_y = round($this->centerY + ($this->maskH / 2));
|
||||
$center_x = round($center_x - ($this->displayWidth / 2));
|
||||
$center_y = round($center_y - ($this->displayHeight / 2));
|
||||
|
||||
$center_x = -$center_x;
|
||||
$center_y = -$center_y;
|
||||
|
||||
$classes = array();
|
||||
$classes[] = 'phui-image-mask-image';
|
||||
|
||||
$styles = array();
|
||||
$styles[] = 'height: '.$this->displayHeight.'px;';
|
||||
$styles[] = 'width: '.$this->displayWidth.'px;';
|
||||
$styles[] = 'background-image: url('.$this->image.');';
|
||||
$styles[] = 'background-position: '.$center_x.'px '.$center_y.'px;';
|
||||
|
||||
$mask = null;
|
||||
if ($this->withMask) {
|
||||
/* The mask is a 300px border around a transparent box.
|
||||
so we do the math here to position the box correctly. */
|
||||
$border = 300;
|
||||
$left = round((($this->displayWidth - $this->maskW) / 2) - $border);
|
||||
$top = round((($this->displayHeight - $this->maskH) / 2) - $border);
|
||||
|
||||
$mstyles = array();
|
||||
$mstyles[] = 'left: '.$left.'px;';
|
||||
$mstyles[] = 'top: '.$top.'px;';
|
||||
$mstyles[] = 'height: '.$this->maskH.'px;';
|
||||
$mstyles[] = 'width: '.$this->maskW.'px;';
|
||||
|
||||
$mask = phutil_tag(
|
||||
'span',
|
||||
array(
|
||||
'class' => 'phui-image-mask-mask',
|
||||
'style' => implode(' ', $mstyles),
|
||||
),
|
||||
null);
|
||||
}
|
||||
|
||||
return phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => implode(' ', $classes),
|
||||
'style' => implode(' ', $styles),
|
||||
),
|
||||
$mask);
|
||||
}
|
||||
}
|
|
@ -99,19 +99,21 @@
|
|||
|
||||
.pholio-transaction-inline-comment .transaction-comment {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
vertical-align: top;
|
||||
padding-left: 8px;
|
||||
padding-top: 4px;
|
||||
}
|
||||
|
||||
.pholio-mock-reticle {
|
||||
position: absolute;
|
||||
display: none;
|
||||
box-sizing: border-box;
|
||||
border: 4px solid transparent;
|
||||
}
|
||||
|
||||
.pholio-mock-reticle-selection {
|
||||
background-color: rgba(255, 255, 255, 0.50);
|
||||
border: 1px dashed #000;
|
||||
border: 1px solid rgba(0,0,0,.5);
|
||||
box-shadow: 0 0 0 4px rgba(255,255,255,.5);
|
||||
}
|
||||
|
||||
.pholio-mock-reticle-draft {
|
||||
|
@ -130,8 +132,12 @@
|
|||
|
||||
.pholio-mock-reticle-draft:hover,
|
||||
.pholio-mock-reticle-final:hover {
|
||||
background-color: rgba(255, 255, 255, 0.50);
|
||||
border: 1px solid rgba(0,0,0,.5);
|
||||
box-shadow: 0 0 0 4px rgba(255,255,255,.5);
|
||||
cursor: pointer;
|
||||
color: transparent;
|
||||
text-shadow: none;
|
||||
-webkit-text-stroke: 0;
|
||||
}
|
||||
|
||||
.device-desktop .mock-has-cursor .pholio-mock-reticle {
|
||||
|
|
23
webroot/rsrc/css/phui/phui-image-mask.css
Normal file
23
webroot/rsrc/css/phui/phui-image-mask.css
Normal file
|
@ -0,0 +1,23 @@
|
|||
/**
|
||||
* @provides phui-image-mask-css
|
||||
*/
|
||||
|
||||
|
||||
.phui-image-mask {
|
||||
background: url('/rsrc/image/checker_lighter.png');
|
||||
display: inline-block;
|
||||
border: 1px solid {$lightblueborder};
|
||||
padding: 4px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.phui-image-mask-image {
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.phui-image-mask-mask {
|
||||
border: 300px solid rgba(0, 0, 0, 0.5);
|
||||
background-clip: content-box;
|
||||
position: absolute;
|
||||
}
|
BIN
webroot/rsrc/image/examples/hero.png
Normal file
BIN
webroot/rsrc/image/examples/hero.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 215 KiB |
Loading…
Reference in a new issue