在描边画布

时间:2016-11-17 09:12:58

标签: javascript qt canvas qml mouseevent

我在qml中使用canvas创建了一个自定义弧进度。我根据经过的时间绘制了画布的进度。现在我需要通过进度条寻找,就像音乐搜索栏一样,我们如何在画布中获得正确的x,y位置。

这是绘制弧的代码

import QtQml 2.2
import QtQuick 2.0

// draws two arcs (portion of a circle)
// fills the circle with a lighter secondary color
// when pressed
Canvas {
    id: canvas
    width: canvasWidth
    height: canvasHeight
    antialiasing: true

    property color primaryColor: "grey"
    property color secondaryColor: "white"

    property int canvasWidth: 0
    property int canvasHeight: 0

    property real centerWidth: width / 2
    property real centerHeight: height / 2
    property real radius: Math.min(canvas.width, canvas.height) / 2 - 2

    property real minimumValue: 0
    property real maximumValue: 100
    property real currentValue: 33

    // this is the angle that splits the circle in two arcs
    // first arc is drawn from 0 radians to angle radians
    // second arc is angle radians to 2*PI radians
    property real angle: ((currentValue - minimumValue) / (maximumValue - minimumValue) * 2 * Math.PI)

    // we want both circle to start / end at 12 o'clock
    // without this offset we would start / end at 9 o'clock
    property real angleOffset: (-Math.PI / 2)

    property string text: "Text"

    signal clicked()

    onPrimaryColorChanged: requestPaint()
    onSecondaryColorChanged: requestPaint()
    onMinimumValueChanged: requestPaint()
    onMaximumValueChanged: requestPaint()
    onCurrentValueChanged: requestPaint()

    onPaint: {
        var ctx = getContext("2d");
        ctx.save();

        ctx.clearRect(0, 0, canvas.width, canvas.height);
        // First, thinner arc
        // From angle to 2*PI

        ctx.beginPath();
        ctx.lineWidth = 3;
        ctx.strokeStyle = primaryColor;
        ctx.arc(canvas.centerWidth,
                canvas.centerHeight,
                canvas.radius,
                angleOffset + canvas.angle ,
                (angleOffset-0.1) + 2*Math.PI );
        ctx.stroke();


        // Second, thicker arc
        // From 0 to angle

        ctx.beginPath();
        ctx.lineWidth = 3;
        ctx.strokeStyle = canvas.secondaryColor;
        ctx.arc(canvas.centerWidth,
                canvas.centerHeight,
                canvas.radius,
                canvas.angleOffset,
                canvas.angleOffset + canvas.angle);
        ctx.stroke();

        ctx.restore();



    }



    function xOnArc(radius, radianAngle) {
           var x = canvas.centerWidth + radius * Math.cos(radianAngle);
           return   x-(rect.width/2)
       }
    function yOnArc(radius, radianAngle) {
           var y = canvas.centerHeight + radius * Math.sin(radianAngle);
           return y-rect.height/2
       }



    Rectangle
   {
       id: rect
       color: "white"
       height: 10
       width: 10
       radius: 10/2
       x: xOnArc(canvas.radius,canvas.angleOffset + canvas.angle)
       y: yOnArc(canvas.radius,canvas.angleOffset + canvas.angle)


//       Behavior on x
//       {
//           NumberAnimation {properties: "x"; duration:10}
//       }

//       Behavior on y
//       {
//           NumberAnimation {properties: "y"; duration:10}
//       }

   }
}

这是我将根据已用时间显示进度的代码

import QtQuick 2.0

Item {
    anchors.fill: parent
    property real value: 0
    height: canvasHeights
    width: canvasWidths
    property real total_time: 180
    property real progress_time: 0
    property bool isPlaying: song_timer.running
    signal songCompleted()
    property int canvasWidths: 240
    property int canvasHeights: 240

    property int text_margin_progress: 0

    /**
      A custom control which draws the the progress Arc in canvas
      */
    ProgressArc
    {
        id: circle
        currentValue: value
        anchors.centerIn: parent
        canvasWidth: canvasWidths
        canvasHeight: canvasHeights


        /**
          A timer will be started when the song starts playing this controls the progress of the song
          */
        Timer
        {
            id: song_timer
            running: false
            repeat: true
            interval: 1000
            onTriggered:
            {
                //progress_time will be incremented after each second which will be used to calculate the progress percentage and
                //and time
                progress_time = progress_time + 1;
                value = calculateStepValue(progress_time)
                circle.currentValue = value;
                time.text = fmtMSS(progress_time)

                /**
                  When value reaches 100 then the song is completed and a signal will be send to the corresponsing class
                  */
                if(value >=100)
                {
                    song_timer.stop()
                    songCompleted()

                }
            }
        }


        /**
          Elapsed time will be shown in the text
          */
        Text
        {
            id: time
            anchors.horizontalCenter: parent.horizontalCenter
            anchors.bottom: parent.bottom
            anchors.bottomMargin: text_margin_progress
            color: "white"
            font.pointSize: (canvasHeights == (350*scaleFactor-(20*scaleFactor)))?20:10
        }

    }

    /**
      Convert seconds to human readable format
      eg:- 68 sec eq 1:08 min
      */
    function fmtMSS(time){
        // Hours, minutes and seconds
        var hrs = ~~(time / 3600);
        var mins = ~~((time % 3600) / 60);
        var secs = time % 60;

        // Output like "1:01" or "4:03:59" or "123:03:59"
        var ret = "";
        if (hrs > 0) {
            ret += "" + hrs + ":" + (mins < 10 ? "0" : "");
        }
        ret += "" + mins + ":" + (secs < 10 ? "0" : "");
        ret += "" + secs;
        return ret;
    }


    /**
      Calculate the step value from the progress time
      */
    function calculateStepValue(current_time)
    {
        return (100 - (((total_time - current_time)/total_time)*100))
    }


    /**
      pause playing music
      */
    function pausePlaying()
    {
        song_timer.stop();
    }

    /**
      Resume playing music
      */
    function resumePlaying()
    {
        if(value>100)
            songCompleted()
        else
            song_timer.start()
    }

    /**
      Start playing song. Before playing set the progress time to 0{song from start}
      */
    function startPlaying()
    {
        progress_time = 0
        song_timer.start()
    }
}

1 个答案:

答案 0 :(得分:0)

要获得您想要的内容,您需要将MouseArea添加到Item或直接添加到ProgressArc(来自第二个列表):

MouseArea {
    anchors.fill: parent
    onClicked: {
        console.log("Clicked on " + mouse.x + " " + mouse.y)
        var percent = calcPercentBasedOnMousePos(mouse.x, mouse.y)
        jumpToPosition(percent)
    }
}

不要忘记设置锚点以填充父项目(否则此MouseArea将为0x0大小且无法处理任何点击次数。

你可以看到onClicked处理程序的虚拟实现 - 它是关于我如何看待你的任务。因此,您可以自行按xy值自由操作。