I am using QuaggaJs to scan the barcode. Everything is good and smooth for desktop version of scanner. But it gets broken when coming to mobile version of website and that too mainly on iPhone.
I tested in both safari and Chrome and for different phone it behaves differently. For some phone camera gets hang and for some camera didn't start at all.
Also, the canvas size is not setting up in the parent div. camera is getting outside the DOM.
Here is what I did.
HTML
<div class="scanner-box">
<div id="scanner-container" class="main_scanner"></div>
</div>
JS
$(document).ready(function(){
if($(".scanner-box").length > 0){
var canvas_width = $(".scanner-box").width();
var canvas_height = $(".scanner-box").height();
if (_scannerIsRunning) {
Quagga.stop();
} else {
startScanner(canvas_width,canvas_height);
}
}
}
var _scannerIsRunning = false;
function startScanner(canvasRatio,canvasHeight) {
Quagga.init({
inputStream: {
name: "Live",
type: "LiveStream",
target: document.querySelector('#scanner-container'),
constraints: {
width: "100%",
height: "100%",
facingMode: "environment"
},
},
decoder: {
readers: [
"ean_reader",
"ean_8_reader"
],
debug: {
showCanvas: true,
showPatches: true,
showFoundPatches: true,
showSkeleton: true,
showLabels: true,
showPatchLabels: true,
showRemainingPatchLabels: true,
boxFromPatches: {
showTransformed: true,
showTransformedBox: true,
showBB: true
}
}
},
},
function (err) {
if (err) {
$("#error").text(err);
return
}
console.log("Initialization finished. Ready to start");
Quagga.start();
_scannerIsRunning = true;
});
Quagga.onProcessed(function (result) {
var drawingCtx = Quagga.canvas.ctx.overlay,
drawingCanvas = Quagga.canvas.dom.overlay;
if (result) {
if (result.boxes) {
drawingCtx.clearRect(0, 0, parseInt(drawingCanvas.getAttribute("width")), parseInt(drawingCanvas.getAttribute("height")));
result.boxes.filter(function (box) {
return box !== result.box;
}).forEach(function (box) {
Quagga.ImageDebug.drawPath(box, { x: 0, y: 1 }, drawingCtx, { color: "green", lineWidth: 2 });
});
}
if (result.box) {
Quagga.ImageDebug.drawPath(result.box, { x: 0, y: 1 }, drawingCtx, { color: "#00F", lineWidth: 2 });
}
if (result.codeResult && result.codeResult.code) {
Quagga.ImageDebug.drawPath(result.line, { x: 'x', y: 'y' }, drawingCtx, { color: 'red', lineWidth: 3 });
}
}
});
Quagga.onDetected(function (result) {
var barcodeResult = $("#result").text(result.codeResult.code);
var barcode = result.codeResult.code;
if(barcode.toString().length < '13'){
}else{
checkBarCode(barcode,canvasRatio,canvasHeight);
if (_scannerIsRunning) {
Quagga.stop();
}
}
console.log("Barcode detected and processed : [" + result.codeResult.code + "]", result);
});
}
CSS
.scanner-box{width:480px;height:320px;background-color:#9a9a9a;position:relative;margin-top:10px;}
#scanner-container{position:relative;height:inherit;}
#scanner-container canvas{
position: absolute;
left : 0px;
top: 0px;
}
this css is just like the sample form https://serratus.github.io/quaggaJS/v1.0.0-beta.1/examples/file_input/
it makes the canvas area which draws windows cover the camera steam area .
Related
I'm trying to create a snake game in Phaser 3. The arrow.(key).isDown is acting strangely and I can't figure out why. If you press a key weather it is up, down, left or right it will not change directions if you press the opposite, it just keeps moving. like if I press down it keeps going down even after I press up. I have been trying to debug it for hours. All the examples pretty much have it set up the same way.
This is my code so far
class mainScene {
preload() {
this.load.image("fruit", "images/fruit.png");
this.load.image("snake", "images/snake.png");
}
create() {
this.score = 0;
this.snake = this.physics.add.sprite(20, 20, "snake");
this.fruit = this.physics.add.sprite(
Phaser.Math.Between(10, 590),
Phaser.Math.Between(10, 590),
"fruit"
);
this.scoreText = this.add.text(500, 5, `Score: ${this.score}`);
this.arrow = this.input.keyboard.createCursorKeys();
//debug
}
update() {
if (this.physics.overlap(this.snake, this.fruit)) {
this.hit();
}
this.snake.setVelocity(0);
if (this.arrow.right.isDown) {
this.snake.setVelocityX(50);
if (this.snake.x > 600) {
this.outOfBounds();
}
} else if (this.arrow.left.isDown) {
this.snake.setVelocityX(-50);
if (this.snake.x < 0) {
this.outOfBounds();
}
}
if (this.arrow.down.isDown) {
this.snake.setVelocityY(50);
if (this.snake.y > 600) {
this.outOfBounds();
}
} else if (this.arrow.up.isDown) {
this.snake.setVelocityY(-50);
if (this.snake.y < 0) {
this.outOfBounds();
}
}
}
hit() {
this.fruit.x = Phaser.Math.Between(10, 590);
this.fruit.y = Phaser.Math.Between(10, 590);
this.score += 1;
this.scoreText.setText(`Score: ${this.score}`);
this.tweens.add({
targets: this.snake,
duration: 200,
scaleX: 1.2,
scaleY: 1.2,
yoyo: true,
});
}
outOfBounds() {
this.score = 0;
this.scoreText.setText(`Score: ${this.score}`);
this.gameOverText = this.add.text(
100,
250,
"You went out of bounds.\nGame Over\nPress Space to continue.",
{ fontSize: "24px" }
);
if (this.arrow.space.isDown) {
this.gameOverText.destroy();
this.scene.restart();
}
}
}
const config = {
type: Phaser.CANVAS,
width: 600,
height: 600,
backgroundColor: 0x000040,
scene: mainScene,
physics: {
default: "arcade",
debug: true,
setBounds: { x: 0, y: 0, width: 600, height: 600 },
},
parent: "game",
};
new Phaser.Game(config);
NET MVC Core and I am trying to use Particles.js. I have already tried referencing a few tutorials, but am unable to solve this issue. This is how it normally looks like. https://vincentgarreau.com/particles.js/#default
I got this however, with big and super laggy buttons and also it does not occupy full screen nor does it have the hover action (whereby the circle moves away as the mouse approaches). The onclick circle works though. And the configuration shouldn't be wrong, as I downloaded the default one.
Update: Just before posting I managed to make it full screen. However, the big buttons and lagginess remains.
The following is my codes so far. I tried to search the id or class but due to the lack of documentation it is quite hard to find. Hope someone who knows it can help! Thank you very much :)
#{
ViewData["Title"] = "Home Page";
}
<div id="particles-js" style="background-color: rgb(0, 0, 0); background-image: url(""); background-size: cover; background-repeat: no-repeat; ba">
<canvas class="particles-js-canvas-el" style="width: 100%; height: 100%;"></canvas>
</div>
<script src="~/js/particles.js" data-turbolinks-track="reload" asp-append-version="true"></script>
<script>
particlesJS("particles-js", {
particles: {
number: {
value: 400,
density: {
enable: true,
value_area: 800
}
},
color: {
value: '#fff'
},
shape: {
type: 'circle',
stroke: {
width: 0,
color: '#ff0000'
},
polygon: {
nb_sides: 5
},
image: {
src: '',
width: 100,
height: 100
}
},
opacity: {
value: 1,
random: false,
anim: {
enable: false,
speed: 2,
opacity_min: 0,
sync: false
}
},
size: {
value: 20,
random: false,
anim: {
enable: false,
speed: 20,
size_min: 0,
sync: false
}
},
line_linked: {
enable: true,
distance: 100,
color: '#fff',
opacity: 1,
width: 1
},
move: {
enable: true,
speed: 2,
direction: 'none',
random: false,
straight: false,
out_mode: 'out',
bounce: false,
attract: {
enable: false,
rotateX: 3000,
rotateY: 3000
}
},
array: []
},
interactivity: {
detect_on: 'canvas',
events: {
onhover: {
enable: true,
mode: 'grab'
},
onclick: {
enable: true,
mode: 'push'
},
resize: true
},
modes: {
grab: {
distance: 100,
line_linked: {
opacity: 1
}
},
bubble: {
distance: 200,
size: 80,
duration: 0.4
},
repulse: {
distance: 200,
duration: 0.4
},
push: {
particles_nb: 4
},
remove: {
particles_nb: 2
}
},
mouse: {}
},
retina_detect: false,
});
//var count_particles, stats, update;
//stats = new Stats;
//stats.setMode(0);
//stats.domElement.style.position = 'absolute';
//stats.domElement.style.left = '0px';
//stats.domElement.style.top = '0px';
//document.body.appendChild(stats.domElement);
//count_particles = document.querySelector('.js-count-particles');
//update = function () {
// stats.begin();
// stats.end();
// if (window.pJSDom[0].pJS.particles && window.pJSDom[0].pJS.particles.array) {
// count_particles.innerText = window.pJSDom[0].pJS.particles.array.length;
// }
// requestAnimationFrame(update);
//};
//requestAnimationFrame(update);;
</script>
Update: I finally found the answer. To facilitate people who working on this in the future, make sure to use the download from the sidebar and not the one in the center.
Not this (the download in the center):
But this (the one at the bottom right side, "Download current config(json)"):
I am using the below code -
afterListeners: function(thisEl, eOpts) {
sliderSprite = Ext.create('Ext.draw.sprite.Rect', {
width: spriteWidth, // half year width height : 20, x : 16, y : 0, draggable : true, floatable : true, 'stroke-width' : 2, fill : '#FCE5C5', stroke : '#C6B395' });
sliderSprite.show(true);
thisEl.getSurface().add(sliderSprite);
alert("before source");
new Ext.drag.Source({
element: sliderSprite,
constrain: {
// Drag only horizontal in 30px increments
horizontal: true, // snap: { // y: 30 // }
},
onDragMove: function() {
alert("inside source");
spriteHighlighter.remove();
me.onDragSprite(e, this, chartWidth, spriteWidth);
},
onDragEnd: function() {
me.refreshCharts(xPlots, bigChart, sliderSprite, firstYear, lastYear, chartWidth);
}
});
alert("outside source");
},
}
}
Now, the issue is, control doesn't go inside the Ext.drag.Source(). I get 2 alert messages ,before source and outside source. and because it doesn't go inside Ext.drag.Source().
The drag-able functionality of the element is not working. What should I do ?
First you need to be clear on which component you want to use. After that you need to put afterrender event on that component and inside of that event you can use Ext.drag.Source.
In this FIDDLE, I have created a demo using button and Ext.drag.Source.
CODE SNIPPET
Ext.application({
name: 'Fiddle',
launch: function () {
var buttons = [],
rendomColor = () => {
return "#" + ((1 << 24) * Math.random() | 0).toString(16);
};
for (var i = 0; i < 10; i++) {
buttons.push({
text: `Button ${i+1}`,
margin: 10,
style: `background:${rendomColor()}`
});
}
Ext.create({
xtype: 'panel',
height: window.innerHeight,
title: 'Ext.drag.Source Example',
defaults: {
xtype: 'button'
},
items: buttons,
renderTo: Ext.getBody(),
listeners: {
afterrender: function (panel) {
panel.items.items.forEach(item => {
new Ext.drag.Source({
element: item.el,
constrain: {
// Drag only vertically in 30px increments
//vertical: true,
snap: {
y: 1,
x: 1
}
}
})
})
}
}
});
}
});
I have a question regarding the browser compatability of Web Animations. I am aware that it is not working on some browsers.
However, is it possible to still use the transformation that is normally applied by the animation. My animation runs (through neon-animation from Polymer), but the result doesn't stay. It reverts back when the animation is finished.
(Small note, the $$("paper-item") is from polymer and is equivalent to querySelector("paper-item"))
I fixed this on Chrome with the following code:
_onNeonAnimationFinish: function() {
if (this.opened) {
this.$$("paper-item").style.margin = '16px auto';
this.$$("paper-item").style.width = '84vw';
this.$$("paper-item").style.height = '144px';
} else {
this.$$("paper-item").style.margin = "0px auto";
this.$$("paper-item").style.width = '72vw';
this.$$("paper-item").style.height = '72px';
}
}
As said, this is working on Chrome. Firefox and Safari are having trouble with it though. How can this be fixed?
My complete code is as following:
<!-- Custom element -->
<dom-module id="agenda-item">
<template>
<style>
paper-item {
background-color: #ffffff;
width: 72vw;
margin: 0 auto;
height: 72px;
}
</style>
<paper-item>
- content -
</paper-item>
</template>
<script>
Polymer({
is: 'agenda-item',
behaviors: [
Polymer.NeonAnimationRunnerBehavior
],
properties: {
opened: {
type: Boolean,
value: false,
reflectToAttribute: true
},
animationConfig: {
value: function() {
return {
'expand': [{
name: 'expand-list-item-animation',
node: this.$$("paper-item"),
timing: {
duration: 1000
}
}],
'collapse': [{
name: 'collapse-list-item-animation',
node: this.$$("paper-item"),
timing: {
duration: 1000
}
}]
};
}
}
},
listeners: {
'tap': 'onClick',
'neon-animation-finish': '_onNeonAnimationFinish'
},
onClick: function(event) {
if (this.opened) {
this.collapse();
} else {
this.expand();
}
},
expand: function() {
this.cancelAnimation();
this.playAnimation('expand');
this.opened = true;
},
collapse: function() {
this.cancelAnimation();
this.opened = false;
this.playAnimation('collapse');
},
_onNeonAnimationFinish: function() {
if (this.opened) {
this.$$("paper-item").style.margin = '16px auto';
this.$$("paper-item").style.width = '84vw';
this.$$("paper-item").style.height = '144px';
} else {
this.$$("paper-item").style.margin = '0px auto';
this.$$("paper-item").style.width = '72vw';
this.$$("paper-item").style.height = '72px';
}
}
});
</script>
</dom-module>
<!-- Custom animation -->
<!-- Both custom animations have the same idea and similar code -->
<script>
Polymer({
is: 'expand-list-item-animation',
behaviors: [
Polymer.NeonAnimationBehavior
],
configure: function(config) {
var node = config.node;
if (config.transformOrigin) {
this.setPrefixedProperty(node, 'transformOrigin', config.transformOrigin);
}
this._effect = new KeyframeEffect(node, [{
offset: 0.0,
'margin': '0 auto',
'width': '72vw',
'height': '72px'
}, {
offset: 0.6,
'margin': '16px auto',
'width': '84vw',
'height': '72px'
}, {
offset: 1.0,
'margin': '16px auto',
'width': '84vw',
'height': '144px'
}], this.timingFromConfig(config));
return this._effect;
}
});
</script>
EDIT:
I found the problem, but not how to solve it. It would be great to get some help.
The neon-animation-finish is not called at the moment the animation finishes. It is called just before that (not on chrome btw). Then, when the function is called to adjust the styling, it is overwritten by the animation.
You need to define a listener to the animation-finish and define what you want to see when the animation has finished like this:
listeners: {
// this event is fired when the animation finishes
'neon-animation-finish': '_onNeonAnimationFinish'
},
Have a look at the Polymer documentation at: https://github.com/PolymerElements/neon-animation/blob/master/README.md
I am new to jointJs library and I am trying to add ports to my custom element that contains html code in it. I followed this tutorial (http://www.jointjs.com/tutorial/html-elements) and created my element. But when I try to add ports to it (based on this tutorial: http://www.jointjs.com/tutorial/ports) it does not work.
Another problem I have is that I want the textbox(textarea on my custom shape) to disappear when I click on the blank paper, and just the label with its content stays visible on the element. For that I used the following piece of code (but it does not give me the above-mentioned functionality):
paper.on('blank:pointerdown', function(evt, x, y) { this.$box.find('textarea').toBack(); });
this.model.on('cell:pointerclick', function(evt, x, y) {this.$box.find('textarea').toFront();});
My whole code is as below:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="graph.css">
<script type="text/javascript" src="http://www.jointjs.com/downloads/joint.js" ></script>
<script src="http://www.jointjs.com/downloads/joint.shapes.devs.js" ></script>
<script src="http://www.jointjs.com/downloads/joint.shapes.devs.min.js" ></script>
</head>
<title>Test</title>
<body>
<div id="myholder"></div>
</body>
<script>
var graph = new joint.dia.Graph;
var paper = new joint.dia.Paper({
el: $('#myholder'),
width: 1500,
height: 700,
model: graph
});
// Create a custom element.
// ------------------------
joint.shapes.html = {};
joint.shapes.html.Element = joint.shapes.basic.Rect.extend({
defaults: joint.util.deepSupplement({
type: 'html.Element',
attrs: {
rect: { stroke: 'none', 'fill-opacity': 0 }
}
}, joint.shapes.basic.Rect.prototype.defaults)
});
// Create a custom view for that element that displays an HTML div above it.
// -------------------------------------------------------------------------
joint.shapes.html.ElementView = joint.dia.ElementView.extend({
template: [
'<div class="html-element">',
'<button class="delete">x</button>',
'<span id="lbl" value="Please write here"></span>',
'<textarea id="txt" type="text" value="Please write here"></textarea>',
'</div>'
].join(''),
initialize: function() {
_.bindAll(this, 'updateBox');
joint.dia.ElementView.prototype.initialize.apply(this, arguments);
this.$box = $(_.template(this.template)());
// Prevent paper from handling pointerdown.
this.$box.find('input,select').on('mousedown click', function(evt) { evt.stopPropagation(); });
// This is an example of reacting on the input change and storing the input data in the cell model.
this.$box.find('textarea').on('change', _.bind(function(evt) {
this.model.set('textarea', $(evt.target).val());
}, this));
this.$box.find('.delete').on('click', _.bind(this.model.remove, this.model));
// Update the box position whenever the underlying model changes.
this.model.on('change', this.updateBox, this);
// Remove the box when the model gets removed from the graph.
this.model.on('remove', this.removeBox, this);
this.updateBox();
},
render: function() {
joint.dia.ElementView.prototype.render.apply(this, arguments);
this.paper.$el.prepend(this.$box);
this.updateBox();
return this;
},
updateBox: function() {
// Set the position and dimension of the box so that it covers the JointJS element.
var bbox = this.model.getBBox();
// Example of updating the HTML with a data stored in the cell model.
paper.on('blank:pointerdown', function(evt, x, y) { this.$box.find('textarea').toBack(); });
this.$box.find('span').text(this.model.get('textarea'));
this.model.on('cell:pointerclick', function(evt, x, y) { this.$box.find('textarea').toFront(); });
this.$box.css({ width: bbox.width, height: bbox.height, left: bbox.x, top: bbox.y, transform: 'rotate(' + (this.model.get('angle') || 0) + 'deg)' });
},
removeBox: function(evt) {
this.$box.remove();
}
});
// Create JointJS elements and add them to the graph as usual.
// -----------------------------------------------------------
var el1 = new joint.shapes.html.Element({
position: { x: 600, y: 250 },
size: { width: 200, height: 100 },
inPorts: ['in'],
outPorts: ['out'],
attrs: {
'.inPorts circle': { fill: 'gray'},
'.outPorts circle': { fill: 'gray'}
},
textarea: 'Start writing'});
graph.addCells([el1]);
paper.on('cell:pointerdblclick', function(cellView, evt, x, y) {
var el2 = new joint.shapes.html.Element({ position: { x: 600, y: 400 }, size: { width: 200, height: 100 }, textarea: 'Start writing'});
var l = new joint.dia.Link({
source: { id: el1.id },
target: { id: el2.id },
attrs: { '.connection': { 'stroke-width': 1, stroke: 'gray' } }
});
graph.addCells([el2, l]);
});
</script>
</html>
I have searched a lot for answers to these problems but I was not successful finding simple and comprehensive ones.
Any help will be appreciated.
Thanks.
I am also new to jointJs and stuck with same problem and found this thread. I have tried and worked successfully.
You have to customize css of element to get better view. Go to working with ports for more work with ports.
Here's the code:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="http://www.jointjs.com/downloads/joint.min.css">
<style type="text/css">
#myholder .html-element{
position: absolute;
margin-left: 8px;
padding: 5px 0 10px 0;
background-color: #fff;
border: 1px solid #eee;
border-radius: 5px;
pointer-events: none;
-webkit-user-select: none;
}
</style>
<script type="text/javascript" src="http://www.jointjs.com/downloads/joint.min.js" ></script>
</head>
<title>Test</title>
<body>
<div id="myholder"></div>
</body>
<script>
var graph = new joint.dia.Graph;
var paper = new joint.dia.Paper({
el: $('#myholder'),
width: 1500,
height: 700,
model: graph
});
// Create a custom element.
// ------------------------
joint.shapes.html = {};
joint.shapes.html.Element = joint.shapes.basic.Generic.extend(_.extend({}, joint.shapes.basic.PortsModelInterface, {
markup: '<g class="rotatable"><g class="scalable"><rect/></g><g class="inPorts"/><g class="outPorts"/></g>',
portMarkup: '<g class="port<%= id %>"><circle/></g>',
defaults: joint.util.deepSupplement({
type: 'html.Element',
size: { width: 100, height: 80 },
inPorts: [],
outPorts: [],
attrs: {
'.': { magnet: false },
rect: {
stroke: 'none', 'fill-opacity': 0, width: 150, height: 250,
},
circle: {
r: 6, //circle radius
magnet: true,
stroke: 'black'
},
'.inPorts circle': { fill: 'green', magnet: 'passive', type: 'input'},
'.outPorts circle': { fill: 'red', type: 'output'}
}
}, joint.shapes.basic.Generic.prototype.defaults),
getPortAttrs: function (portName, index, total, selector, type) {
var attrs = {};
var portClass = 'port' + index;
var portSelector = selector + '>.' + portClass;
var portCircleSelector = portSelector + '>circle';
attrs[portCircleSelector] = { port: { id: portName || _.uniqueId(type), type: type } };
attrs[portSelector] = { ref: 'rect', 'ref-y': (index + 0.5) * (1 / total) };
if (selector === '.outPorts') { attrs[portSelector]['ref-dx'] = 0; }
return attrs;
}
}));
// Create a custom view for that element that displays an HTML div above it.
// -------------------------------------------------------------------------
joint.shapes.html.ElementView = joint.dia.ElementView.extend({
template: [
'<div class="html-element">',
'<button class="delete">x</button>',
'<span id="lbl" value="Please write here"></span>',
'<textarea id="txt" type="text" value="Please write here"></textarea>',
'</div>'
].join(''),
initialize: function() {
_.bindAll(this, 'updateBox');
joint.dia.ElementView.prototype.initialize.apply(this, arguments);
this.$box = $(_.template(this.template)());
// Prevent paper from handling pointerdown.
this.$box.find('input,select').on('mousedown click', function(evt) { evt.stopPropagation(); });
// This is an example of reacting on the input change and storing the input data in the cell model.
this.$box.find('textarea').on('change', _.bind(function(evt) {
this.model.set('textarea', $(evt.target).val());
}, this));
this.$box.find('.delete').on('click', _.bind(this.model.remove, this.model));
// Update the box position whenever the underlying model changes.
this.model.on('change', this.updateBox, this);
// Remove the box when the model gets removed from the graph.
this.model.on('remove', this.removeBox, this);
this.updateBox();
this.listenTo(this.model, 'process:ports', this.update);
joint.dia.ElementView.prototype.initialize.apply(this, arguments);
},
render: function() {
joint.dia.ElementView.prototype.render.apply(this, arguments);
this.paper.$el.prepend(this.$box);
// this.paper.$el.mousemove(this.onMouseMove.bind(this)), this.paper.$el.mouseup(this.onMouseUp.bind(this));
this.updateBox();
return this;
},
renderPorts: function () {
var $inPorts = this.$('.inPorts').empty();
var $outPorts = this.$('.outPorts').empty();
var portTemplate = _.template(this.model.portMarkup);
_.each(_.filter(this.model.ports, function (p) { return p.type === 'in' }), function (port, index) {
$inPorts.append(V(portTemplate({ id: index, port: port })).node);
});
_.each(_.filter(this.model.ports, function (p) { return p.type === 'out' }), function (port, index) {
$outPorts.append(V(portTemplate({ id: index, port: port })).node);
});
},
update: function () {
// First render ports so that `attrs` can be applied to those newly created DOM elements
// in `ElementView.prototype.update()`.
this.renderPorts();
joint.dia.ElementView.prototype.update.apply(this, arguments);
},
updateBox: function() {
// Set the position and dimension of the box so that it covers the JointJS element.
var bbox = this.model.getBBox();
// Example of updating the HTML with a data stored in the cell model.
// paper.on('blank:pointerdown', function(evt, x, y) { this.$box.find('textarea').toBack(); });
this.$box.find('span').text(this.model.get('textarea'));
this.model.on('cell:pointerclick', function(evt, x, y) { this.$box.find('textarea').toFront(); });
this.$box.css({ width: bbox.width, height: bbox.height, left: bbox.x, top: bbox.y, transform: 'rotate(' + (this.model.get('angle') || 0) + 'deg)' });
},
removeBox: function(evt) {
this.$box.remove();
}
});
// Create JointJS elements and add them to the graph as usual.
// -----------------------------------------------------------
var el1 = new joint.shapes.html.Element({
position: { x: 600, y: 250 },
size: { width: 170, height: 100 },
inPorts: ['in'],
outPorts: ['out'],
textarea: 'Start writing'
});
var el2 = new joint.shapes.html.Element({
position: { x: 600, y: 400 },
size: { width: 170, height: 100 },
inPorts: ['in'],
outPorts: ['out'],
textarea: 'Start writing'
});
graph.addCells([el1, el2]);
</script>
</html>
I have asked a question that no one has answered it. It was how I can make the textarea disappear when I click on the blank paper and appear when I click on the cell: First I thought I have to solve it through the jsonJS events inside the javascript. But I found out that there is a very simple solution for this. I just need to use the hover function in css styling and change the opacity from 0 to 1 when you hover over the box (in your css file) :
.html-element textarea {
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 60px;
width: 150px;
border: none;
color: #333;
background-color: white;
padding: 5px;
margin: 5px;
opacity:0;
}
.html-element textarea:hover {
opacity:1;
}
rzkmr's answer worked for me, +1'd his response. (Thank you!)
In his example, to allow the textarea to be used, add this to the css:
.html-element select,
.html-element input,
.html-element textarea,
.html-element button {
/* Enable mouse interaction. */
pointer-events: auto;
}