For my open-source software animatoon, I will add some animation functions.
So, I have created a little application to test the animation, and when it will be ok, I will add it in animatoon.
For the moment, it's an "independant" application .
version 0.4
Code: Select all
; 2D Animation programm
; blendman July 2021 - licence MIT
;{ changes
; 6.7.2021 0.4
; // new
; - add own toolbar (with some tools : paint, move)
; - Zoom canvas, movecanvas
; - we can draw on zoomed and moved canvas
; - now, the canvas use the vectordrawinglib (for zoom)
; // changes
; - layeranim : some modifications in UI (GUI colors, position of alpha)
; - layeranim : dble clic on layeranim alpha->set the alpha of layeranim.
; - canvasdrawing : add space to move the canvas
; 5.7.2021 0.3
; - panel tool : size, alpha, color
; - set layeranim name$, add layeranim alpha (display), image import on currentframe
; - layeranim add butons : visible, lock, up, down
; - display layeranim if visible
; - draw on layeranim if not lock and visible
; - layeranim improved
; - GUi add icones
; //fixes
; - clear layeranim frame doesn't all drawing
; - canvas doesn't draw correctly layeranim if frame hasn't image
; - canvas draw image of another layeranim if no image at frame current
; 2.7.2021 0.2
; - add stroke, ognion skinning, export (all images), bugfixes
; 1.7.2021 0.1
; - we can play animation
; - When draw, if not keyframe, it add image
; - Canvas draw
; - gadgets timeline (addlayeranim, addkeyframe, frame start, end, current, fps, speed, button play/stop)
; - timeline (keyframe, start, end)
;}
; init the image lib
UsePNGImageDecoder() : UsePNGImageEncoder() : UseJPEGImageDecoder() : UseJPEGImageEncoder()
#ProgramVersionAnim ="0.4"
Enumeration
; images & icones
#ico_visible=0 : #ico_Lock : #ico_Up : #ico_Down : #ico_brush : #ico_eraser : #ico_shape : #ico_Line : #ico_move : #ico_Scale : #ico_Rotate
#img_brushcolor
#Img_Final
#img_last ; the last image, to not erase an image before it
; gadgets
#G_Toolbar=0
#G_TB_Brush : #G_TB_Shape : #G_TB_Line : #G_TB_Eraser : #G_TB_Clear
#G_TB_Move : #G_TB_Scale : #G_TB_Rotate
#G_canvasDrawing
#G_cont_CanvasDrawing
#G_cont_CanvasDrawingInside
#G_ContPanelTool
#G_PanelTool
#G_ToolColor
#G_ToolSizeTB : #G_ToolSizeSG
#G_ToolAlphaTB : #G_ToolAlphaSG
#G_ToolShape ; image, circle.
#G_ToolType ; brush=0, eraser=1
; layeranim
#G_LayerAnimVisible
#G_LayerAnimLock
#G_LayerAnimAlpha
#G_LayerAnimAdd : #G_LayerAnimDel : #G_LayerAnimUp : #G_LayerAnimDown :
; timeline
#G_cont_Timeline
#G_AddFrame : #G_DelFrame
#G_OgnionPrevious : #G_OgnionNext
#G_FrameStart : #G_FrameEnd : #G_FrameCurrent :
#G_FrameSpeed : #G_FrameFPS :
#G_PlayAnim : #G_StopAnim
#G_TimeLine
#G_AnimProperties
; menu
#menu_FileOpen=0
#menu_FileSave
#menu_FileExport
#Menu_LayerClear
#Menu_LayerClearLayerAnim
#Menu_LayerImportImage
#Menu_Edit_CopyKeyframe
#Menu_Edit_Pastekeyframe
; action
#action_brush=0
#action_eraser
EndEnumeration
;{ structures& globals
Structure sImageFrame
x.w
y.w
Frame.w
image.i
EndStructure
Structure sLayerAnim
Array Image.sImageFrame(0)
position.w ; position in Y, in the layeranima list
x.w : y.w
visible.a : lock.a : alpha.a
selected.a
color.i
type.a
name$
EndStructure
Global Dim LayerAnim.sLayerAnim(0)
Global NbFrame=-1, NblayerAnim=-1, NBlayerTotal, ImageCurrent, LayerAnimID
Structure sAnimationParameters
FPS.w
Speed.f
FrameCurrent.w
FrameStart.w
FrameEnd.w
OgnionPrevious.a
OgnionNext.a
EndStructure
Global Anim.sAnimationParameters
With Anim
\fps = 12
\Speed=1.0
\FrameCurrent=0
\FrameStart=0
\FrameEnd=12
EndWith
Structure sPoint
x.f : y.f
EndStructure
Structure sStroke
Array Dot.sPoint(0)
EndStructure
Global Dim Stroke.sStroke(0), StrokeID, nbStroke=-1, DotCurrent, nbdot=0
Global previousx, previousy, canvasX, canvasY,Zoom,docW,docH
Structure sBrush
alpha.a
size.w
ShapeType.a
Color.i
EndStructure
Global Dim Brush.sBrush(1), action=#action_brush
brush(i)\alpha = 255
brush(i)\size = 10
;}
;{ macros & procedures
; distance, direction..
Macro GetDistance(x1,y1,x2,y2)
Int(Sqr((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1)) )
EndMacro
Macro GetDirection(x1,y1,x2,y2)
ATan2((y2- y1),(x2- x1))
EndMacro
Declare UpdateTimeLine()
Procedure FreeImage2(image)
If IsImage(image) : FreeImage(image) : EndIf
EndProcedure
Procedure LoadImage2(image,file$)
If LoadImage(image, GetCurrentDirectory()+"data\Theme\Animatoon\icones\"+file$) : EndIf
EndProcedure
Procedure AddSpinGadget(gad,x,y,w,h,min,max,tip$=#Empty$, val=0)
SpinGadget(gad,x,y,w,h,min,max,#PB_Spin_Numeric)
SetGadgetState(gad,val)
GadgetToolTip(gad,tip$)
EndProcedure
Procedure AddButtonGadget(gad,x,y,w,h,text$,tip$=#Empty$,image=-1,option=-1)
If image=-1
ButtonGadget(gad,x,y,w,h,text$)
If option<>-1
ButtonGadget(gad,x,y,w,h,text$,option)
EndIf
Else
ButtonImageGadget(gad,x,y,w,h,ImageID(image))
If option<>-1
ButtonImageGadget(gad,x,y,w,h,ImageID(image),option)
EndIf
EndIf
GadgetToolTip(gad,tip$)
EndProcedure
Procedure AddCheckBoxGadget(Gad,x,y,w,h,text$=#Empty$,name$=#Empty$,tip$=#Empty$,value=0)
If name$<> #Empty$
TextGadget(#PB_Any,x,y,50,h,name$)
x+50
EndIf
CheckBoxGadget(gad,x,y,w,h,texte$)
GadgetToolTip(gad,tip$)
SetGadgetState(gad,value)
EndProcedure
Procedure AddSTringTBGadget(gadTB,gadSG,x,y,wtb,wsg,min,max,val=0,name$=#Empty$,tip$=#Empty$,wtg=30)
; string gadget, name and trackbar
; wtb = width for trackbar
; wsg = width of stringgagdet
; wtg = width for the text gadget
; to color the gadget
; color = GetWindowColor(GetActiveWindow())
; To add a gadget Name+trackbar +stringgadget !! test pour ajouter un gadget "spécial : nom, trackbar et stringgadget
h = 25
If name$ <>#Empty$
If TextGadget(#PB_Any, x+5, y, wtg, h, name$)
; ;SetGadgetColor(gadName, #PB_Gadget_BackColor, color)
EndIf
Else
wtg = 0
EndIf
If TrackBarGadget(gadTB, x+2+wtg, y, wtb, h, min, max)
; SetGadgetColor(gadTB, #PB_Gadget_BackColor, color)
SetGadgetState(gadTB, val)
GadgetToolTip(gadTB, tip$)
If StringGadget(GadSG,x+4+wtg+wtb, y, wsg, h, Str(val),#PB_String_Numeric)
; SetGadgetColor(GadSG, #PB_Gadget_BackColor, color)
SetGadgetText(GadSG, Str(val))
GadgetToolTip(GadSG, tip$)
ProcedureReturn 1
EndIf
EndIf
EndProcedure
Procedure AddKeyFrame()
;NbFrame+1
;Frame.sFrame(0)
EndProcedure
Procedure LayerAnimAdd()
NblayerAnim+1
i = NblayerAnim
NBlayerTotal+1
ReDim LayerAnim.sLayerAnim(i)
With LayerAnim(i)
\name$="Layer"+NBlayerTotal
\position = i
\image(0)\image=-1
\alpha = 255
\visible = 1
EndWith
EndProcedure
Procedure LayerAnimMove(up=1)
k = LayerAnimID
s = ArraySize(LayerAnim())
oldpos = LayerAnim(k)\position
copy.sLayerAnim
copy = LayerAnim(k)
; move up
If up=1
Newpos = oldpos+1
If Newpos>s
Newpos=s
Else
If k<s
newpos = LayerAnim(k+1)\position
LayerAnim(k) = LayerAnim(k+1)
LayerAnim(k+1) = copy
LayerAnim(k+1)\position = newpos
EndIf
EndIf
ElseIf up = -1
Newpos = oldpos-1
If Newpos<0
Newpos=0
Else
If k>0
newpos = LayerAnim(k-1)\position
LayerAnim(k) = LayerAnim(k-1)
LayerAnim(k-1) = copy
LayerAnim(k-1)\position = newpos
EndIf
EndIf
EndIf
LayerAnim(k)\position = oldpos
UpdateTimeLine()
EndProcedure
Procedure PaintbrushLine(x1,y1,x2,y2)
Shared UseFreeMouse
If UseFreeMouse
x2 = previousx
y2 = previousy
EndIf
thesize = brush(action)\size
pas.d = 30*0.01
; the distancebetween Two dots
distBetween2dot.d = Thesize*Pas
;distance between two vectors
Distance.d = GetDistance(x1,y1,x2,y2)
; number of dots to draw
CountPoint = Distance/(Pas * Thesize)
; color
r = Red(brush(action)\Color)
g = Green(brush(action)\Color)
b = Blue(brush(action)\Color)
; Draw
DrawingMode(#PB_2DDrawing_AlphaBlend)
If distBetween2dot <= distance And CountPoint > 0
direction.d = GetDirection(x1, y1, x2, y2)
For N = 0 To CountPoint
; then draw the dots
x3 = x1 + n * distBetween2dot * Sin(direction)
y3 = y1 + n * distBetween2dot * Cos(direction)
Circle(x3,y3,thesize/2,RGBA(r,g,b,brush(action)\alpha))
Next
Else
Circle(x1,y1,thesize/2,RGBA(r,g,b,brush(action)\alpha))
x3 = x1
y3 = y1
EndIf
previousx = x3
previousy = y3
EndProcedure
Procedure AddDot(x1,y1,size = 0)
i = nbdot
If i >0
xx = x1
yy = y1
StartX = Stroke(StrokeID)\Dot(i-1)\x
StartY = Stroke(StrokeID)\Dot(i-1)\y
dist = GetDistance(xx,yy,StartX,StartY)
If dist > size
ok = 1
EndIf
Else
ok = 1
EndIf
If ok
ReDim Stroke(StrokeID)\Dot(nbdot)
Stroke(StrokeID)\Dot(nbdot)\x = x1
Stroke(StrokeID)\Dot(nbdot)\y = y1
nbdot+1
EndIf
EndProcedure
Procedure BrushUpdate(event)
Select event
Case #G_ToolSizeSG, #G_ToolSizeTB
If event=#G_ToolSizeSG
size = Val(GetGadgetText(#G_ToolSizeSG))
Else
size = GetGadgetState(#G_ToolSizeTB)
EndIf
SetGadgetState(#G_ToolSizeTB,size)
SetGadgetText(#G_ToolSizeSG,Str(size))
brush(action)\size = size
Case #G_ToolColor
If EventType()= #PB_EventType_LeftClick
color=ColorRequester(brush(action)\Color)
If color >-1
brush(action)\color=color
If StartDrawing(ImageOutput(#img_brushcolor))
Box(0,0,OutputWidth(),OutputHeight(),color)
StopDrawing()
EndIf
SetGadgetState(#G_ToolColor,ImageID(#img_brushcolor))
EndIf
EndIf
Case #G_ToolAlphaTB, #G_ToolAlphaSG
If event=#G_ToolAlphaSG
a = Val(GetGadgetText(#G_ToolAlphaSG))
Else
a = GetGadgetState(#G_ToolAlphaTB)
EndIf
SetGadgetState(#G_ToolAlphaTB,a)
SetGadgetText(#G_ToolAlphaSG,Str(a))
brush(action)\alpha = a
EndSelect
EndProcedure
Procedure UpdateCanvas(draw=0,x=-1,y=-1)
Shared UseFreeMouse
; UseFreeMouse
; 0 : to use the stroke()\dot() and have undo.
; 1 : not use the dot, but a better free line
UseFreeMouse = 1
Define cx=0, cy=0, z.d=0
z.d = Zoom * 0.01
k = LayerAnimID
j = anim\FrameCurrent
w = docW
h = docH
If draw =2
Else
If j > ArraySize(LayerAnim(k)\Image())
ReDim LayerAnim(k)\Image(j)
LayerAnim(k)\Image(j)\image = -1
EndIf
; create image if needed
If draw = 1 And LayerAnim(k)\lock = 0 And LayerAnim(k)\visible = 1
If Not IsImage(LayerAnim(k)\Image(j)\image) Or LayerAnim(k)\Image(j)\image< #img_last
LayerAnim(k)\Image(j)\image = CreateImage(#PB_Any, w,h,32,#PB_Image_Transparent)
EndIf
EndIf
; draw on current image
img = LayerAnim(k)\Image(j)\image
If draw And LayerAnim(k)\lock = 0 And LayerAnim(k)\visible = 1
If StartDrawing(ImageOutput(img))
DrawingMode(#PB_2DDrawing_AlphaBlend)
If UseFreeMouse = 1
PaintbrushLine(x,y,previousx,previousy)
Else
If ArraySize(Stroke(StrokeID)\Dot())>DotCurrent+1
With Stroke(StrokeID)
If ArraySize(\Dot())=0
PaintbrushLine(\Dot(0)\x,\Dot(0)\y,\Dot(0)\x,\Dot(0)\y)
Else
For i=DotCurrent To ArraySize(\Dot())-1
PaintbrushLine(\Dot(i+1)\x,\Dot(i+1)\y,\Dot(i)\x,\Dot(i)\y)
Next
EndIf
DotCurrent = ArraySize(\Dot())
EndWith
EndIf
EndIf
StopDrawing()
EndIf
EndIf
EndIf
; update the canvas
c= 90 ; backgroundcolor of canvas
If StartDrawing(ImageOutput(#Img_Final))
; Box(0,0,OutputWidth(), OutputHeight(), RGB(c,c,c))
DrawingMode(#PB_2DDrawing_AllChannels)
Box(0,0, OutputWidth(), OutputHeight(), RGBA(255,255,255,255))
DrawingMode(#PB_2DDrawing_AlphaBlend)
; ognion skining previous
j = anim\FrameCurrent
s = ArraySize(LayerAnim())
For k= 0 To s
If LayerAnim(k)\visible
If (j-anim\OgnionPrevious)>=0
For i =(j-anim\OgnionPrevious) To j
If ArraySize(LayerAnim(k)\Image())>i
If LayerAnim(k)\Image(i)\image >#img_last
a = LayerAnim(k)\alpha*0.5
img_2 = LayerAnim(k)\Image(i)\image
DrawAlphaImage(ImageID(img_2),cx,cy, a)
EndIf
EndIf
Next
EndIf
EndIf
Next
; draw the layeranim images for the current frame
; j = anim\FrameCurrent
For i=0 To s
With LayerAnim(i)
If \visible
If ArraySize(\Image())>=J
img = LayerAnim(i)\Image(j)\image
If img >#img_last
DrawAlphaImage(ImageID(img),cx,cy,\alpha)
ok=1
Else
;{
ok = 0
;}
EndIf
EndIf
If ok = 0
; check if we have an image before this frame
For jj=j To 0 Step-1
If ArraySize(\Image()) > =jj
img = LayerAnim(i)\Image(jj)\image
If img >#img_last
DrawAlphaImage(ImageID(img),cx,cy,\alpha)
Break
EndIf
EndIf
Next
EndIf
EndIf
EndWith
Next
; ognion skining next
k=LayerAnimID
If LayerAnim(k)\visible
For i =j To (j+anim\OgnionPrevious)
Next
EndIf
StopDrawing()
EndIf
If StartVectorDrawing(CanvasVectorOutput(#G_canvasDrawing))
AddPathBox(0, 0, GadgetWidth(#G_canvasDrawing), GadgetHeight(#G_canvasDrawing))
VectorSourceColor(RGBA(c,c,c,255))
FillPath()
MovePathCursor(canvasX,canvasY) ; the canvas position
ScaleCoordinates(z,z)
DrawVectorImage(ImageID(#Img_Final))
StopVectorDrawing()
EndIf
EndProcedure
Procedure UpdateTimeLine()
; size of a layer and keyframe
Shared LayerAnimH, LayerAnimW,LayerAnimAlphaX
w = 20
h = 20 : LayerAnimH = h
w1=200 : LayerAnimW = w1; max
w2=10
w4=80
LayerAnimAlphaX=6
xtl = w1-w4-6
If StartDrawing(CanvasOutput(#G_TimeLine))
; draw the background of the timeline and layeranim
c = 90
Box(0,0,OutputWidth(),OutputHeight(),RGB(c,c,c))
; DrawThe layer Animation
For i=0 To ArraySize(LayerAnim())
DrawingMode(#PB_2DDrawing_AllChannels)
With LayerAnim(i)
y = (2+h) * (ArraySize(LayerAnim())-i)
c= 120
; draw the background box
Box(0,y, OutputWidth(), h, RGBA(c,c,c,255))
c= 130
; draw the box for the layer anim
Box(0,y, w1, h, RGBA(c,c,c,255))
; if selected, draw another color
If LayerAnimID=i
c=120
Box(0,y, OutputWidth(), h, RGBA(c+30,c+20,c,255))
c=170
Box(0,y, w1, h, RGBA(c,c,c,255))
EndIf
x=3
; draw icone (visible, lock)
If LayerAnim(i)\visible
DrawAlphaImage(ImageID(#ico_visible),x,y)
EndIf
If LayerAnim(i)\lock
DrawAlphaImage(ImageID(#ico_Lock),18+x,y)
EndIf
; name of the layeranim
DrawingMode(#PB_2DDrawing_Transparent)
DrawText(40,y,\name$)
; alpha of the layeranim
DrawingMode(#PB_2DDrawing_AlphaBlend)
Box(xtl,y+1,w4,h-2,RGBA(0,0,0,40))
DrawingMode(#PB_2DDrawing_AlphaBlend)
Box(xtl,y+1,(w4*\alpha)/255,h-2,RGBA(0,0,255,70))
EndWith
Next
DrawingMode(#PB_2DDrawing_AlphaBlend)
; draw the separation
Box(w1,0,w2,OutputHeight(),RGBA(200,200,200,255))
; Draw the keyframe
x1 = w1+w2+2
w3 =OutputWidth() - w1-w2
For i=0 To w3/w
LineXY(x1+i*w,0,x1+i*w,OutputHeight(),RGBA(255,255,255,180))
Next
; Draw the utilities for anim (start /end cursor, current frame cursor)
Box(x1+(Anim\FrameCurrent)*w,0,w,OutputHeight(),RGBA(200,150,150,140))
Box(x1+(Anim\FrameStart)*w,0,2,OutputHeight(),RGBA(0,255,255,255))
Box(x1+(Anim\FrameEnd+1)*w,0,2,OutputHeight(),RGBA(255,0,0,255))
StopDrawing()
EndIf
UpdateCanvas()
EndProcedure
Procedure EventTimeLine()
Shared LayerAnimW, LayerAnimH, LayerAnimAlphaX
If EventType()=#PB_EventType_LeftButtonDown Or EventType()=#PB_EventType_LeftDoubleClick Or (EventType() = #PB_EventType_MouseMove And GetGadgetAttribute(#G_TimeLine, #PB_Canvas_Buttons) & #PB_Canvas_LeftButton)
x = GetGadgetAttribute(#G_TimeLine, #PB_Canvas_MouseX)
y = GetGadgetAttribute(#G_TimeLine, #PB_Canvas_MouseY)
If EventType() = #PB_EventType_LeftButtonDown
;Select the layer anim
LayerAnimID = ArraySize(LayerAnim())- y/LayerAnimH
If LayerAnimID> ArraySize(LayerAnim())
LayerAnimID= ArraySize(LayerAnim())
ElseIf LayerAnimID<0
LayerAnimID=0
EndIf
EndIf
If x < LayerAnimW
If x<40
If EventType() = #PB_EventType_LeftButtonDown
id = ArraySize(LayerAnim())-y/LayerAnimH
If id> ArraySize(LayerAnim())
id= ArraySize(LayerAnim())
EndIf
If x<21
LayerAnim(id)\visible = 1-LayerAnim(id)\visible
Else
LayerAnim(id)\lock = 1-LayerAnim(id)\lock
EndIf
EndIf
Else
; set the alpha of layeranim
If x > LayerAnimW-(82) And x<LayerAnimW-2
If EventType()=#PB_EventType_LeftDoubleClick
alpha = Val(InputRequester("Transparency",
"Set the transparency For the layeranim",
Str(LayerAnim(LayerAnimID)\alpha)))
If alpha>=0 And alpha <=255
LayerAnim(LayerAnimID)\alpha = alpha
EndIf
Else
LayerAnim(LayerAnimID)\alpha = (x-(LayerAnimW-82))*255/80
EndIf
If LayerAnim(LayerAnimID)\alpha<0
LayerAnim(LayerAnimID)\alpha=0
ElseIf LayerAnim(LayerAnimID)\alpha > 255
LayerAnim(LayerAnimID)\alpha = 255
EndIf
Else
If EventType() = #PB_EventType_LeftDoubleClick
name$ = InputRequester("LAyerAnim", "Name","");LayerAnim(LayerAnimID)\name$)
If name$<>#Empty$
LayerAnim(LayerAnimID)\name$ = name$
UpdateTimeLine()
EndIf
EndIf
EndIf
EndIf
Else
x = Round((x-LayerAnimW-15)/20,#PB_Round_Down)
If x <0
x=0
EndIf
Anim\FrameCurrent = x
SetGadgetState(#G_FrameCurrent, Anim\FrameCurrent)
EndIf
UpdateTimeLine()
EndIf
EndProcedure
Procedure WindowLayerAnim()
; If OpenWindow(#Win_LayerAnim,0,0,w,h,"LayerAnim properties",#PB_Window_SystemMenu)
; EndIf
EndProcedure
;}
If ExamineDesktops()
w=DesktopWidth(0)
h=DesktopHeight(0)
EndIf
If OpenWindow(0, 0, 0, w, h, "Animatoon - animation v"+#programVersionAnim, #PB_Window_SystemMenu|#PB_Window_MaximizeGadget|#PB_Window_Maximize|#PB_Window_MinimizeGadget)
ProjectName$ = "Project"+FormatDate("%dd%mm%yyyy%hh%ii%ss", Date())
Zoom = 100 : z.d=zoom * 0.01 : c = 150 ; color theme
SetWindowColor(0, RGB(c,c,c))
;{ menu
CreateMenu(0,WindowID(0))
MenuTitle("File")
MenuItem(#menu_FileOpen, "Open")
MenuItem(#menu_FileSave, "Save")
MenuItem(#menu_FileExport, "Export")
MenuTitle("View")
MenuTitle("Layer")
;MenuItem(#Menu_LayerClearLayerAnim, "Clear LayerAnim (all frames)")
MenuItem(#Menu_LayerClear, "Clear current frame on LayerAnim")
MenuItem(#Menu_LayerImportImage, "Import image on current frame")
CreateStatusBar(0,WindowID(0)) : AddStatusBarField(100) : AddStatusBarField(100)
;}
;{ load icone
LoadImage2(#ico_visible,"view.png") : LoadImage2(#ico_Lock,"locked.png")
LoadImage2(#ico_Up,"up.png") : LoadImage2(#ico_Down,"down.png")
LoadImage2(#ico_brush,"brush.png") : LoadImage2(#ico_shape,"circle.png")
;}
;{ gadgets
w = 800 : h=600
docW = w : docH = h
If CreateImage(#Img_Final,docW,docH,32,#PB_Image_Transparent) : EndIf
wp = 200 ; width panel tool
x = wp
h1=170 ; height of timeline
tbh = 30 ; toobar height
canvasW = WindowWidth(0)-wp-10
canvasH = WindowHeight(0)-h1-MenuHeight()-StatusBarHeight(0)-tbh
canvasX = canvasW/2-(z*docW)/2 : canvasY = canvasH/2-(z*docH)/2
c = 150 ; color theme
If ContainerGadget(#G_Toolbar,0,0,WindowWidth(0),tbh)
SetGadgetColor(#G_Toolbar,#PB_Gadget_BackColor, RGB(c,c,c))
x = 10 : y = 0 : h=28 : b = 3
AddButtonGadget(#G_TB_Brush,x,y,h,h,"","",#ico_brush,#PB_Button_Toggle) : x+h+b
AddButtonGadget(#G_TB_Shape,x,y,h,h,"","",#ico_shape,#PB_Button_Toggle) : x+h+b
CloseGadgetList()
EndIf
y = tbh : c = 150
If ContainerGadget(#G_ContPanelTool,0,y,wp,CanvasH)
SetGadgetColor(#G_ContPanelTool,#PB_Gadget_BackColor, RGB(c,c,c))
If PanelGadget(#G_PanelTool,0,0,wp,CanvasH)
SetGadgetColor(#G_PanelTool,#PB_Gadget_BackColor, RGB(c,c,c))
AddGadgetItem(#G_PanelTool,0,"Tool")
x=0 : y=10
wtb = 100 : wsg = 50
AddSTringTBGadget(#G_ToolSizeTB,#G_ToolSizeSG,x,y,wtb,wsg,1,100,brush(action)\size,"Size") : y+25
AddSTringTBGadget(#G_ToolAlphaTB,#G_ToolAlphaSG,x,y,wtb,wsg,0,255,brush(action)\alpha,"Tra","Set the transparency of the Tool") : y+25
If CreateImage(#img_brushcolor,50,50)
If ImageGadget(#G_ToolColor,x+10,y,50,50,ImageID(#img_brushcolor),#PB_Image_Border ) :EndIf
EndIf
; #G_ToolImage
; #G_ToolType ; brush=0, eraser=1
CloseGadgetList()
EndIf
CloseGadgetList()
EndIf
y = tbh : x = wp+5 : c = 90
If ContainerGadget(#G_cont_CanvasDrawing,x,y,canvasW,CanvasH)
SetGadgetColor(#G_cont_CanvasDrawing,#PB_Gadget_BackColor, RGB(c,c,c))
CanvasGadget(#G_canvasDrawing, 0,0, canvasW, CanvasH,#PB_Canvas_Keyboard)
CloseGadgetList()
EndIf
y=WindowHeight(0)-h1-MenuHeight()-StatusBarHeight(0)
w=20 : h=20 : d=30 : b = 3: c = 150
If ContainerGadget(#G_cont_Timeline,0,y,WindowWidth(0),h1)
SetGadgetColor(#G_cont_Timeline,#PB_Gadget_BackColor, RGB(c,c,c))
x=10 : y=10
AddButtonGadget(#G_LayerAnimVisible,x,y,h,h,"","",#ico_visible,#PB_Button_Toggle) : x+h+b
AddButtonGadget(#G_LayerAnimLock,x,y,h,h,"","",#ico_Lock,#PB_Button_Toggle) : x+h+b
AddButtonGadget(#G_LayerAnimAdd,x,y,w,h,"+","Add a layerAnim") : x+w+b
AddButtonGadget(#G_LayerAnimDel,x,y,w,h,"-","Delete the current layerAnim") : x+w+b
AddButtonGadget(#G_LayerAnimUp,x,y,w,h,"-","Move the layerAnim up",#ico_Up) : x+w+b
AddButtonGadget(#G_LayerAnimDown,x,y,w,h,"-","Move the layerAnim down",#ico_Down) : x+w+15
x = 250
AddButtonGadget(#G_AddFrame,x,y,w,h,"+","Add keyframe (and image on the selected layer)") : x+w+b
AddButtonGadget(#G_DelFrame,x,y,w,h,"-","Delete the current keyframe (and delete all images for this keyframe on the layer)") : x+w+d
w=60
AddSpinGadget(#G_OgnionPrevious,x,y,w,h,0,5,"Ognion Skinning Previous",Anim\OgnionPrevious) : x+w+b
AddSpinGadget(#G_OgnionNext,x,y,w,h,0,5,"Ognion Skinning Next",Anim\OgnionNext) : x+w+d
AddSpinGadget(#G_FrameStart,x,y,w,h,0,1000,"Start of animation",Anim\FrameStart) : x+w+b
AddSpinGadget(#G_FrameEnd,x,y,w,h,1,1000,"End of animation",Anim\FrameEnd) : x+w+b
AddSpinGadget(#G_FrameCurrent,x,y,w,h,0,1000, "Current frame",Anim\FrameCurrent) : x+w+d
AddSpinGadget(#G_FrameSpeed,x,y,w,h,0,100, "Speed of animation",Anim\Speed*10) : x+w+b
AddSpinGadget(#G_FrameFPS,x,y,w,h,0,100, "FPS of animation",Anim\FPS) : x+w+d
w= 70
AddButtonGadget(#G_PlayAnim,x,y,w,h,"Play","",-1,#PB_Button_Toggle) : x+w+b
AddButtonGadget(#G_StopAnim,x,y,w,h,"Stop") : x+w+d
; the timeline
x=10 : y+h+5
CanvasGadget(#G_TimeLine, 10, y, WindowWidth(0)-20, h1-40,#PB_Canvas_Border )
CloseGadgetList()
EndIf
LayerAnimAdd()
UpdateTimeLine()
;}
Repeat
Event = WaitWindowEvent(1)
EventGadget = EventGadget()
EventMenu = EventMenu()
z.d=zoom * 0.01
mx = WindowMouseX(0) - GadgetX(#G_cont_CanvasDrawing)
my = WindowMouseY(0) - GadgetY(#G_cont_CanvasDrawing)
Select Event
Case #PB_Event_Menu
Select EventMenu
Case #Menu_LayerClear
If ArraySize(LayerAnim(LayerAnimID)\Image())>=anim\FrameCurrent
img = LayerAnim(LayerAnimID)\Image(anim\FrameCurrent)\image
If IsImage(img) And img > #img_last
; If StartDrawing(ImageOutput(LayerAnim(LayerAnimID)\Image(anim\FrameCurrent)\image))
; DrawingMode(#PB_2DDrawing_AllChannels)
; Box(0,0,OutputWidth(), OutputHeight(), RGBA(0,0,0,0))
; StopDrawing() : EndIf
FreeImage2(LayerAnim(LayerAnimID)\Image(anim\FrameCurrent)\image)
LayerAnim(LayerAnimID)\Image(anim\FrameCurrent)\image = -1
updateCanvas(0)
EndIf
EndIf
Case #Menu_LayerImportImage
file$= OpenFileRequester("Import",GetCurrentDirectory(),"Images|*.png;*.jpg;*bmp",0)
If file$ <>#Empty$
FreeImage2( LayerAnim(LayerAnimID)\Image(anim\FrameCurrent)\image )
LayerAnim(LayerAnimID)\Image(anim\FrameCurrent)\image = LoadImage(#PB_Any,file$)
UpdateCanvas(1)
EndIf
Case #menu_FileExport
oldlayerANimId = LayerAnimID
For k=0 To ArraySize(LayerAnim())
For i=0 To ArraySize(LayerAnim(k)\Image())
img = LayerAnim(k)\Image(i)\image
If IsImage(img) And img > #img_last
If SaveImage(img, GetCurrentDirectory()+ProjectName$+"_Layer"+Str(k)+"_Image"+Str(i)+".png",#PB_ImagePlugin_PNG)
EndIf
EndIf
Next
Next
LayerAnimID= oldlayerANimId
EndSelect
Case #PB_Event_Gadget
Select EventGadget
Case #G_canvasDrawing
If EventType() = #PB_EventType_KeyUp
If GetGadgetAttribute(#G_canvasDrawing, #PB_Canvas_Key) & #PB_Shortcut_Space
movecanvas = 0
EndIf
ElseIf EventType() = #PB_EventType_KeyDown
If GetGadgetAttribute(#G_canvasDrawing, #PB_Canvas_Key) & #PB_Shortcut_Space
movecanvas =1
EndIf
Else
If movecanvas =1
If EventType() = #PB_EventType_LeftButtonDown
If move = 0
move = 1
startcanvasX = mx - canvasX
startcanvasY = my - canvasY
; UpdateCanvas()
EndIf
ElseIf EventType() = #PB_EventType_LeftButtonUp
move = 0
UpdateCanvas()
ElseIf move And EventType() = #PB_EventType_MouseMove
canvasX = mx - startcanvasX
canvasY = my - startcanvasY
; ResizeGadget(#G_canvasDrawing,canvasX,canvasY,#PB_Ignore,#PB_Ignore)
UpdateCanvas(2)
EndIf
Else
If EventType() = #PB_EventType_Focus
ElseIf EventType() = #PB_EventType_MouseWheel
zoom +10*GetGadgetAttribute(#G_canvasDrawing,#PB_Canvas_WheelDelta)
If zoom<10
zoom=10
ElseIf zoom> 500
zoom = 500
EndIf
StatusBarText(0,1,"Zoom : "+Str(Zoom)+"%")
UpdateCanvas(2)
Else
x = GetGadgetAttribute(#G_canvasDrawing, #PB_Canvas_MouseX)/z -canvasX/z
y = GetGadgetAttribute(#G_canvasDrawing, #PB_Canvas_MouseY)/z -canvasY/z
If EventType() = #PB_EventType_LeftButtonUp
; StrokeID+1 ; to get an undo ?
ReDim Stroke.sStroke(StrokeID)
DotCurrent=0
nbdot=0
ElseIf EventType() = #PB_EventType_LeftButtonDown
AddDot(x,y)
previousx = x
previousY = y
updateCanvas(1,x,y)
ElseIf (EventType() = #PB_EventType_MouseMove And GetGadgetAttribute(#G_canvasDrawing, #PB_Canvas_Buttons) & #PB_Canvas_LeftButton)
AddDot(x,y)
updateCanvas(1,x,y)
previousx = x
previousY = y
EndIf
EndIf
EndIf
EndIf
Case #G_ToolSizeTB, #G_ToolSizeSG, #G_ToolAlphaSG, #G_ToolAlphaTB,#G_ToolColor
BrushUpdate(EventGadget)
Case #G_OgnionPrevious,#G_OgnionNext
Anim\OgnionPrevious = GetGadgetState(#G_OgnionPrevious)
Anim\OgnionNext = GetGadgetState(#G_OgnionNext)
updateCanvas(0)
Case #G_LayerAnimUp
LayerAnimMove(1)
Case #G_LayerAnimDown
LayerAnimMove(-1)
Case #G_LayerAnimAdd
LayerAnimAdd()
UpdateTimeLine()
Case #G_FrameStart
Anim\FrameStart = GetGadgetState(EventGadget)
UpdateTimeLine()
Case #G_FrameEnd
Anim\FrameEnd = GetGadgetState(EventGadget)
UpdateTimeLine()
Case #G_FrameFPS, #G_FrameSpeed
Anim\FPS = GetGadgetState(#G_FrameFPS)
Anim\Speed = GetGadgetState(#G_FrameSpeed)/10
UpdateTimeLine()
Case #G_PlayAnim
PlayANim=1
animtimer = ElapsedMilliseconds()
Case #G_StopAnim
PlayANim=0
SetGadgetState(#G_PlayAnim,0)
Case #G_FrameCurrent
Anim\FrameCurrent = GetGadgetState(EventGadget)
UpdateTimeLine()
Case #G_TimeLine
EventTimeLine()
EndSelect
EndSelect
If PlayAnim = 1
If ElapsedMilliseconds() >animtimer + (1000/(anim\FPS * anim\Speed))
animtimer = ElapsedMilliseconds()
Anim\FrameCurrent +1
If Anim\FrameCurrent> Anim\FrameEnd
Anim\FrameCurrent= Anim\FrameStart
EndIf
UpdateTimeLine()
SetGadgetState(#G_FrameCurrent, Anim\FrameCurrent)
EndIf
EndIf
Until Event = #PB_Event_CloseWindow
EndIf