2016-02-25 10 views
11

Sto provando a disegnare un settore dell'annulus in QML utilizzando l'oggetto Canvas. Innanzitutto, ho scritto il codice javascript e ho verificato che sia corretto eseguendolo in un browser.QML Canvas: comportamento differente nel rendering

Eccolo:

var can = document.getElementById('myCanvas'); 
var ctx=can.getContext("2d"); 
var center = { 
    x: can.width/2, 
    y: can.height/2 
}; 
var minRad = 100; 
var maxRad = 250; 

var startAngle = toRad(290); 
var endAngle = toRad(310); 

drawAxis(); 
drawSector(); 

function drawSector() { 
    var p1 = { 
    x: maxRad * Math.cos(startAngle), 
    y: maxRad * Math.sin(startAngle) 
    } 
    p1 = toCanvasSpace(p1); 

    var p2 = { 
    x: minRad * Math.cos(startAngle), 
    y: minRad * Math.sin(startAngle) 
    } 
    p2 = toCanvasSpace(p2); 

    var p3 = { 
    x: minRad * Math.cos(endAngle), 
    y: minRad * Math.sin(endAngle) 
    } 
    p3 = toCanvasSpace(p3); 
    var p4 = { 
    x: maxRad * Math.cos(endAngle), 
    y: maxRad * Math.sin(endAngle) 
    } 
    p4 = toCanvasSpace(p4); 

    ctx.beginPath(); 
    ctx.moveTo(p1.x, p1.y); 
    ctx.arc(center.x, center.y, maxRad, startAngle, endAngle); 
    ctx.lineTo(p3.x, p3.y); 
    ctx.arc(center.x, center.y, minRad, endAngle, startAngle, true); 
    ctx.closePath(); 

    ctx.strokeStyle = "blue"; 
    ctx.lineWidth = 2; 
    ctx.stroke(); 
} 


function drawAxis() { 
    ctx.beginPath(); 
    ctx.moveTo(can.width/2, 0); 
    ctx.lineTo(can.width/2, can.height); 
    ctx.stroke(); 
    ctx.beginPath(); 
    ctx.moveTo(0, can.height/2); 
    ctx.lineTo(can.width, can.height/2); 
    ctx.stroke(); 
} 

function toRad(degrees) { 
    return degrees * Math.PI/180; 
} 

function toCanvasSpace(p) { 
    var ret = {}; 
    ret.x = p.x + can.width/2; 
    ret.y = p.y + can.height/2; 
    return ret; 
} 

Here È possibile eseguire il codice di cui sopra. L'output è questo:

enter image description here

successiva, ho spostato lo stesso codice in un oggetto in tela Qml.

vedere qui il main.qml contenente Canvas:

import QtQuick 2.5 
import QtQuick.Window 2.2 

Window { 
    visible: true 
    width: 500 
    height: 500 
    x:500 

    Canvas 
    { 
     id: can 
     anchors.fill: parent 
     antialiasing: true 



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

      var center = { 
       x: can.width/2, 
       y: can.height/2 
      }; 
      var minRad = 100; 
      var maxRad = 250; 

      var startAngle = toRad(290); 
      var endAngle = toRad(310); 

      drawAxis(); 
      drawSector(); 

      function drawSector() { 
       var p1 = { 
        x: maxRad * Math.cos(startAngle), 
        y: maxRad * Math.sin(startAngle) 
       } 
       p1=toCanvasSpace(p1); 

       var p2 = { 
        x: minRad * Math.cos(startAngle), 
        y: minRad * Math.sin(startAngle) 
       } 
       p2=toCanvasSpace(p2); 

       var p3 = { 
        x: minRad * Math.cos(endAngle), 
        y: minRad * Math.sin(endAngle) 
       } 
       p3=toCanvasSpace(p3); 
       var p4 = { 
        x: maxRad * Math.cos(endAngle), 
        y: maxRad * Math.sin(endAngle) 
       } 
       p4=toCanvasSpace(p4); 

       ctx.beginPath(); 
       ctx.moveTo(p1.x, p1.y); 
       ctx.arc(center.x, center.y, maxRad, startAngle, endAngle); 
       ctx.lineTo(p3.x, p3.y); 
       ctx.arc(center.x, center.y, minRad, endAngle, startAngle, true); 
       ctx.closePath(); 

       ctx.strokeStyle="blue"; 
       ctx.lineWidth=2; 
       ctx.stroke(); 
      } 


      function drawAxis() { 
       ctx.beginPath(); 
       ctx.moveTo(can.width/2, 0); 
       ctx.lineTo(can.width/2, can.height); 
       ctx.stroke(); 
       ctx.beginPath(); 
       ctx.moveTo(0, can.height/2); 
       ctx.lineTo(can.width, can.height/2); 
       ctx.stroke(); 
      } 

      function toRad(degrees) { 
       return degrees * Math.PI/180; 
      } 

      function toCanvasSpace(p) { 
       var ret = {}; 
       ret.x = p.x + can.width/2; 
       ret.y = p.y + can.height/2; 
       return ret; 
      } 


     } 
    } 
} 

In questo caso ottengo questo output:

enter image description here

Come potete vedere c'è un'imperfezione in fondo.

Davvero non capisco perché ci sia quell'imperfezione; inoltre non capisco perché lo stesso codice dia risultati diversi.

Qualsiasi aiuto è apprezzato! Grazie

risposta

4

Il lineTop3 non è necessaria, perché quando un segmento arc viene disegnato, la linea di collegamento viene disegnata automaticamente, secondo le Canvas specifiche:

metodo

L'arco() è equivalente alla metodo ellisse() nel caso in cui i due raggi sono uguali. [...]

Quando viene richiamato il metodo ellipse(), deve procedere come segue. Prima, se il percorso dell'oggetto presenta sottotracciati, il metodo deve aggiungere una linea retta dall'ultimo punto nel sottotracciato al punto iniziale dell'arco.

Inoltre, il moveTop1 non è necessaria, perché sarebbe fatto come parte del primo arco.

Per quanto riguarda il motivo per cui la linea in eccesso viene disegnata oltre l'inizio del secondo arco, potrebbe trattarsi di un bug in Qt (forse una divisione per il numero 0 - solo indovinando qui), o forse semplicemente non lo hai calcolato posizione corretta.

+0

Può verificare che questo lo risolva. Bello. :) – Mitch

+0

Wow, confermo che questa è una soluzione! Grazie! – Mauri

Problemi correlati