I'm using jointjs to draw diagrams.
My problem is that in my jointjs rect, the text inside is too long. The size of my rect is assumed fixed.
I have used joint.util.breakText to control the height and width, but the overflow disappears. And I have set the font-size small enough. How to fix this problem?
Thanks in advance.
I had a similar problem. In my case I have empty shapes. By click-event I can add a comment (text) to the shape. This example enlarges the shape's size and wraps the text inside additionally. Hope it helps!
function enterText(viewShape) {
var shapeText = prompt('Enter your new comment:', '');
if (viewShape.model.id === 'CommentID') {
//change comment text here
if (shapeText.length > 5) {
var wraptext = joint.util.breakText(shapeText, {
width: 200
//height: optionalHeight
});
//resize attribute and add it to paper
viewShape.model.resize(wraptext.length * 8, 67);
viewShape.model.attr('text/text', wraptext).attr('text/ref-y', 0.45);
} else {
viewShape.model.attr('text/text', shapeText).attr('text/ref-y', 0.45);
}
}
}
Related
var rectangle = new Graphics();
rectangle.beginFill(0, 0.001);
rectangle.lineStyle(1, 0xFF0000);
rectangle.drawRect(5, 5, 200, 100);
rectangle.interactive = true;
rectangle.buttonMode = true;
rectangle.on('pointerdown', onDragStart)
.on('pointerup', onDragEnd)
.on('pointerupoutside', onDragEnd)
.on('pointermove', onDragMove);
app.viewport.addChild(rectangle);
I'm using this code to create a rectangle and adding it to rectangle. This is the onDragMove Function
function onDragMove() {
if (this.dragging) {
const newPosition = this.data.getLocalPosition(this.parent);
this.width = newPosition.x;
this.height = newPosition.y;
}
}
This is basically changing its width and height, but I also want to Drag the Rectangle when clicked inside the rectangle and dragged on the screen. Any suggestions how can I achieve this?
Borders to change width/height
clicking inside rectangle to drag on the screen.
I created working example of dragging and resizing: https://www.pixiplayground.com/#/edit/SbpTjm7WKXbL51kmiG89W - please check.
when you click near bottom border of rectangle (+/- 20 px) then you will start resizing it.
when you click in any other place inside rectangle then you will drag it
Basing on this example i think you can implement resizing of other borders of rectangle etc :)
One note: please look at function drawRectangle :
function drawRectangle(rectangle)
{
rectangle.clear();
rectangle.beginFill(0, 0.001);
rectangle.lineStyle(1, 0xFF0000);
rectangle.drawRect(rectangle.myRectanglePosition[0], rectangle.myRectanglePosition[1], rectangle.myRectanglePosition[2], rectangle.myRectanglePosition[3]);
}
^ the rectangle.clear(); is called to redraw the PIXI.Graphics object. So on each frame we clear and draw it again on specific position with specific width & height.
In this jsFiddle I have a Raphael canvas with a line/path where the user can drag it.
Problem is that the exact top pixel of the mouse pointer has to be on the line to be able to drag it. I need Raphael to be more "forgiving" and let the user drag the line if it touches the top, say, 3 pixels of the pointer.
I added mouseover/mouseout events to actually tell when the mouse is over the line, otherwise is very difficult to know.
So the question is: is there a way to drag the line without having to accurately position the mouse pointer?
var paper = Raphael("canvas", 600, 600);
var line = this.paper.path('M10 10 L50 50');
var start = function () {
this.odx = 0;
this.ody = 0;
},
move = function (dx, dy) {
this.translate(dx - this.odx, dy - this.ody);
this.odx = dx;
this.ody = dy;
},
up = function () {};
line.drag(move, start, up);
line.mouseover(function(e) {
line.attr('stroke', 'red');
});
line.mouseout(function(e) {
line.attr('stroke', 'black');
});
The Raphael library creates an SVG element (not a CANVAS element) for drawing purposes, and drawing lines creates PATH elements within the SVG element.
I had some success by increasing the line width on hover. You do have to trigger the width change by at least moving the mouse over the line, but it is a lot easier to select afterwards. While the visual effect produced may not be perfect (some width flicking can occur) continuing the drag operation proceeds without problem.
You could try increasing the line width by either modifying the stroke-width attribute in the mouseover and mouseout handlers:
line.mouseover(function(e) {
line.attr('stroke', 'red');
line.attr('stroke-width', '9')
});
line.mouseout(function(e) {
line.attr('stroke', 'black');
line.attr('stroke-width', '1')
});
or by modifying the stroke-width styling when hovering over all path elements in CSS using
path:hover {
stroke-width: 9;
}
According to this question Raphael does not provide an abstraction of all possible CSS styling so it could use VML in XML documents. If you can live without IE 9 support and expect users to have a modern browser you may be interested in the following snippet which
increases the width of a line on mouseover by setting class name draggable, which sets a move cursor,
when a move is started replaces draggable with dragging ( which removes the width increase) and sets a move cursor over the svg container,
removes class draggable, but not dragging, on mouseout
cleans up classes and the cursor in the up function.
"use strict";
var container = document.getElementById("canvas");
var paper = Raphael("canvas", 600, 600);
var line = this.paper.path('M10 10 L50 50');
var start = function () {
this.odx = 0;
this.ody = 0;
},
move = function (dx, dy) {
this.translate(dx - this.odx, dy - this.ody);
this.odx = dx;
this.ody = dy;
if( this.node.classList.contains("draggable")) {
this.node.classList.replace("draggable", "dragging");
container.classList.add("moveCursor");
}
},
up = function (e) {
line.node.classList.remove("draggable", "dragging");
container.classList.remove("moveCursor");
};
line.drag(move, start, up);
line.mouseover(function(e) {
if(!e.target.classList.contains("dragging")) {
e.target.setAttribute("class", "draggable");
}
});
.draggable:hover {
stroke-width: 9;
stroke:red;
cursor: move;
}
path.dragging {
stroke: red;
}
.moveCursor{
cursor:move;
}
svg {
border: thin solid blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js"></script>
<!-- body-html -->
<div id="canvas"></div>
The code is basically for demonstration - if you drag a line outside the SVG element you can't see it or grab it to drag back.
Some CSS rules (i.e. path.dragging) needed additional specificity to take priority over the defaults supplied by Raphael.
I am creating a discolor function for designing a jeans pant. I have 2 images of equal sizes one with dark color and other with lighter color. What I want to do is if someone draw a line with brush on my canvas it need to copy same area from a hidden image and need to fill that line with pasting that area from hidden image.
See these images to understand my requirement
Image 1 which showing over canvas.
Image 2 is hidden Image. It must not show on any condition
Image 3 is requirement.
(source: hhcnct.com)
(source: hhcnct.com)
Like you can see in image 2 top area is not lighter it means if someone brush on top no differnce will occur as both have same color at top.
Should I need to create a hidden layer first from second image?
I am looking a solution in fabric.js because my current base setup in fabric.js.
Anybody can help please?
JSFIDDLE Link
https://jsfiddle.net/19kpdwjx/
Need to finish the answer. Had no idea how to save a draft.
Answere incomplete here
var canvas = new fabric.Canvas('canvas-front', {
preserveObjectStacking: true,
controlsAboveOverlay: true
});
canvas.backgroundColor = '#ebeced';
window.fabric.Image.fromURL('https://evolveapothecary.com/frontnew.jpg', (img) => {
canvas.freeDrawingBrush.color = new fabric.Pattern({ source: img._element, repeat: 'no-repeat' });
});
window.fabric.Image.fromURL('https://evolveapothecary.com/frontnew.jpg', (img) => {
img.set({
left: 0,
top: 0
});
canvas.add(img);
})
canvas.renderAll();
canvas.isDrawingMode = true;
canvas.freeDrawingBrush.width = 20;
[hidden] {
display: none!important;
}
.painting-area{
overflow: hidden;
margin: 0;
height: auto;
border: 1px solid #e0e0e0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.4.0/fabric.min.js"></script>
<div class="painting-area">
<canvas id="canvas-front" width="680" height="680"></canvas>
</div>
I'm trying to place text dynamically into an svg created by Snap, this is what I tried:
this.setContent(
`<svg id="${this.svgId}"></svg>`
);
var snap = Snap($(`#${this.svgId}`)[0]);
text = "asdfsdfsdsfd";
var rect = snap.paper.rect(0, 0, 50, text.length*3 + 4, 10);
snap.text(1.5,10, text);
console.log("rect", rect);
console.log("snap", snap);
rect.attr({
fill: "#FFFFFF",
fillOpacity: 0.6,
});
I get this:
I want the rectangle to be just a little bigger than the text, but there must be a better way to do it than to calculate the length and height of the text, and that's assuming the font size won't change.
This is the only result I found regarding text in the snap docs: http://snapsvg.io/docs/#Paper.text
You could try using getBBox() on the text element, and use that to figure the size of the rect. getBBox() wll give you the x,y,width,height,x2,y2 figures to help.
var text = s.text(0,0,'blah blah')
var bb = text.getBBox();
var rect = s.rect(bb.x, bb.y, bb.width, bb.height )
Adjusting with offsets for whatever padding etc that you want. You may also need to allow for stroke widths, as I don't think that's included.
I have used canvas in the html5 using fabric js .
I want to apply outlines to the active text on the canvas. following code I have written it is working fine but problem is when I increase the thickness of outline then it overlaps on the text that means text color disappears.
activeObject1.stroke = color;
activeObject1.strokeWidth = 5;
and one more thing by applying this I am unable to apply 2nd outline.
I got one example but it is not working with the fabricjs.
http://jsfiddle.net/vNWn6/
Fabric.js first applies a fill, followed by the stroke. You will need to invert the order in order to achieve the results.
original
_renderText: function(ctx) {
this._renderTextFill(ctx);
this._renderTextStroke(ctx);
}
Before
modified
_renderText: function(ctx) {
this._renderTextStroke(ctx);
this._renderTextFill(ctx);
}
After
version: fabric-1-7-1.js
fabric.Text.prototype.set({
fill: '#000',
stroke: '#fff',
strokeWidth: 4,
paintFirst: 'stroke', // stroke behind fill
})
since 2017-09-17
var active_obj = canvas.getActiveObject();
active_obj.stroke = '#000';
active_obj.strokeWidth = 5;
canvas.renderAll();