1

HTML5 Canvas を使用して jQuery Knob のような効果を実現したいと考えていますが、jQuery Knob が行うストローク カーソル効果ではなく、円のノブ/カーソルを使用します。

jQuery Knob コードに基づいて、onMouseMove イベントをサークル ノブ/カーソルに接続することができたので、マウスの位置の X 座標と Y 座標に従ってサークル ノブが移動します。ただし、この例のように円のパス上または円に沿ってのみ移動するようにノブを「制限」することはできないため、円のパス内をクリック/マウスダウンすると、円のノブがパス内に移動します。

上記の例のような Raphael ではなく、Canavas と jQuery のみを使用してこれを達成する方法はありますか?

私の考えの 1 つは、mousemove イベントがパスの外側で発生するたびに、円のノブをトラック (パス上) に戻すことでした (このように)。ただし、この計算を成功させるには運がありません。これを達成するために使用できる数学/幾何学の公式はありますか?

4

1 に答える 1

5

三角法を少し使うだけで、あなたの質問に答えることができます!

このコードは、マウスクリックに最も近い円上の点を見つけます。

var rads = Math.atan2(mouseY - knobCenterY, mouseX - knobCenterX);
var indicatorX=knobRadius*Math.cos(rads)+knobCenterX;
var indicatorY=knobRadius*Math.sin(rads)+knobCenterY;

このコードは、ユーザーがクリックした場所に最も近いノブにインジケーターを配置します。

そして、ここにフィドルがあります --- http://jsfiddle.net/m1erickson/pL5jP/

    <!doctype html>
    <html>
    <head>
    <link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
    <script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
    <!--[if lt IE 9]><script type="text/javascript" src="../excanvas.js"></script><![endif]-->

    <style>
        body{ background-color: ivory; }
        canvas{border:1px solid red;}
    </style>

    <script>
    $(function(){

        var canvas=document.getElementById("canvas");
        var ctx=canvas.getContext("2d");
        var canvasOffset=$("#canvas").offset();
        var offsetX=canvasOffset.left;
        var offsetY=canvasOffset.top;
        var circleArc=Math.PI*2;

        // drawing design properties
        var knobCenterX=100;
        var knobCenterY=100;
        var knobRadius=50;
        var knobColor="green";
        var indicatorRadius=5;
        var indicatorColor="yellow";

        Draw(canvas.width/2,1); // just to get started

        function Draw(mouseX,mouseY){
            // given mousePosition, what is the nearest point on the knob
            var rads = Math.atan2(mouseY - knobCenterY, mouseX - knobCenterX);
            var indicatorX=knobRadius*Math.cos(rads)+knobCenterX;
            var indicatorY=knobRadius*Math.sin(rads)+knobCenterY;
            // start drawing
            ctx.clearRect(0,0,canvas.width,canvas.height);
            // draw knob
            ctx.beginPath();
            ctx.arc(knobCenterX,knobCenterY,knobRadius,0,circleArc,false);
            ctx.fillStyle="ivory";
            ctx.fill();
            ctx.lineWidth=2;
            ctx.strokeStyle=knobColor;
            ctx.stroke();
            // draw indicator
            ctx.beginPath();
            ctx.arc(indicatorX, indicatorY, indicatorRadius, 0, circleArc, false);
            ctx.fillStyle = indicatorColor;
            ctx.fill();
            ctx.lineWidth = 2;
            ctx.strokeStyle = 'black';
            ctx.stroke();
        }

        function handleMouseDown(e){
          MouseX=parseInt(e.clientX-offsetX);
          MouseY=parseInt(e.clientY-offsetY);
          Draw(MouseX,MouseY);
        }

        $("#canvas").mousedown(function(e){handleMouseDown(e);});

    }); // end $(function(){});
    </script>

    </head>

    <body>

        <br/><p>Click anywhere in the canvas to set the knob indicator</p><br/>
        <canvas id="canvas" width=200 height=200></canvas>

    </body>
    </html>
于 2013-02-22T08:06:13.943 に答える