Enable rotation of molecules

This commit is contained in:
Saul Johnson
2020-05-16 14:39:42 +01:00
parent a45f4dc0df
commit 2e16e0ad15
7 changed files with 1261 additions and 34 deletions
+26
View File
@@ -19,6 +19,8 @@ class MoleculeRenderer
private $customLabel;
private $rotation;
/**
* Initializes a new instance of a molecule rendering service.
*
@@ -60,6 +62,7 @@ class MoleculeRenderer
list($r, $g, $b) = sscanf($color, "%02x%02x%02x");
$unit = 100 / 255;
$img->colorize($unit * $r, $unit * $g, $unit * $b);
$img->rotate($this->rotation);
return $img; // Return molecule image.
}
@@ -72,6 +75,7 @@ class MoleculeRenderer
* @param int $canvasWidth the width of the canvas to scale the molecule to
* @param int $canvasHeight the height of the canvas to scale the molecule to
* @param float $proportion the maximum proportion of the canvas the molecule should occupy (in either direction)
* @param float $rotation the angle to rotate the image by
* @return \Intervention\Image\Image
*/
public function renderScaledMolecule($smiles, $color, $canvasWidth, $canvasHeight, $proportion = 0.8)
@@ -165,4 +169,26 @@ class MoleculeRenderer
$this->customLabel = $customLabel;
return $this;
}
/**
* Gets the angle of rotation to apply to the molecule.
*
* @return float
*/
public function getRotation()
{
return $this->rotation;
}
/**
* Sets the angle of rotation to apply to the molecule.
*
* @param float $rotation the angle of rotation to apply
* @return MoleculeRenderer
*/
public function setRotation($rotation)
{
$this->rotation = $rotation;
return $this;
}
}
+35 -13
View File
@@ -7,6 +7,9 @@ $(document).ready ->
foregroundColor = 'ce3838'
backgroundColor = '5f0000'
# Transforms.
rotation = 0
# Custom label for molecule.
customLabel = ''
@@ -58,8 +61,10 @@ $(document).ready ->
#
buildUrl = (width, height, foreground, background, name) ->
url = "/api/name/#{width}/#{height}/#{background}/#{foreground}/#{name}"
if customLabel != '' then url += "?label=#{customLabel}"
return url
qs = ""
if customLabel != '' then qs += "label=#{customLabel}"
if rotation != 0 then qs += "rotation=#{rotation}"
return if qs == "" then url else url + "?" + qs
# Builds a URL to generate a molecule-only image from a compound name.
#
@@ -70,8 +75,10 @@ $(document).ready ->
#
buildMoleculeOnlyUrl = (width, height, foreground, name) ->
url = "/api/name/#{width}/#{height}/#{foreground}/#{name}"
if customLabel != '' then url += "?label=#{customLabel}"
return url
qs = ""
if customLabel != '' then qs += "label=#{customLabel}"
if rotation != 0 then qs += "rotation=#{rotation}"
return if qs == "" then url else url + "?" + qs
# Builds a URL to generate a wallpaper image from a SMILES structure.
#
@@ -83,8 +90,10 @@ $(document).ready ->
#
buildSmilesUrl = (width, height, foreground, background, smiles) ->
url = "/api/smiles/#{width}/#{height}/#{background}/#{foreground}/#{smiles}"
if customLabel != '' then url += "?label=#{customLabel}"
return url
qs = ""
if customLabel != '' then qs += "label=#{customLabel}"
if rotation != 0 then qs += "rotation=#{rotation}"
return if qs == "" then url else url + "?" + qs
# Builds a URL to generate a molecule-only image from a SMILES structure.
#
@@ -95,8 +104,10 @@ $(document).ready ->
#
buildSmilesMoleculeOnlyUrl = (width, height, foreground, smiles) ->
url = "/api/smiles/#{width}/#{height}/#{foreground}/#{smiles}"
if customLabel != '' then url += "?label=#{customLabel}"
return url
qs = ""
if customLabel != '' then qs += "label=#{customLabel}"
if rotation != 0 then qs += "rotation=#{rotation}"
return if qs == "" then url else url + "?" + qs
# Checks if a compound name can be converted to SMILES using the configured database.
#
@@ -153,7 +164,8 @@ $(document).ready ->
params = {
'label': customLabel,
'background': backgroundColor,
'foreground': foregroundColor
'foreground': foregroundColor,
'rotation': rotation
}
if smilesMode
params['smiles'] = currentCompoundSmiles
@@ -180,16 +192,16 @@ $(document).ready ->
refreshPreviewCompoundName = ->
currentCompoundName = getCompoundName()
smilesMode = false
url = buildMoleculeOnlyUrl screenWidth, screenHeight, foregroundColor, currentCompoundName
updatePreview previewElement, url, backgroundColor
url = buildMoleculeOnlyUrl screenWidth, screenHeight, foregroundColor, currentCompoundName, rotation
updatePreview previewElement, url, backgroundColor, rotation
# Refreshes the preview using the SMILES structure text box.
#
refreshPreviewSmiles = ->
currentCompoundSmiles = getCompoundSmiles()
smilesMode = true
url = buildSmilesMoleculeOnlyUrl screenWidth, screenHeight, foregroundColor, currentCompoundSmiles
updatePreview previewElement, url, backgroundColor
url = buildSmilesMoleculeOnlyUrl screenWidth, screenHeight, foregroundColor, currentCompoundSmiles, rotation
updatePreview previewElement, url, backgroundColor, rotation
# Refreshes the preview using the compound name or SMILES structure text box depending on mode.
#
@@ -267,5 +279,15 @@ $(document).ready ->
currentCompoundSmiles = smilesTextBox.val()
customLabel = customLabelTextBox.val()
window.knobListener = (k, v) ->
rotation = v
modeAwareRefreshPreview()
initRotationKnob()
passedRotation = getParameterByName 'rotation'
if passedRotation != null
rotationKnob.setValue(passedRotation)
rotation = rotationKnob.getValue()
# Initial update.
modeAwareRefreshPreview()
+28
View File
@@ -0,0 +1,28 @@
###
* Demo code for knob element.
###
initRotationKnob = ->
# Create knob element, 300 x 300 px in size.
knob = pureknob.createKnob(88, 88)
# Set properties.
knob.setProperty 'angleStart', 0
knob.setProperty 'angleEnd', Math.PI * 2
knob.setProperty 'colorFG', '#C0C0C0'
knob.setProperty 'colorBG', '#505050'
knob.setProperty 'trackWidth', 0.4
knob.setProperty 'valMin', 0
knob.setProperty 'valMax', 359
knob.setProperty 'needle', true
# Set initial value.
knob.setValue 0
knob.addListener window.knobListener
# Create element node.
node = knob.node()
# Add it to the DOM.
elem = document.getElementById('rotation_knob')
elem.appendChild node
window.rotationKnob = knob
window.initRotationKnob = initRotationKnob
+1 -1
View File
@@ -28,7 +28,7 @@
@picker-border: #444;
// Width variables.
@sidebar-width: 250px;
@sidebar-width: 400px;
@width2: 100px;
@full-width: 100%;
+18 -2
View File
@@ -34,6 +34,8 @@
<script type="text/javascript" src="/js/params.js"></script>
<script type="text/javascript" src="/js/hamburger.js"></script>
<script type="text/javascript" src="/js/main.js"></script>
<script type="text/javascript" src="/js-lib/pureknob.js"></script>
<script type="text/javascript" src="/js/rotationknob.js"></script>
{% include "_analytics.html.twig" %}
</head>
<body>
@@ -110,11 +112,13 @@
<div class="tool-section mtop-10">
<div class="row">
<div class="col-xs-12">
<div class="section-lbl">Colours</div>
<div class="section-lbl">Colors and Rotation</div>
<hr>
</div>
</div>
<div class="row mtop-10">
<div class="col-xs-7">
<div class="row">
<div class="col-xs-6">
<div class="picker-lbl">Molecule:</div>
</div>
@@ -122,7 +126,7 @@
<input type="text" class="picker picker-fg">
</div>
</div>
<div class="row mtop-10">
<div class="row">
<div class="col-xs-6">
<div class="picker-lbl">Background:</div>
</div>
@@ -131,6 +135,18 @@
</div>
</div>
</div>
<div class="col-xs-5">
<div id="rotation_knob"></div>
</div>
</div>
</div>
<div class="tool-section mtop-10">
<div class="row mtop-10">
<div class="col-xs-6">
<div id="rotation_knob"></div>
</div>
</div>
</div>
<div class="tool-section mtop-10">
<div class="row">
<div class="col-xs-12">
+13 -1
View File
@@ -14,7 +14,7 @@ use Avogadrio\MoleculeRenderer;
$app = new Silex\Application();
// Uncomment the line below while debugging your app.
// $app['debug'] = true;
$app['debug'] = true;
// Load config.
$config = Spyc::YAMLLoad(__DIR__ . '/../config/config.yaml');
@@ -52,6 +52,9 @@ $app->get('/api/smiles/{width}/{height}/{background}/{foreground}/{smiles}',
// Add label.
$moleculeRenderer->setCustomLabel($request->get('label'));
// Add rotation.
$moleculeRenderer->setRotation((float) $request->get('rotation'));
// Render molecule with background.
$image = $moleculeRenderer->renderMoleculeWithBackground($smiles, $foreground, $background, $width, $height);
@@ -68,6 +71,9 @@ $app->get('/api/smiles/{width}/{height}/{color}/{smiles}',
// Add label.
$moleculeRenderer->setCustomLabel($request->get('label'));
// Add rotation.
$moleculeRenderer->setRotation((float) $request->get('rotation'));
// Render molecule only.
$image = $moleculeRenderer->renderScaledMolecule($smiles, $color, $width, $height);
@@ -90,6 +96,9 @@ $app->get('/api/name/{width}/{height}/{background}/{foreground}/{name}',
// Add label.
$moleculeRenderer->setCustomLabel($request->get('label'));
// Add rotation.
$moleculeRenderer->setRotation((float) $request->get('rotation'));
// Render molecule with background.
$image = $moleculeRenderer->renderMoleculeWithBackground($smiles, $foreground, $background, $width, $height);
@@ -116,6 +125,9 @@ $app->get('/api/name/{width}/{height}/{color}/{name}',
// Add label.
$moleculeRenderer->setCustomLabel($request->get('label'));
// Add rotation.
$moleculeRenderer->setRotation((float) $request->get('rotation'));
// Render molecule only.
$image = $moleculeRenderer->renderScaledMolecule($smiles, $color, $width, $height);
File diff suppressed because it is too large Load Diff