Что нового

Анимации png

saraconor

Новичок
Сообщения
362
Репутация
2
Хочу сделать некий "помощник" в программе, при активации определенной кнопки будет возникать анимационная фигурка с прозрачностью, которая при наведении на элементы интерфейса будет подлетать к ним и окошками сообщений и жестами объяснять что это и как пользоваться (нечто вроде желтой собачки в Windows XP). Так вот, сперва нужно написать скрипт, который файлы для удобства использования скомпоновывает из отдельных кадров .png в единый файл ленту, это одна часть работы.
В дальнейшем понадобится удобный для использования UDF, с возможностью воспроизводить анимацию пользуясь этими лентами (разрезание ленты на кадры и цикличное воспроизведение), менять файлы анимации (как в виде ресурсов в скомпилированном виде, так и просто с путями на конкретные файлы) чтобы фигурка плавно меняла позы, зацикливать анимации, переходить от одного цикла анимаций в другой. И само окошко с GUI чтобы можно было перемещать из скрипта (не мышкой) чтобы при этом анимация не прекращалась, и не терялась прозрачность за картинкой. Нужно сделать обе части (компоновщик файлов и UDF анимации), по отдельности мне это не нужно.
Само собой все за денежку.
p.s. предлагать переделать все под gif не надо, нужно именно с png работать.
 

InnI

AutoIT Гуру
Сообщения
4 247
Репутация
1 128
За всю работу не возьмусь. Но могу подарить (совершенно бесплатно), вот эти заготовки. Тренировался на ваших же файлах: https://yadi.sk/d/RlYU45wNVl9AhQ

Скрипт объединения файлов в "ленту". Размеры рассчитываются по первому файлу, т.к. подразумевается, что все файлы одинакового размера. Чтобы не заморачиваться с сортировкой файлов нужно дать им числовые имена с учётом нулей, т.е. не 1.png, 2.png, а 01.png, 02.png и т.д.
Код:
#include <File.au3>
#include <GDIPlus.au3>

; поиск файлов
$aFiles = _FileListToArray(@ScriptDir, "*.png", 1)
If @error Then Exit

_GDIPlus_Startup()

; загрузка файлов
Global $aImg[$aFiles[0] + 1] = [$aFiles[0]]
For $i = 1 To $aImg[0]
  $aImg[$i] = _GDIPlus_ImageLoadFromFile($aFiles[$i])
Next

; размер первой картинки
$W = _GDIPlus_ImageGetWidth($aImg[1])
$H = _GDIPlus_ImageGetHeight($aImg[1])

; создание общей картинки
$Image = _GDIPlus_BitmapCreateFromScan0($W * $aImg[0], $H)
$Graph = _GDIPlus_ImageGetGraphicsContext($Image)

; рисование файлов на общую картинку
For $i = 1 To $aImg[0]
  _GDIPlus_GraphicsDrawImage($Graph, $aImg[$i], ($i - 1) * $W, 0)
Next

; сохранение ленты
_GDIPlus_ImageSaveToFile($Image, "ribbon.png")

; освобождение ресурсов
For $i = 1 To $aImg[0]
  _GDIPlus_ImageDispose($aImg[$i])
Next
_GDIPlus_ImageDispose($Image)
_GDIPlus_GraphicsDispose($Graph)
_GDIPlus_Shutdown()

Анимация "ленты" с перемещением окна за курсором мыши. В начале скрипта обязательно нужно задать ширину "кадра"
Код:
#include <GDIPlus.au3>
#include <WinAPISysWin.au3>
#include <WindowsConstants.au3>

; выход по Shift+ESC
HotKeySet("+{esc}", "Quit")

; ширина кадра
$Width = 150

; загрузка ленты
_GDIPlus_Startup()
$Image = _GDIPlus_ImageLoadFromFile("ribbon.png")
If @error Then Exit _GDIPlus_Shutdown()

; расчёты
$Count = _GDIPlus_ImageGetWidth($Image) / $Width
$Height = _GDIPlus_ImageGetHeight($Image)

; разбиение на кадры
Global $aImg[$Count]
For $i = 0 To $Count - 1
  $Img = _GDIPlus_BitmapCloneArea($Image, $i * $Width, 0, $Width, $Height, $GDIP_PXF32ARGB)
  $aImg[$i] = _GDIPlus_BitmapCreateHBITMAPFromBitmap($Img)
  _GDIPlus_ImageDispose($Img)
Next
_GDIPlus_ImageDispose($Image)
_GDIPlus_Shutdown()

; создание окна и анимация
$GUI = GUICreate("", $Width, $Height, -1, -1, $WS_POPUPWINDOW, BitOR($WS_EX_LAYERED, $WS_EX_TOPMOST))
GUISetState()
While 1
  For $i = 0 To $Count - 1
    Sleep(111)
    _WinAPI_UpdateLayeredWindowEx($GUI, -1, -1, $aImg[$i])
    WinMove($GUI, "", MouseGetPos(0) + 30, MouseGetPos(1) + 30)
  Next
WEnd

; удаление ресурсов
For $i = 0 To $Count - 1
  _WinAPI_DeleteObject($aImg[$i])
Next

; выход
Func Quit()
  Exit
EndFunc

по отдельности мне это не нужно
Ну, может кому-то пригодится...
Сообщение автоматически объединено:

Кстати, функция _WinAPI_UpdateLayeredWindowEx() поддерживает прозрачность. Поэтому можно не рисовать несколько одинаковых кадров с разной прозрачностью, а выводить один непрозрачный кадр, программно меняя ему прозрачность
Код:
; создание окна и анимация
$GUI = GUICreate("", $Width, $Height, -1, -1, $WS_POPUPWINDOW, BitOR($WS_EX_LAYERED, $WS_EX_TOPMOST))
GUISetState()
While 1
  ; выводится один кадр $aImg[6] с разной прозрачностью
  For $i = 0 To 5
    Sleep(111)
    _WinAPI_UpdateLayeredWindowEx($GUI, -1, -1, $aImg[6], $i * 40)
    WinMove($GUI, "", MouseGetPos(0) + 30, MouseGetPos(1) + 30)
  Next
  ; выводятся остальные кадры
  For $i = 6 To $Count - 1
    Sleep(111)
    _WinAPI_UpdateLayeredWindowEx($GUI, -1, -1, $aImg[$i])
    WinMove($GUI, "", MouseGetPos(0) + 30, MouseGetPos(1) + 30)
  Next
WEnd
 
Последнее редактирование:
Автор
S

saraconor

Новичок
Сообщения
362
Репутация
2
Спасибо большое за скрипты и комментарии там, буду думать как использовать.
 
Верх