Search code examples
htmlhtml5-canvasdartdart-editordartium

Dart, why won't my shape show up?


I'm trying to make it so at each position my mouse is going to a black circle is generated, but I can't get it to show up, I know I'm receiving input but I have no idea why my stuff isn't showing up? Is there some sort of repaint method that I'm missing? I've tried quite a few things I don't really understand how requestAnimation would work here.

What am I doing wrong?

import 'dart:html';
import 'dart:async';
import 'package:polymer/polymer.dart';

CanvasElement canvas = document.querySelector('#myPaintCanvas');
CanvasRenderingContext2D context = canvas.getContext('2d');

//circle deminsions
var centerX;
var centerY;
var radius = 15;
var PI = 3.14;

void requestRedraw(){
  window.requestAnimationFrame(scribble());
 }

void scribble(pointX, pointY){
 print("MouseX: " + pointX.toString() + " MouseY: " + pointY.toString());


context.arc(pointX, pointY, radius, 0, 2 * PI, false);
context.fillStyle = 'black';
context.fill();
context.strokeStyle = '#003300';
context.stroke();

}

void main(){
 canvas.onMouseDown.listen((onDown){

    StreamSubscription mouseMoveStream = canvas.onMouseMove.listen((onData){
     scribble(onData.client.x, onData.client.y);
    });

//to end my stream when the mouse is up
canvas.onMouseUp.listen((onData) => mouseMoveStream.cancel());
  });

}

Solution

  • You, most likely, have scaling problem due to mismatch between the canvases actual drawing dimension and it's dimension as a DOM element (canvas.width = 500; and canvas.style.width="500px";)

    Fixed scaling + some additional fixes:

    import 'dart:html';
    import 'dart:async';
    
    CanvasElement canvas = document.querySelector('#myPaintCanvas');
    CanvasRenderingContext2D context;
    
    //circle deminsions
    var centerX;
    var centerY;
    var radius = 15;
    var PI = 3.14;
    
    
    void scribble(pointX, pointY) {
      print("MouseX: " + pointX.toString() + " MouseY: " + pointY.toString());
      context.clearRect(0, 0, canvas.width, canvas.height);
      context.beginPath();
      context.arc(pointX, pointY, radius, 0, 2 * PI, false);
      context.fillStyle = 'black';
      context.fill();
      context.strokeStyle = '#003300';
      context.stroke();
      context.closePath();
    }
    
    void main() {
      canvas.width = 500;
      canvas.style.width="500px";
      canvas.height = 500;
      canvas.style.height="500px";
      context = canvas.getContext('2d');
      canvas.onMouseDown.listen((onDown) {
    
        StreamSubscription mouseMoveStream = canvas.onMouseMove.listen((onData) {
          var rec = canvas.getBoundingClientRect();
          scribble(onData.client.x- rec.left, onData.client.y - rec.top);
        });
    
        //to end my stream when the mouse is up
        document.onMouseUp.listen((onData) => mouseMoveStream.cancel());
      });
    }
    

    I added context.clearRect to make it clear where the circle is. context.beginPath(); and context.closePath(); are needed to prevent bridges between circles. document.onMouseUp instead of canvas.onMouseUp fixes problem when mouse button is released outside of the canvas.