// Draw rounded rectangle centered about given point. func (c *Context) CenteredRoundedRect(center, size r2.X, cornerRadius float64) { r := cornerRadius z := center dx, dy := r2.XY(r, 0), r2.XY(0, r) dz := size / 2 dzc := dz.Conj() // Upper left, upper right, lower left, lower right corners. ul, ur, ll, lr := z-dz, z+dzc, z-dzc, z+dz c.BeginPath() c.MoveTo(ul + dx) c.ArcTo(ur, ur+dy, r) c.ArcTo(lr, lr-dx, r) c.ArcTo(ll, ll-dy, r) c.ArcTo(ul, ul+dx, r) }
func (c *myCanvas) Draw(x *canvas.Context) { if true { x.SetFillStyle(canvas.RGBA{R: 1, A: 1}) r := r2.Rect{X: 0, Size: 1 + 1i} scale := float64(72) x.Save() x.Scale(r2.XY(scale, scale)) x.FillRect(r.X, r.Size) x.BeginPath() x.Arc(r.Size, .5, 0, r2.AngleMax, true) x.SetFillStyle(canvas.RGBA{G: 1, A: 1}) x.Fill() x.LineWidth = .1 x.SetStrokeStyle(canvas.RGBA{A: .25}) x.Stroke() x.Restore() x.Save() x.SetFillStyle(canvas.RGBA{A: 1}) x.Font = "24pt Ariel" x.Translate(x.Size / 2) x.Rotate(r2.AngleMax / 8) w := x.MeasureText(c.greeting) x.FillText(c.greeting, -w/2) x.Restore() } else { x.Save() x.SetStrokeStyle(canvas.RGBA{A: .8}) x.LineWidth = 2 for i := 0; i < 1000; i++ { z := r2.XY( rand.Float64()*x.Size.X(), rand.Float64()*x.Size.Y(), ) x.SetFillStyle(canvas.RGBA{G: rand.Float32(), A: 1}) x.BeginPath() x.Arc(z, 4, 0, r2.AngleMax) x.Fill() x.Stroke() } x.Restore() } }
func canvasEvent(e jquery.Event) { c := jq(e.Target) _, l := getDrawerListener(c) if l != nil { xy := c.Offset() px := float64(e.PageX-xy.Left) / screenPixelsPerPoint py := float64(e.PageY-xy.Top) / screenPixelsPerPoint l.Event(canvasContext(c), r2.XY(px, py)) } }
func canvasContext(c jquery.JQuery) (x *canvas.Context) { x = canvas.GetContext(c) h := float64(c.Width()) w := float64(c.Height()) x.PixelsPerPoint = screenPixelsPerPoint x.PointsPerPixel = 1 / screenPixelsPerPoint x.Size = r2.XY(h*x.PointsPerPixel, w*x.PointsPerPixel) // Always work in points not pixels. x.Scale(r2.XY1(screenPixelsPerPoint)) return }
func (m *myElog) Draw(ctx *canvas.Context) { vw := &m.view err := rpc.Call("Listener.GetEventView", &struct{}{}, vw) if err != nil { panic(err) } ctx.Save() ctx.BeginPath() ctx.SetFillStyle(canvas.RGBA{A: 1, R: .95, G: .95, B: .95}) ctx.Rect(0, ctx.Size) ctx.Fill() ctx.Restore() vw.GetTimeBounds(&m.tb) // Switch to Cartesian coordinates where (0,0) is at the lower left and S is the upper right. m.margin = r2.XY(16., 24.) m.max = ctx.Size - 2*m.margin ctx.Translate(r2.XY(m.margin.X(), ctx.Size.Y()-m.margin.Y())) /* Draw and label time axis. */ { ctx.Save() ctx.SetStrokeStyle(canvas.RGBA{A: 1}) ctx.LineWidth = 1 ctx.BeginPath() ctx.MoveTo(0) ctx.LineTo(r2.XY(m.max.X(), 0)) ctx.Stroke() ctx.Font = "10px Ariel" ctx.TextBaseline = "top" ctx.TextAlign = "center" nUnit := int(.5 + m.tb.Dt/(m.tb.Round*m.tb.Unit)) x, dx := r2.XY1(0), r2.XY(m.max.X()/float64(nUnit), 0) t, dt := m.tb.Min, m.tb.Round*m.tb.Unit for i := 0; i <= nUnit; i++ { str := fmt.Sprintf("%.0f", t/m.tb.Unit) dy := r2.XY(0, 2) ctx.FillText(str, x+dy) ctx.BeginPath() ctx.MoveTo(x + dy) ctx.LineTo(x - dy) ctx.Stroke() x += dx t += dt } ctx.Font = "11px Ariel" label := fmt.Sprintf("Time in %s from %s", m.tb.UnitName, m.tb.Start.Format("2006-01-02 15:04:05")) ctx.FillText(label, r2.XY(m.max.X()/2, 14)) ctx.Restore() } { ctx.Save() dy := 7. ctx.Font = fmt.Sprintf("%.0fpt monospace", dy) ctx.TextAlign = "center" ctx.TextBaseline = "middle" black := canvas.RGBA{A: 1} stroke := canvas.RGBA{A: 1, R: 151 / 256., G: 187 / 256., B: 205 / 256.} fill := stroke fill.A = .2 labelStyle := canvas.RGBA{A: 1} ctx.SetStrokeStyle(black) ctx.SetFillStyle(fill) lastXmax := 0. idy := 0 for i := range vw.Events { e := &vw.Events[i] t := vw.Time(e).Sub(m.tb.Start).Seconds() // label := e.Type().Name label := e.String() if len(label) > 20 { label = label[:20] } dx := 1.1*ctx.MeasureText(label) + r2.XY(0, 1.5*dy) x := r2.XY(m.max.X()*(t-m.tb.Min)/m.tb.Dt, -m.max.Y()/2) if i > 0 && x.X()-.5*dx.X() < lastXmax { idy++ } else { idy = 0 } thisDy := 0. if idy != 0 { // Even stacked events go down; odd events up. if idy%2 == 0 { thisDy = float64(idy/2) * dy } else { thisDy = -float64((1+idy)/2) * dy } } // fmt.Println(idy, thisDy) x += r2.XY(0, thisDy*2) lastXmax = x.X() + .5*dx.X() ctx.CenteredRoundedRect(x, dx, 2) ctx.SetFillStyle(fill) ctx.Fill() ctx.Stroke() ctx.SetFillStyle(labelStyle) ctx.FillText(label, x) } ctx.Restore() } }
func xy(o *js.Object, n string) r2.X { return r2.XY( o.Get(n+"X").Float(), o.Get(n+"Y").Float()) }