Silverlight web comic
Its a silverlight page to create a simple comic with photos and text-ballons
Introduction
When the Visual Studio 2010 was still on beta I participate on a Microsoft competition from Mexico to develop an application with the new .NET framework 4.0 new the prize was a laptop. So because I like to learn new technologies (like ajax, wpf, linq, sdk of kinect, apis for google maps, google docs, Verifones TPV, fingerprints, a csc, xcode, develop for android etc). I wanted learn about silverlight because I didn't know silverlight and I like draw and I wanted my own page to create a simple comic. I ressearched if there was an existing page for create comics, but I found only a few pages, so I decide to learn silverlight and submit a silverlight application to create a webcomic for the competition.
Background
I was develop a simple program to draw simple figures in a canvas on 2D and 3D with C++ Builder when I was studying the carrer. The exe of my simple paint on 2D is here and on 3D is here. After I did a more simple paint on a java applet and flash. So I knew about how to draw in canvas, with the events drag and drop of the canvas, and the canvas on silverlight include the methos for drag and drop, and print the canvas in a easy way. You can watch the comic working here. The instructions and the page is in spanish because the competition was on Mexico, so I develop the page on spanish.
Using the code
I began for the most basic example I put a set of canvas on a webpage between a MainCanvas, I set the property AllowDrop in true and use the drag and drop events to drag and drop images from my pc to the webpage. Like this
<Canvas Height="800" HorizontalAlignment="Left" Margin="0,0,0,0" Name="canvasComic" VerticalAlignment="Top" Width="735" Background="White">
<Canvas Canvas.Left="17" Canvas.Top="16" Height="198" Name="box1" Width="705" Background="#FFFC1717" AllowDrop="True" />
<Canvas Canvas.Left="17" Canvas.Top="226" Height="181" Name="box2" Width="220" AllowDrop="True" Background="#FFDFF206" />
<Canvas Canvas.Left="260" Canvas.Top="226" Height="181" Name="box3" Width="220" AllowDrop="True" Background="#FF17A00C" />
<Canvas Canvas.Left="502" Canvas.Top="226" Height="181" Name="box4" Width="220" AllowDrop="True" Background="#FF03F8F8" />
<Canvas Canvas.Left="17" Canvas.Top="421" Height="160" Name="box5" Width="345" AllowDrop="True" Background="#FF155BCB"/>
<Canvas Canvas.Left="378" Canvas.Top="421" Height="160" Name="box6" Width="345" AllowDrop="True" Background="#FFAE16F2" />
</Canvas>
After in the code I aggregate a function to all canvas for the event drop for receive and resize the image to the size of the canvas. The code is the next
Private Sub Canvas_Drop(ByVal sender As System.Object, ByVal e As System.Windows.DragEventArgs) Handles MyBase.Drop, box1.Drop, box2.Drop, box3.Drop, box4.Drop, box5.Drop, box6.Drop Dim dataObject As IDataObject = e.Data 'For know what is the canvas of the image was dropped Dim dropPoint As Point = e.GetPosition(sender) 'For know the position of the image was dropped If dataObject.GetDataPresent(DataFormats.FileDrop) Then 'If a file was dropped Dim files As FileInfo() = DirectCast(dataObject.GetData(DataFormats.FileDrop), FileInfo()) 'Get the info of the file dropped If files.Length > 0 Then sender.Children.Clear() 'A filter to only accept images files (.jpg, .png or gifs) If files(0).Extension.ToLower = ".jpg" Or files(0).Extension.ToLower = ".png" Or files(0).Extension.ToLower = ".gif" Then Dim bitmapImage As New System.Windows.Media.Imaging.BitmapImage() 'For copy the image dropped bitmapImage.SetSource(files(0).OpenRead()) 'Copy the image to a bitmap Dim newImage As New Image() 'Create a new image for copy the image 'For put the image on the coordinates 0,0 dropPoint.Y = 0 dropPoint.X = 0 'Resize the image to the size of the canvas newImage.Width = sender.Width newImage.Height = sender.Height newImage.Source = bitmapImage newImage.SetValue(Canvas.TopProperty, dropPoint.Y) newImage.SetValue(Canvas.LeftProperty, dropPoint.X) newImage.Stretch = Stretch.Fill 'Add the image at the canvas sender.Children.Add(newImage) End If End If End If End Sub
For the ballons I create a class, to save a textblock for include the text for the ballon, the posiotion of the ballon, the type of the ballon, and the figure for the ballon, and events for move the ballons around the canvas
Imports System.IO Imports System.Windows.Printing Imports System.Windows.Media.Imaging Public Class cFigure Public tb As New TextBlock Public type As MainPage.eFigure Public iNumber As Integer Public iChildren As Integer Public bAux As Boolean Public iPosition As Point Public newImage As New Image() ''' <summary> ''' Set the ballon and the text and the mouse events ''' </summary> ''' <param name="sText">Text for the ballon</param> ''' <param name="pPosition">Coordinates (x,y) for the location of the ballon</param> ''' <param name="typeFigure">The Type of figure</param> ''' <param name="iActualBallon">The number of the ballon in the list of ballons</param> ''' <remarks></remarks> Public Sub SetImage(ByVal sText As String, ByVal pPosition As Point, ByVal typeFigure As MainPage.eFigure, ByVal iActualBallon As Integer) Dim sFigure As String = "" 'Set the text to the combobox tb.Text = " " + sText 'Save the color of the text tb.Foreground = New SolidColorBrush(Colors.Black) 'Set options to center the text and automatic wordwrap tb.TextAlignment = System.Windows.TextAlignment.Center tb.TextWrapping = TextWrapping.Wrap type = typeFigure iNumber = iActualBallon 'Set the image of the ballon Select Case type Case MainPage.eFigure.leftCloud sFigure = "Images/left_cloud.png" Case MainPage.eFigure.rightCloud sFigure = "Images/right_cloud.png" Case MainPage.eFigure.rightOval sFigure = "Images/rght_oval.png" Case MainPage.eFigure.leftOval sFigure = "Images/left_oval.png" Case MainPage.eFigure.rightBox sFigure = "Images/right_box.png" Case MainPage.eFigure.leftBox sFigure = "Images/left_box.png" Case MainPage.eFigure.Box sFigure = "Images/box.png" End Select 'The uri of the image of the ballon Dim uriImage As New Uri(sFigure, UriKind.Relative) 'Get the stream of the image of the ballon Dim oImageStream As Stream = Application.GetResourceStream(uriImage).Stream 'Create a new Image for the ballon Dim oImage As New BitmapImage() 'Set the image of the ballon oImage.SetSource(oImageStream) 'Set the size proportional to the text only for the ballons. newImage.Width = tb.ActualWidth + 50 newImage.Height = tb.ActualHeight 'If the figure is different of the box add a space for center the text If type <> MainPage.eFigure.Box Then newImage.Height += 30 tb.SetValue(Canvas.TopProperty, pPosition.Y + 8) Else newImage.Height += 10 tb.SetValue(Canvas.TopProperty, pPosition.Y + 5) End If tb.SetValue(Canvas.LeftProperty, pPosition.X + 18) newImage.SetValue(Canvas.LeftProperty, pPosition.X) newImage.SetValue(Canvas.TopProperty, pPosition.Y) iPosition.Y = tb.GetValue(Canvas.TopProperty) iPosition.X = tb.GetValue(Canvas.TopProperty) 'Set the ballon with text newImage.Source = oImage newImage.Stretch = Stretch.Fill 'Set the events for the ballon AddHandler newImage.MouseLeftButtonDown, AddressOf Image_Mouse_Button_Down AddHandler newImage.MouseMove, AddressOf Image_Mouse_Button_Move AddHandler newImage.MouseLeftButtonUp, AddressOf Image_Mouse_Button_Up End Sub ''' <summary> ''' Set the position of the ballon ''' </summary> ''' <param name="pPosition">Coordinates (x,y) for the location of the ballon</param> ''' <remarks></remarks> Public Sub SetPosition(ByVal pPosition As Point) newImage.SetValue(Canvas.TopProperty, pPosition.Y) newImage.SetValue(Canvas.LeftProperty, pPosition.X) If type <> MainPage.eFigure.Box Then tb.SetValue(Canvas.TopProperty, pPosition.Y + 8) Else tb.SetValue(Canvas.TopProperty, pPosition.Y + 5) End If tb.SetValue(Canvas.LeftProperty, pPosition.X + 18) iPosition.Y = tb.GetValue(Canvas.TopProperty) iPosition.X = tb.GetValue(Canvas.LeftProperty) End Sub Private Sub Image_Mouse_Button_Down(ByVal sender As System.Object, ByVal e As System.Windows.Input.MouseButtonEventArgs) bAux = True MainPage.iActualCloud = iNumber End Sub Private Sub Image_Mouse_Button_Move(ByVal sender As System.Object, ByVal e As System.Windows.Input.MouseEventArgs) End Sub Private Sub Image_Mouse_Button_Up(ByVal sender As System.Object, ByVal e As System.Windows.Input.MouseButtonEventArgs) bAux = False End Sub End Class
After I aggregate the ballons. I agregate one textbox for include the text for the ballons and 7 buttons for different types of the ballons, and I got the images of the ballons and save the images on the folder Images of the silverlight application.
So for include a ballon you need set the text and press the button of the ballon that you want to add and drag to the canvas. I add all the ballons to a ComboBox for that user chooste a ballon and can modify the position of the ballons.
With a printdocument I print the comic that contains all the canvas
' create an instance of PrintDocument
Dim document As New PrintDocument()
' Add the handlers for print canvasComic is the canvas that contains the box of the page
AddHandler document.BeginPrint, Function(s, args) CanvasBeginPrint(s, args)
AddHandler document.PrintPage, Function(s, args) CanvasPrintPage(s, args, canvasComic)
AddHandler document.EndPrint, Function(s, args) CanvasEndPrint(s, args, canvasComic)
' call the Print() with a proper name which will be visible in the Print Queue
document.Print("Printing Comic")
Points of Interest
At this moment I only save the ballons on a xml. I'll ressearch how to save the images add to the canvas. With the new HTML5 canvas I think that I'll do this comic with html5 and maybe php and mysql for save the comics, at least the canvas of html5 include a function to save a canvas like an image.
But at this moment I don't know how to save a canvas like a image with silverlight. So before I change to html5 I'll add more functionalities to this project. Like set the size, font, and color for the text of the ballons, save on a sql databases, and add a predefined set of canvas, and a option to save a comic with more than one page. And within each page a comic a part to the user save comments for the comic.
I apreciate your suggest, dudes, comments and report the bugs that you can find.