JavaScript - 动态创建SVG并修改游标

时间:2016-08-18 15:47:03

标签: javascript fabricjs

假设我有一个HTML5画布(在本例中使用fabric.js),我想在画布上更改光标以表示已选择的画笔大小和颜色。我认为应该有一种方法可以通过使用JS动态更改SVG的属性(大小和颜色)来实现这一点,因此我们不必使用多个图像。关于这是否可行的任何想法?

var canvas = new fabric.Canvas(c, {
            isDrawingMode: true,
            freeDrawingCursor: 'url("img/cursor.svg"), auto'
});

3 个答案:

答案 0 :(得分:3)

我认为freeDrawingCursor只是寻找正常的css属性名称。以下是如何使结构对象表示光标大小和颜色的示例:

var canvas = new fabric.Canvas('c', {
  isDrawingMode: true,
  freeDrawingCursor: 'none'
});

canvas.freeDrawingBrush.width = 10;
canvas.freeDrawingBrush.color = '#9f9';

var mousecursor = new fabric.Circle({ 
  left: 0, 
  top: 0, 
  radius: canvas.freeDrawingBrush.width / 2, 
  fill: canvas.freeDrawingBrush.color, 
  originX: 'right', 
  originY: 'bottom',
})

canvas.add(mousecursor);

canvas.on('mouse:move', function(obj) {
  mousecursor.top = obj.e.y - mousecursor.radius;
  mousecursor.left = obj.e.x - mousecursor.radius;
  canvas.renderAll()
})

canvas.on('mouse:out', function(obj) {
  // put circle off screen
  mousecursor.top = -100;
  mousecursor.left = -100;
  canvas.renderAll()
})
canvas {
    border: 1px solid #ccc;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.6.3/fabric.js"></script>

<canvas id="c" width="600" height="600"></canvas>

答案 1 :(得分:1)

I was looking for the same and found my way to this question. Unfortunately the solution by STHayden is not working for me. So I've modified it a bit and came up with the code below. It uses two canvas layers, the bottom for drawing, the top for the "cursor". Works pretty well for me now, maybe someone will find it helpful :)

//drawing layer
var canvas = new fabric.Canvas("draw", {
  isDrawingMode: true,
  freeDrawingCursor: 'none'
});
//mouse cursor layer
var cursor = new fabric.StaticCanvas("cursor");

canvas.freeDrawingBrush.width = 20;
canvas.freeDrawingBrush.color = '#ff0000';

var cursorOpacity = .5;
//create cursor and place it off screen
var mousecursor = new fabric.Circle({ 
  left: -100, 
  top: -100, 
  radius: canvas.freeDrawingBrush.width / 2, 
  fill: "rgba(255,0,0," + cursorOpacity + ")",
  stroke: "black",
  originX: 'center', 
  originY: 'center'
});

cursor.add(mousecursor);

//redraw cursor on new mouse position when moved
canvas.on('mouse:move', function (evt) {
  var mouse = this.getPointer(evt.e);  
  mousecursor
    .set({
      top: mouse.y,
      left: mouse.x
    })
    .setCoords()
    .canvas.renderAll();
});

//put cursor off screen again when mouse is leaving
canvas.on('mouse:out', function () {
  mousecursor
    .set({
      top: mousecursor.originalState.top,
      left: mousecursor.originalState.left
    })
    .setCoords()
    .canvas.renderAll();
});

//while brush size is changed show cursor in center of canvas
document.getElementById("size").oninput = function () {
  var size = parseInt(this.value, 10);
  mousecursor
    .center()
    .set({
      radius: size/2
    })
    .setCoords()
    .canvas.renderAll();
};

//after brush size has been changed move offscreen, update brush size
document.getElementById("size").onchange = function () {
  var size = parseInt(this.value, 10);
  canvas.freeDrawingBrush.width = size;
  mousecursor
    .set({
      left: mousecursor.originalState.left,
      top: mousecursor.originalState.top,
      radius: size/2
    })
    .setCoords()
    .canvas.renderAll();
};

//change mousecursor opacity
document.getElementById("opacity").onchange = function () {
  cursorOpacity = this.value;
  var fill = mousecursor.fill.split(",");
  fill[fill.length-1] = cursorOpacity + ")";
  mousecursor.fill = fill.join(",");
};

//change drawing color
document.getElementById("color").onchange = function () {
  canvas.freeDrawingBrush.color = this.value;  
  var bigint = parseInt(this.value.replace("#", ""), 16);
  var r = (bigint >> 16) & 255;
  var g = (bigint >> 8) & 255;
  var b = bigint & 255;  
  mousecursor.fill = "rgba(" + [r,g,b,cursorOpacity].join(",") + ")";
};
#cont {
  position: relative;
  width: 500px;
  height: 500px;
}

canvas {
  border: 1px solid;
}

#cont canvas, .canvas-container {
  position: absolute!important;
  left: 0!important;
  top: 0!important;
  width: 100%!important;
  height: 100%!important;
}

#cursor {
  pointer-events: none!important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.6.4/fabric.min.js"></script>
Color: <input id="color" type="color" value="#ff0000"><br/>
Brush size: <input id="size" type="range" min="1" max="100" step="1" value="20"><br/>
Brush opacity: <input id="opacity" type="number" min="0" max="1" step="0.1" value="0.5"><br/>
<div id="cont">
  <canvas id="draw" width="500" height="500"></canvas>
  <canvas id="cursor" width="500" height="500"></canvas>
</div>

答案 2 :(得分:0)

现有答案在2020年对我不起作用。请尝试以下操作:

    this.canvas.isDrawingMode = true;
    this.canvas.freeDrawingCursor = 'none';

    const mousecursor = new fabric.Circle({
        left: 0,
        top: 0,
        radius: this.canvas.freeDrawingBrush.width / 2,
        fill: this.canvas.freeDrawingBrush.color,
        originX: 'right',
        originY: 'bottom',
    });

    this.canvas.add(mousecursor);

    // Cursor in canvas
    this.canvas.on('mouse:move', event => {
        mousecursor.top = event.e.layerY + mousecursor.radius;
        mousecursor.left = event.e.layerX + mousecursor.radius;
        this.canvas.renderAll();
    });

    // Cursor out of canvas
    this.canvas.on('mouse:out', event => {
        mousecursor.top = -100;
        mousecursor.left = -100;
        this.canvas.renderAll();
    });

与Angular 7配合良好。