228 lines
5.6 KiB
ObjectPascal
228 lines
5.6 KiB
ObjectPascal
// SPDX-License-Identifier: LGPL-3.0-linking-exception
|
|
{
|
|
Created by BGRA Controls Team
|
|
Dibo, Circular, lainz (007) and contributors.
|
|
For detailed information see readme.txt
|
|
|
|
Site: https://sourceforge.net/p/bgra-controls/
|
|
Wiki: http://wiki.lazarus.freepascal.org/BGRAControls
|
|
Forum: http://forum.lazarus.freepascal.org/index.php/board,46.0.html
|
|
}
|
|
{******************************* CONTRIBUTOR(S) ******************************
|
|
- Edivando S. Santos Brasil | mailedivando@gmail.com
|
|
(Compatibility with delphi VCL 11/2018)
|
|
|
|
***************************** END CONTRIBUTOR(S) *****************************}
|
|
unit BCEffect;
|
|
|
|
{$I bgracontrols.inc}
|
|
{$IFDEF FPC}
|
|
{$modeswitch advancedrecords}
|
|
{$ENDIF}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, {$IFDEF FPC}LCLProc, LazUTF8, {$ELSE}Types, BGRAGraphics, GraphType, FPImage, {$ENDIF} BGRABitmapTypes;
|
|
|
|
{-- Fading --}
|
|
|
|
type
|
|
TFadingMode = (fmSuspended, fmFadeIn, fmFadeOut, fmFadeInCycle, fmFadeOutCycle, fmFadeInOut, fmFadeOutIn);
|
|
|
|
const
|
|
FadingModeStr: array[TFadingMode] of string = ('Suspended', 'Fade In', 'Fade Out', 'Fade In Cycle','Fade Out Cycle', 'Fade In Out', 'Fade Out In');
|
|
|
|
function StrToTFadingMode(const s: ansistring): TFadingMode;
|
|
procedure FadingModeStrList(s: TStrings);
|
|
|
|
type
|
|
|
|
{ TFading }
|
|
|
|
TFading = record
|
|
private
|
|
FAlpha: byte;
|
|
FMode: TFadingMode;
|
|
FAlphaStep: byte;
|
|
FDuration: integer;
|
|
FPrevDate: TDateTime;
|
|
FElapsedMsAccumulator: integer;
|
|
public
|
|
procedure SetFAlpha(AValue: byte);
|
|
procedure SetFMode(AValue: TFadingMode);
|
|
procedure SetFAlphaStep(AValue: byte);
|
|
procedure SetFDuration(AValue: integer);
|
|
public
|
|
function Execute(AStepCount: integer= 1): byte; // execute and return new alpha
|
|
function Reset: byte; // reset and return new alpha
|
|
procedure PutImage(ADestination: TBGRACustomBitmap; AX,AY: integer; ASource: TBGRACustomBitmap);
|
|
procedure FillRect(ADestination: TBGRACustomBitmap; ARect: TRect; AColor: TBGRAPixel);
|
|
public
|
|
property Alpha: byte read FAlpha write SetFAlpha;
|
|
property Mode: TFadingMode read FMode write SetFMode;
|
|
property Step: byte read FAlphaStep write SetFAlphaStep;
|
|
property Duration: integer read FDuration write SetFDuration;
|
|
end;
|
|
|
|
{-- Fading --}
|
|
|
|
implementation
|
|
|
|
{-- Fading --}
|
|
|
|
function StrToTFadingMode(const s: ansistring): TFadingMode;
|
|
var
|
|
fm: TFadingMode;
|
|
ls: ansistring;
|
|
begin
|
|
ls := {$IFDEF FPC}UTF8LowerCase{$ELSE}LowerCase{$ENDIF}(s);
|
|
for fm := low(TFadingMode) to high(TFadingMode) do
|
|
if ls = {$IFDEF FPC}UTF8LowerCase{$ELSE}LowerCase{$ENDIF}(FadingModeStr[fm]) then
|
|
begin
|
|
Result := fm;
|
|
break;
|
|
end;
|
|
Result := fm;
|
|
end;
|
|
|
|
procedure FadingModeStrList(s: TStrings);
|
|
var
|
|
fm: TFadingMode;
|
|
begin
|
|
for fm := low(TFadingMode) to high(TFadingMode) do
|
|
s.Add(FadingModeStr[fm]);
|
|
end;
|
|
|
|
{ TFading }
|
|
|
|
procedure TFading.SetFAlpha(AValue: byte);
|
|
begin
|
|
if FAlpha = AValue then
|
|
Exit;
|
|
FAlpha := AValue;
|
|
end;
|
|
|
|
procedure TFading.SetFMode(AValue: TFadingMode);
|
|
begin
|
|
if FMode = AValue then
|
|
Exit;
|
|
FMode := AValue;
|
|
FPrevDate:= 0;
|
|
end;
|
|
|
|
procedure TFading.SetFAlphaStep(AValue: byte);
|
|
begin
|
|
if FAlphaStep = AValue then
|
|
Exit
|
|
else
|
|
FAlphaStep := AValue;
|
|
end;
|
|
|
|
procedure TFading.SetFDuration(AValue: integer);
|
|
begin
|
|
FDuration:= AValue;
|
|
end;
|
|
|
|
function TFading.Execute(AStepCount: integer= 1): byte;
|
|
var curDate: TDateTime;
|
|
alphaStep: byte;
|
|
timeGrain: integer;
|
|
begin
|
|
if FAlphaStep <= 0 then
|
|
alphaStep := 1
|
|
else
|
|
alphaStep := FAlphaStep;
|
|
|
|
if FDuration > 0 then
|
|
begin
|
|
curDate := Now;
|
|
if FPrevDate = 0 then
|
|
begin
|
|
FPrevDate := curDate;
|
|
FElapsedMsAccumulator := 0;
|
|
result := FAlpha;
|
|
exit;
|
|
end;
|
|
|
|
inc(FElapsedMsAccumulator, round((curDate-FPrevDate)*(24*60*60*1000)) );
|
|
timeGrain := round(FDuration*alphaStep/255);
|
|
if timeGrain <= 0 then timeGrain := 1;
|
|
AStepCount := FElapsedMsAccumulator div timeGrain;
|
|
FElapsedMsAccumulator:= FElapsedMsAccumulator mod timeGrain;
|
|
FPrevDate := curDate;
|
|
end;
|
|
|
|
if AStepCount < 0 then AStepCount := 0
|
|
else if AStepCount > 255 then AStepCount := 255;
|
|
|
|
case FMode of
|
|
fmFadeIn, fmFadeInOut, fmFadeInCycle:
|
|
begin
|
|
if (FAlpha = 255) and (FMode = fmFadeInCycle) then
|
|
FAlpha := 0
|
|
else
|
|
if FAlpha + alphaStep*AStepCount >= 255 then
|
|
begin
|
|
FAlpha := 255;
|
|
if FMode = fmFadeInOut then
|
|
FMode := fmFadeOutIn
|
|
else if FMode <> fmFadeInCycle then
|
|
FMode := fmSuspended;
|
|
end
|
|
else
|
|
FAlpha := FAlpha + (alphaStep*AStepCount);
|
|
end;
|
|
fmFadeOut,fmFadeOutIn, fmFadeOutCycle:
|
|
begin
|
|
if (FAlpha = 0) and (FMode = fmFadeOutCycle) then
|
|
FAlpha := 255
|
|
else
|
|
if FAlpha - alphaStep*AStepCount <= 0 then
|
|
begin
|
|
FAlpha := 0;
|
|
if FMode = fmFadeOutIn then
|
|
FMode := fmFadeInOut
|
|
else if FMode <> fmFadeOutCycle then
|
|
FMode := fmSuspended;
|
|
end
|
|
else
|
|
FAlpha := FAlpha - (alphaStep*AStepCount);
|
|
end;
|
|
end;
|
|
|
|
Result := FAlpha;
|
|
end;
|
|
|
|
function TFading.Reset: byte;
|
|
begin
|
|
case FMode of
|
|
fmFadeIn, fmFadeInOut:
|
|
begin
|
|
FAlpha := 0;
|
|
end;
|
|
fmFadeOut,fmFadeOutIn:
|
|
begin
|
|
FAlpha := 255;
|
|
end;
|
|
end;
|
|
Result := FAlpha;
|
|
FPrevDate := 0;
|
|
end;
|
|
|
|
procedure TFading.PutImage(ADestination: TBGRACustomBitmap; AX, AY: integer;
|
|
ASource: TBGRACustomBitmap);
|
|
begin
|
|
ADestination.PutImage(AX,AY,ASource,dmDrawWithTransparency,Alpha);
|
|
end;
|
|
|
|
procedure TFading.FillRect(ADestination: TBGRACustomBitmap; ARect: TRect;
|
|
AColor: TBGRAPixel);
|
|
begin
|
|
ADestination.FillRect(ARect, BGRA(AColor.red,AColor.green,AColor.blue,AColor.alpha*Alpha div 255),dmDrawWithTransparency);
|
|
end;
|
|
|
|
{-- Fading --}
|
|
|
|
end.
|