Warning, /maui/mauikit/src/controls.6/DoodleCanvas.qml is written in an unsupported language. File is not indexed.

0001 import QtQuick
0002 import QtQuick.Controls
0003 
0004 /**
0005 @since org.mauikit.controls 1.0
0006 @brief The canvas element for the Doodle component.
0007 
0008 @note Use the Doodle element instead, since it has the features implemneted.
0009 */
0010 Item
0011 {
0012     id: control
0013     property alias buffer: buffer
0014     
0015     /**
0016     * 
0017     */
0018     property int brushSize : 16
0019     
0020     /**
0021     * 
0022     */
0023     property real brushOpacity : 1
0024     
0025     /**
0026     * 
0027     */
0028     property int brushShape : 1 //0 -Circular, 1 - rectangular.
0029     
0030     /**
0031     * 
0032     */
0033     property int maxBrushSize: 100
0034     
0035     /**
0036     * 
0037     */
0038     property color paintColor: "red"
0039     
0040     
0041     Canvas
0042     {
0043         id: pickCanvas
0044         width: 1
0045         height: 1
0046         visible: false
0047     }
0048     
0049     
0050     Canvas
0051     {
0052         id: buffer
0053         
0054         anchors.fill: parent
0055         
0056         property real lastX
0057         property real lastY
0058         property color paintColor: control.paintColor
0059         smooth: false
0060         
0061         function clear()
0062         {
0063             var bufferCtx = buffer.getContext("2d")
0064             bufferCtx.clearRect(0, 0, width, height)
0065             buffer.requestPaint()
0066         }
0067         
0068         MouseArea
0069         {
0070             id: mouseArea
0071             anchors.fill: parent
0072             propagateComposedEvents: false
0073             preventStealing: true
0074             
0075             property int spacing: 32
0076             
0077             property real deltaDab: Math.max(spacing / 100 * control.brushSize, 1)
0078             property var points: []
0079             property point lastDrawPoint
0080             property point startPos
0081             property point finalPos
0082             property real brushAngle: 0
0083             
0084             onPressed:
0085             {
0086                 var point = Qt.point(mouseX, mouseY)
0087                 points = []
0088                 
0089                 startPos = Qt.point(point.x, point.y)
0090                 finalPos = Qt.point(point.x, point.y)
0091                 lastDrawPoint = point
0092                 if (control.brushShape != 1)
0093                 {//if brush is not square
0094                     drawDab(point)
0095                 }
0096                 points = []
0097                 points.push(point)
0098                 
0099                 //Hide Color Picker later move it to the whole screen.
0100                 //                 colorPicker.visible = false
0101             }
0102             
0103             
0104             onPositionChanged:
0105             {
0106                 
0107                 drawDab(Qt.point(mouseX, mouseY))
0108                 
0109                 // **************** Fancy and intense bezier I don't quite understand yet:
0110                 var currentPoint = Qt.point(mouseX, mouseY)
0111                 var startPoint = lastDrawPoint
0112                 
0113                 
0114                 //Rotating the dab if brush is recangular.
0115                 if (control.brushShape == 1) {
0116                     spacing = 16
0117                     
0118                     if ( (currentPoint.x > startPoint.x))
0119                     {
0120                         // dab.brushAngle = find_angle(Qt.point(startPoint.x, startPoint.y-10),
0121                         // startPoint, currentPoint)
0122                         // dab.requestPaint()
0123                         brushAngle = find_angle(Qt.point(startPoint.x, startPoint.y-10),startPoint, currentPoint)
0124                         
0125                     } else
0126                     {
0127                         // dab.brushAngle = - find_angle(Qt.point(startPoint.x, startPoint.y-10),
0128                         // startPoint, currentPoint)
0129                         // dab.requestPaint()
0130                         brushAngle = - find_angle(Qt.point(startPoint.x, startPoint.y-10),startPoint, currentPoint)
0131                         
0132                     }
0133                 } else
0134                 {
0135                     spacing = 32
0136                 }
0137                 
0138                 // ##
0139                 var currentSpacing = Math.sqrt(Math.pow(currentPoint.x - startPoint.x, 2) + Math.pow(currentPoint.y - startPoint.y, 2))
0140                 var numDabs = Math.floor(currentSpacing / deltaDab)
0141                 
0142                 if (points.length == 1 || numDabs < 3) {
0143                     var endPoint = currentPoint
0144                 } else {
0145                     var controlPoint = points[points.length - 1]
0146                     endPoint = Qt.point((controlPoint.x + currentPoint.x) / 2, (controlPoint.y + currentPoint.y) / 2)
0147                 }
0148                 
0149                 var deltaT = 1 / numDabs
0150                 var betweenPoint = startPoint
0151                 var t = deltaT
0152                 var diff
0153                 while (t > 0 && t <= 1) {
0154                     var point = bezierCurve(startPoint, controlPoint, endPoint, t)
0155                     var deltaPoint = Math.sqrt(Math.pow(point.x - betweenPoint.x, 2) + Math.pow(point.y - betweenPoint.y, 2))
0156                     // check on bezier loop
0157                     if (diff && Math.abs(deltaPoint - deltaDab) > Math.abs(diff)) { break; }
0158                     diff = deltaPoint - deltaDab
0159                     if (Math.abs(diff <= 0.5)) {
0160                         drawDab(point)
0161                         diff = undefined
0162                         betweenPoint = point
0163                         t += deltaT
0164                     } else {
0165                         t -= diff / deltaDab * deltaT
0166                     }
0167                 }
0168                 points.push(currentPoint)
0169                 lastDrawPoint = betweenPoint
0170                 
0171             }
0172             
0173             onReleased:
0174             {
0175                 
0176                 var bufferCtx = buffer.getContext("2d")
0177                 
0178                 //saving image
0179                 // Grab Buffer image
0180                 var bufferImage = bufferCtx.getImageData(0, 0, width, height)
0181                 
0182                 
0183                 // Auto save painting
0184                 //                         saveDrawing()
0185                 
0186                 // Clear the buffer
0187                 buffer.requestPaint()
0188                 
0189                 
0190             }
0191             
0192             function drawDab(point)
0193             {
0194                 var ctx = buffer.getContext("2d")
0195                 
0196                 //Bezier Dab
0197                 // ctx.save()
0198                 // var size = toolbar.maxBrushSize //toolbar.brushSize
0199                 // var x = point.x - size / 2
0200                 // var y = point.y - size / 2
0201                 // if (x < startPos.x) { startPos.x = Math.min(0, x) }
0202                 // if (y < startPos.y) { startPos.y = Math.min(0, y) }
0203                 // if (x > finalPos.x) { finalPos.x = Math.max(x, buffer.width) }
0204                 // if (y > finalPos.y) { finalPos.y = Math.max(y, buffer.height) }
0205                 // ctx.drawImage(dab, x, y)
0206                 // ctx.restore()
0207                 // buffer.requestPaint()
0208                 
0209                 //Raster Circle:
0210                 //ctx.drawImage("brushes/circle.png", x, y, size, size)
0211                 
0212                 //Simple dab
0213                 var size = control.brushSize
0214                 ctx.fillStyle =  Qt.rgba(control.paintColor.r, control.paintColor.g, control.paintColor.b, control.brushOpacity);
0215                 var x = point.x - size / 2
0216                 var y = point.y - size / 2
0217                 
0218                 if (control.brushShape == 0)
0219                 {
0220                     ctx.beginPath();
0221                     x = point.x - size/8
0222                     y = point.y - size/8
0223                     ctx.arc(x, y, size/2 ,0,Math.PI*2,true);
0224                 } else
0225                 {
0226                     ctx.save()
0227                     ctx.translate(x+size/2,y+size/2)
0228                     ctx.beginPath()
0229                     ctx.rotate(brushAngle)
0230                     ctx.roundedRect(-size/4, -size/8, size/2, size/4, 2, 2)
0231                     ctx.restore()
0232                 }
0233                 ctx.fill()
0234                 buffer.requestPaint()
0235                 
0236             }
0237         }
0238         
0239         
0240     }
0241     
0242     // Bezier Curve
0243     function bezierCurve(start, control, end, t)
0244     {
0245         var x, y
0246         // linear bezier curve
0247         if (!control) {
0248             x = (1 - t) * start.x + t * end.x
0249             y = (1 - t) * start.y + t * end.y
0250         }
0251         // quad bezier curve
0252         else {
0253             x = Math.pow((1 - t), 2) * start.x + 2 * t * (1 - t) * control.x + t * t * end.x
0254             y = Math.pow((1 - t), 2) * start.y + 2 * t * (1 - t) * control.y + t * t * end.y
0255         }
0256         return Qt.point(x, y)
0257     }
0258     
0259     // Convert RGB to HEX
0260     function rgbToHex(r, g, b)
0261     {
0262         if (r > 255 || g > 255 || b > 255)
0263             throw "Invalid color component";
0264         return ((r << 16) | (g << 8) | b).toString(16);
0265     }
0266     
0267     function find_angle(A,B,C) {
0268         var AB = Math.sqrt(Math.pow(B.x-A.x,2)+ Math.pow(B.y-A.y,2));
0269         var BC = Math.sqrt(Math.pow(B.x-C.x,2)+ Math.pow(B.y-C.y,2));
0270         var AC = Math.sqrt(Math.pow(C.x-A.x,2)+ Math.pow(C.y-A.y,2));
0271         return Math.acos((BC*BC+AB*AB-AC*AC)/(2*BC*AB));
0272     }            
0273 }
0274 
0275 
0276 
0277