2016-08-18 14 views
1

HTML5キャンバス(この場合はfabric.jsを使用しています)があり、キャンバス上のカーソルを変更して、選択されたブラシのサイズと色を表したいとします。私は、SVGのプロパティ(サイズ&の色)をJSと動的に変更することによってこれを行う方法があるべきだと考えていますので、複数の画像を使用する必要はありません。これが可能ならどんなアイディアですか?JavaScript - SVGを動的に作成してカーソルを変更する

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

答えて

2

私は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>

+0

これは本当に素晴らしいアイデアです!私は自分のアプリで円カーソルが実際に描画されている場所の位置に揃えられていないことがわかっていますが、描画モードを終了するとカーソルも残ります。不透明度を0などに設定しますか? http://codepen.io/paulcredmond/pen/GqLmgb –

+1

originXとoriginYが設定されているコードを書き留めます。私は、円が描画出力が行われていた場所と同じ場所に来るようにするには、これらの設定が必要であることに気付きました。マウス:アウトで不透明度を0に設定すると動作する可能性があります。もっと理想的な解決方法は、おそらく、マウスの上のキャンバスからオブジェクトを削除することです:終了しますが、キャンバスに戻ったときに戻すときに参照を保持するだけです。 – StefanHayden

+0

'mouse:exit'関数がないようです。どのようにそれを行うにはどのようなアイデア? –

1

:ここでは生地のオブジェクトを持っている方法の例では、カーソルのサイズと色を表しています。残念ながら、STHaydenのソリューションは私のために働いていません。だから私はそれを少し修正し、以下のコードを思い付いた。これは2つのキャンバスレイヤーを使用しています。これは、描画の底部、「カーソル」の上部です。今の私のためにかなりよく働く、多分誰かがそれが役に立つでしょう:)

//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>

+0

あなたのソリューションを投稿していただきありがとうございます。私は実際にはほぼ同じ結論に達しましたが、キャンバスの上に余分な「レイヤー」を作成する必要はありませんでした。 –

+1

@PaulRedmond:はい、絶対に第2層が必要なわけではありません。私はそれを使用します。なぜなら、描画レイヤー上で画像処理を行い、そこにカーソルを置くこと(例えば、そのピクセルを「見る」)は役に立たないからです。 2つの層ですべてが大きく分離されています:) – Fidel90

+1

良い点。私は毎回カーソルを隠さなければならないので、イメージを保存するかシリアル化することについて考えていました。キャンバスをリセットしたときと同じですが、カーソルを再作成する必要があります。 –

関連する問題