Jump to content

dxDrawText alpha script


IsGh

Recommended Posts

Hey, I'm stuck with this script

local x,y = guiGetScreenSize()
local defScale = 0
local currentScale = defScale
local maxScale = 2
local step = 0.08
local turn = true
local font = "sans"
local text = "Is#99ccaaGh"
 
function renderPulse()
  if turn == true then
    currentScale = currentScale + step
    if currentScale > maxScale then
      currentScale = maxScale
      turn = false
    end
  else
    currentScale = currentScale - step
    if currentScale < defScale then
     if text == "#99ccaaOdyssey Metamorphosis" then
        step = 0
     else
        font = "bankgothic"
        text = "#99ccaaOdyssey Metamorphosis"
        turn = true
     end
    end
  end
  local width = dxGetTextWidth(text,currentScale,font, true)
  local height = dxGetFontHeight(currentScale,font)
  dxDrawText(text,x/2-width/2,100,width,height,tocolor(0, 204, 170, 255),currentScale,font, "left", "top", false,false,false,true)
end
addEventHandler("onClientRender",getRootElement(),renderPulse)

 

What it actually do is to write "IsGh" with size 0 and then reach the size of 2 then gets back to size 0 then writes"Odyssey Metamorphosis" with size 0, reach the size of 2 and gets back to 0.

But I want to make it's alpha gets from 0 to 255 while "IsGh" size gets from 0 to 2 and "odyssey metamorphosis"s alpha gets from 255 to 0 while it's size is getting from 2 to 0

I haven't find anyway to do it so i thought posting it here will be a better solution.

 

Link to comment
  • Moderators

It is a very complex process. But the best way to do this is by using the "os time".

https://wiki.multitheftauto.com/wiki/GetTickCount

 

local duration = 5000
local futureTime = getTickCount() + duration

 



local timeNow = getTickCount()
local timeLeft = futureTime - timeNow

if timeLeft > 0 then -- animation ran NOT out of time ?
	local progress = (duration - timeLeft) / duration
	
	if progress > 0.5 then
		
	else
    	
	end
end

 

Try to understand this concept first .

 

-------------------------------------------------------

 

Feel free to use my content animator. It might to be too complex for you, but maybe you find your answer in the code.

 

(next page)


 

 

Pre requirement:

For the functions: addRenderEvent, removeRenderEvent

 

Content animator:

Spoiler

-------------------------------------
-- Author: IIYAMA animated content --
-------------------------------------

local screenWidth, screenHeight = guiGetScreenSize()

local activeAnimatedContent = {}

local idCounter = 0

local renderAnimations

function createAnimatedContent (content)
	local duration 
	
	if content.duration == "infinity" or content.duration == "inf" then
		duration = "inf"
	else
		duration = tonumber(content.duration)
	end
	

	
	if duration and (type(content.func) == "function" or type(content.func) == "string") then
		
		
	
		local delay = tonumber(content.delay) or 0
		local id = content.id
		if id then
			removeAnimatedContentById(id)
		end
		
		local startTime = getTickCount() + delay
		
		local animations = content.animations
		if animations then
			for i=#animations, 1, -1 do
				local animation = animations[i]
				local removeAnimation = true
				
				-- check if animation is OK
				do
					if not animation.parameter then 
						break
					end
					animation.from = tonumber(animation.from)
					if not animation.from then 
						break
					end
					animation.to = tonumber(animation.to)
					if not animation.to then 
						break
					end
					
					animation.difference = animation.to - animation.from
					
					animation.duration = tonumber(animation.duration)
					if not animation.duration then 
						break
					end
					removeAnimation = false
				end

				-- prepare the time data.
				animation.delay = tonumber(animation.delay) or 0
				
				animation.startTime = startTime + animation.delay
				animation.endTime = startTime + animation.delay + animation.duration
				
				
				
				
				if removeAnimation then
					table.remove(animations, i)
				end
				--
			end
		end
		
		
		
		-- give it a new id if it hasn't one.
		if not id then
			idCounter = idCounter + 1
			id = "anim:" .. idCounter .. ":" .. getRealTime().timestamp
		end
		
		local parameters = content.parameters or {}
		
		-- pre defined parameters --
		parameters.screenWidth = screenWidth
		parameters.screenHeight = screenHeight
		parameters.screenCenterX = screenWidth / 2
		parameters.screenCenterY = screenHeight / 2
		
		parameters.scaleFactorX = 1 / 1920 * screenWidth
		parameters.scaleFactorY = 1 / 1080 * screenHeight
		
		
		if content.isLoadStringFunction then
			content.func = loadstring('return function(param) ' .. content.func .. ' end')
		end
		
		-- Move the content to a new table.
		activeAnimatedContent[#activeAnimatedContent + 1] = {
			id = id,
			
			startTime = startTime,
			endTime = type(duration) == "string" and duration or startTime + duration,
			duration = duration,
			delay = delay,
			
			parameters = parameters,
			animations = animations,
			func = content.func,
			isLoadStringFunction = content.isLoadStringFunction
		}
		

		
		addRenderEvent(renderAnimations)
		return id
	end
	return false
end

function removeAnimatedContentById(id)
	for i=1, #activeAnimatedContent do
		if activeAnimatedContent[i].id == id then
			table.remove(activeAnimatedContent, i)
			return true
		end
	end
	return false
end


function renderAnimations ()
	
	local timeNow = getTickCount()
	
	for i=#activeAnimatedContent, 1, -1 do
		local animatedContent = activeAnimatedContent[i]
		
		local animations = animatedContent.animations
		local parameters = animatedContent.parameters
		
		-- loop through all animations
		if animations then
			for j=1, #animations do
				local animation = animations[j]
				
				-- can we start the animation? or has it already ended?
				if not animation.finished and timeNow > animation.startTime then
					local parameter = animation.parameter
					if timeNow < animation.endTime then
						local progress = ((timeNow - animation.startTime) / animation.duration) 
						-- edit a parameter
						local value
						if animation.easingType then
							value = animation.difference * getEasingValue(progress, animation.easingType, animation.easingPeriod, animation.easingAmplitude, animation.easingOvershoot)
						else
							value = (progress * animation.difference)
						end
						
						parameters[parameter] = value + animation.from 
					else -- animation has finished
						local value = animation.to
						parameters[parameter] = value
						animation.finished = true
					end
				end
			end
		end
		
		if animatedContent.endTime == "inf" or timeNow <= animatedContent.endTime then
			-- call the attached function
			if not animatedContent.isLoadStringFunction then
				animatedContent.func(parameters)
			else
				animatedContent.func()(parameters)
			end
		else
			table.remove(activeAnimatedContent, i)
		end
	end
	
	if #activeAnimatedContent == 0 then
		removeRenderEvent(renderAnimations)
	end
end

 

 

Example, this is an animated rectangle:

 

Fill in:

  • id
  • duration
  • delay
  • func (function where you do the animation stuff)
  • parameters (default/start values)
  • animations (these will animate/change the values of the parameters)

 

Warning: The animations do not wait for each other, that is where the delay setting comes in.

setTimer(function ()
	local sample = {
		id = "sample", -- optional
		duration = 5000, -- or "infinity" / "inf"
		delay = 1000,
		func = function (param)
			local rectangleSize = 100 * param.scaleFactorY
			dxDrawRectangle ( param.screenCenterX - rectangleSize / 2, param.screenCenterY - rectangleSize / 2, rectangleSize, rectangleSize, tocolor ( 255, 0, 0, param.opacityStart ) )
		end,
		
		-- optional 1
		parameters = {
			opacityStart = 0
		},
		
		-- optional 2 (requires optional 1)
		animations = {
			{
				parameter = "opacityStart",
				from = 0,
				to = 255,
				duration = 2000,
				delay = 0,
				-- optional 3
				easingType = "OutInBounce",
				easingAmplitude = 1.0
				--
			},
			{
				parameter = "opacityStart",
				from = 255,
				to = 0,
				duration = 2000,
				delay = 2000
			}
		}
	}
	createAnimatedContent (sample)
end, 100, 1)

 

Edited by IIYAMA
Link to comment
1 hour ago, IIYAMA said:

It is a very complex process. But the best way to do this is by using the "os time".

https://wiki.multitheftauto.com/wiki/GetTickCount

 


local duration = 5000
local futureTime = getTickCount() + duration

 



local timeNow = getTickCount()
local timeLeft = futureTime - timeNow

if timeLeft > 0 then -- animation ran NOT out of time ?
	local progress = (duration - timeLeft) / duration
	
	if progress > 0.5 then
		
	else
    	
	end
end

 

Try to understand this concept first .

 

-------------------------------------------------------

 

Feel free to use my content animator. It might to be too complex for you, but maybe you find your answer in the code.

 

(next page)


 

 

Pre requirement:

For the functions: addRenderEvent, removeRenderEvent

 

Content animator:

  Reveal hidden contents


 
-------------------------------------
-- Author: IIYAMA animated content --
-------------------------------------

local screenWidth, screenHeight = guiGetScreenSize()

local activeAnimatedContent = {}

local idCounter = 0

local renderAnimations

function createAnimatedContent (content)
	local duration 
	
	if content.duration == "infinity" or content.duration == "inf" then
		duration = "inf"
	else
		duration = tonumber(content.duration)
	end
	

	
	if duration and (type(content.func) == "function" or type(content.func) == "string") then
		
		
	
		local delay = tonumber(content.delay) or 0
		local id = content.id
		if id then
			removeAnimatedContentById(id)
		end
		
		local startTime = getTickCount() + delay
		
		local animations = content.animations
		if animations then
			for i=#animations, 1, -1 do
				local animation = animations[i]
				local removeAnimation = true
				
				-- check if animation is OK
				do
					if not animation.parameter then 
						break
					end
					animation.from = tonumber(animation.from)
					if not animation.from then 
						break
					end
					animation.to = tonumber(animation.to)
					if not animation.to then 
						break
					end
					
					animation.difference = animation.to - animation.from
					
					animation.duration = tonumber(animation.duration)
					if not animation.duration then 
						break
					end
					removeAnimation = false
				end

				-- prepare the time data.
				animation.delay = tonumber(animation.delay) or 0
				
				animation.startTime = startTime + animation.delay
				animation.endTime = startTime + animation.delay + animation.duration
				
				
				
				
				if removeAnimation then
					table.remove(animations, i)
				end
				--
			end
		end
		
		
		
		-- give it a new id if it hasn't one.
		if not id then
			idCounter = idCounter + 1
			id = "anim:" .. idCounter .. ":" .. getRealTime().timestamp
		end
		
		local parameters = content.parameters or {}
		
		-- pre defined parameters --
		parameters.screenWidth = screenWidth
		parameters.screenHeight = screenHeight
		parameters.screenCenterX = screenWidth / 2
		parameters.screenCenterY = screenHeight / 2
		
		parameters.scaleFactorX = 1 / 1920 * screenWidth
		parameters.scaleFactorY = 1 / 1080 * screenHeight
		
		
		if content.isLoadStringFunction then
			content.func = loadstring('return function(param) ' .. content.func .. ' end')
		end
		
		-- Move the content to a new table.
		activeAnimatedContent[#activeAnimatedContent + 1] = {
			id = id,
			
			startTime = startTime,
			endTime = type(duration) == "string" and duration or startTime + duration,
			duration = duration,
			delay = delay,
			
			parameters = parameters,
			animations = animations,
			func = content.func,
			isLoadStringFunction = content.isLoadStringFunction
		}
		

		
		addRenderEvent(renderAnimations)
		return id
	end
	return false
end

function removeAnimatedContentById(id)
	for i=1, #activeAnimatedContent do
		if activeAnimatedContent[i].id == id then
			table.remove(activeAnimatedContent, i)
			return true
		end
	end
	return false
end


function renderAnimations ()
	
	local timeNow = getTickCount()
	
	for i=#activeAnimatedContent, 1, -1 do
		local animatedContent = activeAnimatedContent[i]
		
		local animations = animatedContent.animations
		local parameters = animatedContent.parameters
		
		-- loop through all animations
		if animations then
			for j=1, #animations do
				local animation = animations[j]
				
				-- can we start the animation? or has it already ended?
				if not animation.finished and timeNow > animation.startTime then
					local parameter = animation.parameter
					if timeNow < animation.endTime then
						local progress = ((timeNow - animation.startTime) / animation.duration) 
						-- edit a parameter
						local value
						if animation.easingType then
							value = animation.difference * getEasingValue(progress, animation.easingType, animation.easingPeriod, animation.easingAmplitude, animation.easingOvershoot)
						else
							value = (progress * animation.difference)
						end
						
						parameters[parameter] = value + animation.from 
					else -- animation has finished
						local value = animation.to
						parameters[parameter] = value
						animation.finished = true
					end
				end
			end
		end
		
		if animatedContent.endTime == "inf" or timeNow <= animatedContent.endTime then
			-- call the attached function
			if not animatedContent.isLoadStringFunction then
				animatedContent.func(parameters)
			else
				animatedContent.func()(parameters)
			end
		else
			table.remove(activeAnimatedContent, i)
		end
	end
	
	if #activeAnimatedContent == 0 then
		removeRenderEvent(renderAnimations)
	end
end

 

 

Example, this is an animated rectangle:

 

Fill in:

  • id
  • duration
  • delay
  • func (function where you do the animation stuff)
  • parameters (default/start values)
  • animations (these will animate/change the values of the parameters)

 

Warning: The animations do not wait for each other, that is where the delay setting comes in.


setTimer(function ()
	local sample = {
		id = "sample", -- optional
		duration = 5000, -- or "infinity" / "inf"
		delay = 1000,
		func = function (param)
			local rectangleSize = 100 * param.scaleFactorY
			dxDrawRectangle ( param.screenCenterX - rectangleSize / 2, param.screenCenterY - rectangleSize / 2, rectangleSize, rectangleSize, tocolor ( 255, 0, 0, param.opacityStart ) )
		end,
		
		-- optional 1
		parameters = {
			opacityStart = 0
		},
		
		-- optional 2 (requires optional 1)
		animations = {
			{
				parameter = "opacityStart",
				from = 0,
				to = 255,
				duration = 2000,
				delay = 0,
				-- optional 3
				easingType = "OutInBounce",
				easingAmplitude = 1.0
				--
			},
			{
				parameter = "opacityStart",
				from = 255,
				to = 0,
				duration = 2000,
				delay = 2000
			}
		}
	}
	createAnimatedContent (sample)
end, 100, 1)

 

sorry, but I haven't understand what it does exactly

so can you edit my code itself ? 

thanks in advance

Link to comment
  • Moderators
1 hour ago, IsGh said:

so can you edit my code itself ?

That will not help you understand what the code does, or do you have some magic for that?

 

This code does:

 

  1. Defining the animation duration
  2. Calculate the time when the animation should end.

 

  1. Getting the time now.
  2. Calculate the amount of animation-time left.
  3. Calculate the progress of the animation.

 

The progress is a value from 0 t/m 1.

0 = 0%, 0.5 = 50%, 1 = 100%

Which you can multiply with the alpha:

progress * 255 (alpha)

 

Shouldn't be too hard to understand? After all, the variable names speak for them self.

Edited by IIYAMA
  • Like 1
Link to comment
10 hours ago, IIYAMA said:

That will not help you understand what the code does, or do you have some magic for that?

 

This code does:

 

  1. Defining the animation duration
  2. Calculate the time when the animation should end.

 

  1. Getting the time now.
  2. Calculate the amount of animation-time left.
  3. Calculate the progress of the animation.

 

The progress is a value from 0 t/m 1.

0 = 0%, 0.5 = 50%, 1 = 100%

Which you can multiply with the alpha:

progress * 255 (alpha)

 

Shouldn't be too hard to understand? After all, the variable names speak for them self.

Well, I understood what it does and what every variable do. But, I'm not even good in scripting so the problem is where exactly to put you code in my code?

I tried to do it but the script doesn't work at all after adding your code.

Link to comment
  • Moderators
40 minutes ago, IsGh said:

Well, I understood what it does and what every variable do. But, I'm not even good in scripting so the problem is where exactly to put you code in my code?

I tried to do it but the script doesn't work at all after adding your code.

The first two lines should be on top of the script.

The rest should be inside of the function which is called every frame. (Name: renderPulse)

  • Like 1
Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...