Introduction
Painting is fun, painting is entertaining and painting is social. iPaint is a new way to paint, iPaint is a music composer too. You don't paint, you compose painting.
Uses and Concept
iPaint can be used by friends and family for entertainment.
iPaint's primary job is painting, its only a side effect that's its a equally good musical instrument. iPaint's primary job is to make painting fun for family and friends. With the integration of "family cloud", iPaint turns painting into family painting.
Background
There are lot many paint apps, then what is different? I encourage you to watch this video and then you will have your answer. iPaint aims to be a unique experience.
The most unique aspect is the music. You not only paint but you also compose music. Painting with iPaint is a great experience.
Development Approach
Target Platform: AIO PC
Category: Entertainment
I am building this app in WPF. I will be using the AIO PC to optimize it for big screen size and make use of the strikers as a stamp, which when pressed on the screen will fill color in the touched area.
Project Status
I have divided the workflow into three parts.
Part 1
Basic funtionality to be completed in Part 1.
Status: Complete;
Part 2
Add visual appeal. Add shine and chrome.
Status: In progress;
Part 3
Add online features.
Status: In design phase;
Future:
I plan to port it to Unity and release it for all platforms. Since I am also working on a game in Unity, my knowledge of Unity is increasing by each passing day and so is my confidence that I can build iPaint in Unity.
Unity provides much more power than a presentation framework like WPF. There is more work in Unity but you get more power. Porting in Unity is for the future as its a big undertaking and cannot be done now. I will miss the boat if I even try.
Features
Simple Painting
iPaint provides a virtual canvas to paint. iPaint supports multi-touch with no upper limit on the no of fingers it can track.
Color Filling
Besides good old basic Painting, there is also color filling. iPaint contains a lot of sketches in which the user can fill colors.
Reference Drawing
In this mode, the user is given a reference painting and his job is to build the same. Users can learn to paint and develop creativity by building paintings by other good painters and learn from their paintings.
Innovative Features
What set iPaint apart are the following features:
Collaboration
You can collaborate with other people and paint together, you don't need to be physically present to paint together, you can paint over the internet, using iPaint Cloud.
iPaint Save and Continue
Your painting are saved on your device and you can continue, modify those paintings at any time you want. You can also lock a painting to prevent other people from changing or deleting it.
Cloud Storage
All your painitngs are saved in the cloud and are available on all your devices. You can start a new painting on one device, continue it on another device and modify it on another completely different device or platform or when on the move on your phone!!!
Painting Recording and Playback
See yourself in action!!
Your painitngs are recorded and saved and anytime you can play these painting and show your friends how you made the masterpiece, each stroke, color, music is recorded and played back.
Family wall
With family wall you can have access to your family's painting and can create a copy of any of your family member's painitng and modify it for yourself. With family wall, you know what your family has been painting on iPaint. Family wall acts as a social network for your family. You can also chat with your family members while painting.
Planning to add in-app video calling when collaborating.
Music
iPaint blends the two most creative, exhilarating tasks Painting and Music, into one.
You do not draw, you compose paint. iPaint has a musical touch to painting. When you draw, you compose a note, when you fill colors you compose a hold. Its like you are painitng and composing music ALL IN ONE.
Cheackout the demo to see music and painting blended together in iPaint.
Visual Effects
iPaint is full of visual effects, which gives a feeling of peace and accomplishment when drawing. These Visual effects add to subtility of painting on a virtual canavs. These visual effects help build a sense of accomplishment as the final painting is beautiful, independent of user's painting skills.
Dynamic colors
The colors are dynamic, when you draw the colors change beautifully to build a masterpiece.
Below is a painting build with the prototype of iPaint with dynamic colors. At no point was the color changed manually, it was all dynamic.
Glide color filling
You don't need a strobe to fill color. Just hold down the screen on the point where you want to fill color and the color will spread on the screen as if its flowing from your fingure onto the screen.
Intiutive Color Picker
Changing colors in iPaint is non-obtrusive. The color palette is a circular tube with a slide. You slide on the tube to choose the desired color.
128 Musical Instruments
iPaint has about 128 instruments to choose from. From Grand Piano to Electric Guitar, iPaint has it all.
Use of Horizon specific features
Strikers
Strikers are used to fill colors and even draw.
27" Grand Touch Screen
The grand size AIO has, provides a big surface to paint.
iPaint uses of the grand screen size to provide a big canvas and support for multi-touch. There is no limit to how many people can paint simultaneously.
Surrond Sound Speakers
The high quality speakers with surround sound will produce good music. Good for the user's ears ;)
Demo
Using the code
There are three main jobs of the painting app.
- To draw
- To play sounds
- To handle social features
Code to draw
Drawing lines on the canvas.
I am using a path to draw lines.
You can check this tutorial on how to build a simple paint app. The code is taken from there. I have modified it for my use.
private PathFigure _pathFigure;
private bool _isOnCanvas;
private Path _path = new Path();
private Color _color = Colors.Black;
private const float _penWidth = 3.0f;
public void Freeze()
{
if (_pathFigure != null)
_pathFigure.Freeze();
}
public bool IsFrozen
{
get
{
return _pathFigure.IsFrozen;
}
}
public void AddToCanvas(Canvas canvas)
{
if (_isOnCanvas)
return;
_isOnCanvas = true;
PathGeometry pathGeometry = new PathGeometry();
pathGeometry.Figures = new PathFigureCollection() { _pathFigure };
_path.StrokeThickness = _penWidth;
_path.Data = pathGeometry;
canvas.Children.Add(_path);
}
public Color Color
{
get
{
return _color;
}
set
{
_color = value;
_path.Stroke = new SolidColorBrush(_color);
}
}
public int Id { get; set; }
public void Add(Point pt)
{
if (_pathFigure != null && IsFrozen)
throw new InvalidOperationException("This object is frozen");
if (_pathFigure == null)
{
_pathFigure = new PathFigure();
_pathFigure.IsClosed = false;
_pathFigure.StartPoint = pt;
_pathFigure.Segments = new PathSegmentCollection();
}
else
{
_pathFigure.Segments.Add(new LineSegment(pt, true));
}
}
<param name="canvas" /><param name="pt" />
Code to play sounds
I am using MIDI for .NET Library to play sounds. I play each note in new thread to allow multiple notes running at same time. I sleep the thread for a second and then close the midi player, thus the note plays for a second and then is turned off.
MDI for .NET provides a static object of type MidiPlayer which you use to play sounds. Before playing any sound you first open the midi player. You do that by calling MidiPlayer.OpenMidi(). By default midiplayer comes with 127 channels(instruments). Program change is used to change the channel, vol among other things. You play the note by calling play and a NoteOn object passing a delta(initial delay), channel(a byte value), the note(a string like "C0") and the volume(a byte value) to the NoteOn object.
new Thread(() =>
{
MidiPlayer.OpenMidi();
MidiPlayer.Play(new ProgramChange(0, 1, channel));
MidiPlayer.Play(wheel);
MidiPlayer.Play(new NoteOn(delta, 1, note, vol));
Thread.Sleep(1000);
MidiPlayer.Play(new NoteOff(delta, 1, note, vol));
MidiPlayer.CloseMidi();
}).Start();
Code to handle social features
I am using SignalR for communication and pushing the painting onto connected members. SignalR needs to be hosted somewhere to work. I am using Windows Azure to host SignalR and also to act as a cloud storage for all paintings.
I save the drawings in XML, storing the timeline of all points, colors and music that was played which is later uploaded to the server or used to play back the painting.
Building the home page.
The Home page is a slidehow of the Paintings. Building the background was fun.
Its all ellipses with random colors which are satcked together to give a blurred vivid background. Code to build that.
The ellipses are drawn on a canvas named 'CanvasBackground'
int x=-30,y=-30;
for (int i = 0; i < width/15*width/30; i++)
{
Ellipse ellipse = new Ellipse();
ellipse.Width = ellipse.Height = (width / 30) - radiusRandom.Next(0, height / 100);
ellipse.Fill = GetRandomColor();
ellipse.Opacity =0.7;
ellipse.Effect = new BlurEffect() { Radius = 15 };
Canvas.SetTop(ellipse, y);
Canvas.SetLeft(ellipse, x);
_backgroundCircles[i]=(ellipse);
CanvasBackground.Children.Add(ellipse);
x = x + width / 90;
if (x > width)
{
x = -30;
y = y + height / 20;
}
if (y > height)
y = 0;
}
Just to make things interesting, I animate the background a little. By randomally choosing some of these ellipses, I change their color or opacity or blurrness, it makes the background dynamic instead of boring static. Code to animate background: I use a DispatchTimer ticking every 100 seconds.
private void animateBackground(object sender, EventArgs e)
{
while (currentStack.Count <= 10)
{
currentStack.Add(_backgroundCircles[ellipseRandom.Next(_backgroundCircles.Length)]);
}
foreach (Ellipse ellipse in currentStack)
{
AnimateEllipse(ellipse);
}
if (removelRanodm.Next(10) == 2)
{
currentStack.RemoveAt(removelRanodm.Next(10));
}
}
private void AnimateEllipse(Ellipse ellipse)
{
int what = funtcionRandom.Next(3);
switch (what)
{
case 0:
ellipse.Fill = GetRandomColor();
break;
case 1:
ellipse.Opacity = opacityRandom.Next(10) / 10f;
break;
case 2:
BlurEffect effect = ellipse.Effect as BlurEffect;
effect.Radius = radiusRandom.Next(20) / 20f;
break;
default:
break;
}
}
One more thing, due to the vast number of ellipses it takes a little time to load the home page, what I do is load the page in background while showing another startscreen when the application is launched. I use a NavigationWindow with navigationbar hidden.
Code to load page in background.
Page thePage=(Page)Application.LoadComponent(new Uri("/Pages/Home.xaml", UriKind.Relative)); Action action = () =>
{
((NavigationWindow)Application.Current.MainWindow).Navigate(thePage);
if (MainNavigationWindow != null) MainNavigationWindow.ShowsNavigationUI = false;
};
Application.Current.Dispatcher.BeginInvoke(action, DispatcherPriority.Normal);
Points of Interest
I learned I am no musician while developing this app. I was trying to work together with a lot of notes until I figured out that I can't and neither can the users. I brought down the no. of notes from 600 to 300. I was reluctant in doing it but was surprised to see that it added to the fun.
History
[28.07.2013] - iMuzik was born with some drawing effects, which didn't hold.
[29.07.2013] - Improved the notes, got rid of screeching notes.
[30.07.2013] - Turned the music app into paint app. iPaint was born.
[31.07.2013] - Added family wall and turned iPaint into a family app.
[01.08.2013] - Added some nice painting effects, like sparks, glides
[02.08.2013] - Improved the performance of the app. Reduced Memory and CPU consumption.
[01.09.2013] - Prototype Complete.