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