问题
I made 3 modes for this code:
- select line
- draw line and
- delete line.
It looks like it is working. But I want to change 2 things. For example that every time when I select a line i just need to click it.
Can you tell me how i can improve my code ?
Thank You for your answers.
This is my code:
<!DOCTYPE html>
<html>
<head>
<script type ="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.5.0/fabric.min.js"></script>
<script type ="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<title>Test</title>
</head>
<body>
<button id="select">Selection mode</button>
<button id="draw">Drawing mode</button>
<button id="delete">Delete selected object(s)</button><br />
<canvas id="c" width="400" height="400" style="border:1px solid #ccc"></canvas>
<script type="text/javascript">
var line, isDown,mode;
var canvas = new fabric.Canvas('c');
$("#select").click(function(){
mode="select";
canvas.selection=true;
canvas.perPixelTargetFind = true;
canvas.targetFindTolerance = 4;
canvas.renderAll();
});
$("#draw").click(function(){
mode="draw";
});
$("#delete").click(function(){
deleteObjects();
});
// Adding objects to the canvas...
canvas.on('mouse:down', function(o){
isDown = true;
var pointer = canvas.getPointer(o.e);
var points = [ pointer.x, pointer.y, pointer.x, pointer.y ];
if(mode=="draw"){
line = new fabric.Line(points, {
strokeWidth: 5,
fill: 'red',
stroke: 'red',
originX: 'center',
originY: 'center',
});
canvas.add(line);}
});
canvas.on('mouse:move', function(o){
if (!isDown) return;
var pointer = canvas.getPointer(o.e);
if(mode=="draw"){
line.set({ x2: pointer.x, y2: pointer.y });
canvas.renderAll(); }
});
canvas.on('mouse:up', function(o){
isDown = false;
});
// select all objects
function deleteObjects(){
var activeObject = canvas.getActiveObject(),
activeGroup = canvas.getActiveGroup();
if (activeObject) {
if (confirm('Are you sure?')) {
canvas.remove(activeObject);
}
}
else if (activeGroup) {
if (confirm('Are you sure?')) {
var objectsInGroup = activeGroup.getObjects();
canvas.discardActiveGroup();
objectsInGroup.forEach(function(object) {
canvas.remove(object);
});
}
}
}
</script>
</body>
</html>
Ps.: Sorry for bad english or mistakes.
回答1:
When adding a line to canvas it is normally selectable. But since you modified it's own properties like width and height that derives from the 2 points, its widht and height are changed.
If you change dimensions programmatically you have to call line.setCoords()
explicitly otherwise the interaction points are not calculated again.
perPixelTargetFind is optional and does not need to be called every time you go on selection mode.
So the answer is:
call line.setCoords() in your mouseup event.
Check the snippet.
<!DOCTYPE html>
<html>
<head>
<script type ="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.5.0/fabric.min.js"></script>
<script type ="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<title>Test</title>
</head>
<body>
<button id="select">Selection mode</button>
<button id="draw">Drawing mode</button>
<button id="delete">Delete selected object(s)</button><br />
<canvas id="c" width="400" height="400" style="border:1px solid #ccc"></canvas>
<script type="text/javascript">
var line, isDown,mode;
var canvas = new fabric.Canvas('c');
canvas.perPixelTargetFind = true;
canvas.targetFindTolerance = 4;
$("#select").click(function(){
mode="select";
canvas.selection=true;
canvas.renderAll();
});
$("#draw").click(function(){
mode="draw";
});
$("#delete").click(function(){
deleteObjects();
});
// Adding objects to the canvas...
canvas.on('mouse:down', function(o){
isDown = true;
var pointer = canvas.getPointer(o.e);
var points = [ pointer.x, pointer.y, pointer.x, pointer.y ];
if(mode=="draw"){
line = new fabric.Line(points, {
strokeWidth: 5,
fill: 'red',
stroke: 'red',
originX: 'center',
originY: 'center',
});
canvas.add(line);}
});
canvas.on('mouse:move', function(o){
if (!isDown) return;
var pointer = canvas.getPointer(o.e);
if(mode=="draw"){
line.set({ x2: pointer.x, y2: pointer.y });
canvas.renderAll(); }
});
canvas.on('mouse:up', function(o){
isDown = false;
line.setCoords();
});
// select all objects
function deleteObjects(){
var activeObject = canvas.getActiveObject(),
activeGroup = canvas.getActiveGroup();
if (activeObject) {
if (confirm('Are you sure?')) {
canvas.remove(activeObject);
}
}
else if (activeGroup) {
if (confirm('Are you sure?')) {
var objectsInGroup = activeGroup.getObjects();
canvas.discardActiveGroup();
objectsInGroup.forEach(function(object) {
canvas.remove(object);
});
}
}
}
</script>
</body>
</html>
回答2:
I think in your code where you create the line you can change it to below so that you can select the line when you click on it
Try this jsfiddle
if(mode=="draw"){
line = new fabric.Line(points, {
strokeWidth: 5,
fill: 'red',
stroke: 'red',
originX: 'center',
originY: 'center',
selectable: true,
targetFindTolerance: true
}
来源:https://stackoverflow.com/questions/35016961/fabric-js-straight-line-and-select-on-click