Jump to content

Custom camera "fade"


Dzsozi (h03)

Recommended Posts

Hello! I started doing a custom camera fading script, which I would like to make look like this:

https://youtu.be/Ejon93PmXAg?t=1m7s (the blue rectangles sliding in the background)

I would like to make a new custom function for that, where I can give the following arguments: the color of the rectangles and the size of the rectangles. I have a few little problems. First of all, how can I make the length random, so one of the rectangles is longer than the other, one is shorter, etc. Right now it is wiggling, because it always generates a random number because it is inside the onClientRender event I guess, or maybe because of the loop, or both, I'm not sure.

The other thing I don't know how to make is the disappearing. So for example I have the function called fadeCameraDX and it has the following arguments:

state: the state whether the camera should fade in or away
r,g,b: the RGB color of all the rectangles, if it is not given then the colors will be random
size: the size of the rectangles

I would like to prevent a "bug" when the camera is already faded in I can't start the fade in animation again, so I made a variable for that, called currentState, I am using outputchatbox to see if it is working correctly and it seems like it is fine, but for some reason the rectangles doesn't start to go away when I use the fadeCameraDX(false) function, and it should start if the currentState variable is true, and it is true, but it doesn't work.

And one more thing I'm not SURE about, is if I made the rectangles correctly. I mean it is not 100% correct, because if I set the size of the rectangles to 10, the rectangles doesn't cover even the half of the screen. How can I make sure that there is always just enough rectangles to cover the screen? Not more, to avoid unnecessary drawings and fps drops and not less to cover up the whole screen. Is there any way to count it? You will see what I mean if you look at the script, here it is:

local screenX, screenY = guiGetScreenSize()
local dxFades = nil
local timeToFade = 2000
local currentState = false
function fadeCameraDX(state,r,g,b,size)
	if dxFades then return end
	
	dxFades = {}
	dxFades.timeStart = getTickCount()
	dxFades.timeStop = dxFades.timeStart + timeToFade
	dxFades.state = state
	
	if not tonumber(size) then
		size = 50
	end
	dxFades.size = size
	
	if not tonumber(r) then
		r = math.random(100,255)
	end
	if not tonumber(g) then
		g = math.random(100,255)
	end
	if not tonumber(b) then
		b = math.random(100,255)
	end
	dxFades.color = {r,g,b}
	
	addEventHandler("onClientRender", root, renderDXCameraFading)
end

function renderDXCameraFading()
	local r,g,b = unpack(dxFades.color)
	local rectangleWidth = screenX
	local rectanglePosX = 0
	local borderSize = dxFades.size/10
	if dxFades.state == true then
		if currentState == false then
			local now = getTickCount()
			local elapsedTime = now - dxFades.timeStart
			local duration = dxFades.timeStop - dxFades.timeStart
			local progress = elapsedTime / duration
			rectangleWidth = interpolateBetween(
			0,0,0,
			screenX,0,0,
			progress, "InOutQuad"
			)
			if elapsedTime > duration then
				currentState = true
			end
		end
		for i=0,dxFades.size do -- what should I change dxFades.size to to have just enough rectangles that covers up the whole screen, but not more?
			local randomSize = math.random(0,250)
			exports.vice_util:dxDrawBorder(0, i*(dxFades.size+borderSize), rectangleWidth+randomSize, dxFades.size, borderSize, tocolor(0,0,0,255))
			dxDrawRectangle(0, i*(dxFades.size+dxFades.size/10), rectangleWidth+randomSize, dxFades.size, tocolor(r,g,b,255))
		end
	else
		if currentState == true then
			local now = getTickCount()
			local elapsedTime = now - dxFades.timeStart
			local duration = dxFades.timeStop - dxFades.timeStart
			local progress = elapsedTime / duration
			rectanglePosX = interpolateBetween(
			0,0,0,
			screenX,0,0,
			progress, "InOutQuad"
			)
			if elapsedTime > duration then
				currentState = false
			end
		end
		for i=0,dxFades.size do -- what should I change dxFades.size to to have just enough rectangles that covers up the whole screen, but not more?
			local randomSize = math.random(0,250)
			exports.vice_util:dxDrawBorder(rectanglePosX+randomSize, i*(dxFades.size+borderSize), screenX, dxFades.size, borderSize, tocolor(0,0,0,255))
			dxDrawRectangle(rectanglePosX+randomSize, i*(dxFades.size+dxFades.size/10), screenX, dxFades.size, tocolor(r,g,b,255))
		end
	end
	outputChatBox(tostring(currentState))
end

fadeCameraDX(true,255,255,255,10)
setTimer(function()
	fadeCameraDX(true,0,0,0,20)
	outputChatBox("1")
	setTimer(function()
		fadeCameraDX(false,255,0,0,50)
		outputChatBox("2")
	end, 5000, 1)
end, 10000, 1)

So my questions again:

How can I make the disappearing work and if the disappearing animation is over then remove the event handler of the onclientrender event?
How can I make the rectangles have different lengths without wiggling and moving around, changing sizes? If I create the randomSize variable outside of the loop it doesn't change the size for each, but all of them, so it looks like nothing has changed.
How can I "optimise" or make the loop better so I can get always just enough rectangles to cover up the whole screen?

Edited by Dzsozi
Link to comment

I think you're simply looking for removeEventHandler("onClientRender", root,  renderDXCameraFading)

and for the different sizes I'd just make them start on a random location of the leftside of the screen between 0 and 30% for example and then make the all move to the right and stopping when you went from 0 till 100%

at least, that's how I'd do it

Link to comment

I know that I should remove the event handler with removeEventHandler function, I even wrote it above, the thing I don't know is how. Same with the positions. What do you mean by make them start on a random location of the left side? When they are fading in it is okay to start at pos 0 and change their X sizes randomly, and when fading away it is okay to keep the X size of the screen and change their X positions randomly, that's just what I did, since it is the simplest way to do this, and I don't think there is any probem with the base. I just don't know how to change their size without wiggling around, please just read the lines I wrote above.

Link to comment

Clipboardimage2016-11-29212255.png

So first you create the bars off-screen with a length equal to the max width of the screen (for example 1920px) so the position is -1920px

Clipboardimage2016-11-29212259.png

"the blue line is a photoshop guide :) representing +/- 30% of the screen"

30% of 1920px is 576px so you generate a math.random(0, 576) or start higher somewhere higher than 0 to be sure it's minimum somewhere on the screen.

That random number you add to the -1920px so you'll have, for example; math.random(50, 576) => returns 377 then you do -1920px + 377px = -1543px

After setting all these bars a random position then just start doing there horizontal position (-1543px) plus 1 every frame. so -1543px + 1.

After 1920 frames you stop the render since every possible bar would've hit the right by then.

 

(Note: I'm not sure if putting something to the left off screen is -1920 but I think so, anyhow, I hope you get my idea)

Link to comment

I had a little bit of fun with it, I like the idea of this custom fading thing. Try this:

 

local screenX, screenY = guiGetScreenSize()
local dxFades = nil
local timeToFade = 2000
local currentState = false

function fadeCameraDX(state,r,g,b)
	if dxFades then return end
	
	dxFades = {}
	dxFades.timeStart = getTickCount()
	dxFades.barStartPoint = {}
	dxFades.barNumber = math.ceil(screenY / 35) -- editing this will change the number of bars | less bars -> increase it, more bars -> decrease it
	dxFades.barHeight = math.ceil(screenY / dxFades.barNumber)
	dxFades.barMargin = 4
	
	for i = 1, dxFades.barNumber do
		dxFades.barStartPoint[i] = math.random(300, 500)
	end
	
	if not tonumber(r) then
		r = math.random(100,255)
	end
	if not tonumber(g) then
		g = math.random(100,255)
	end
	if not tonumber(b) then
		b = math.random(100,255)
	end
	dxFades.color = {r,g,b}
	
	addEventHandler("onClientRender", root, renderDXCameraFading)
	outputDebugString("Num bars: " .. dxFades.barNumber)
end

function renderDXCameraFading()
	local r,g,b = unpack(dxFades.color)
	local rectangleWidth = screenX
	local rectanglePosX = 0
	local borderSize = screenY / 24
	local startEnd, outEnd
	local now = getTickCount()
	
	if not currentState then currentState = "in" end
	
	if currentState == "in" then
		startEnd = dxFades.timeStart + timeToFade
		local elapsedTime = now - dxFades.timeStart
		local duration = startEnd - dxFades.timeStart
		local progress = elapsedTime / duration
		rectangleWidth = interpolateBetween(
			0,0,0,
			screenX + 600,0,0,
			progress, "InOutQuad"
		)
	else
		outEnd = dxFades.outStart + timeToFade
		local elapsedTime = now - dxFades.outStart
		local duration = outEnd - dxFades.outStart
		local progress = elapsedTime / duration
		rectanglePosX = interpolateBetween(
			0,0,0,
			screenX + 600,0,0,
			progress, "InOutQuad"
		)
		if outEnd <= now then
			removeEventHandler("onClientRender", root, renderDXCameraFading)
			currentState = false
		end
	end
	
	if tonumber(startEnd) and startEnd <= now and currentState == "in" then
		currentState = "out"
		outputDebugString("OUT")
		dxFades.outStart = now
	end
	
	for i = 1, dxFades.barNumber do
		local startWidth = dxFades.barStartPoint[i]
		if currentState == "in" then
			dxDrawRectangle(0 - 500, (i - 1) * dxFades.barHeight, rectangleWidth + startWidth, dxFades.barHeight - dxFades.barMargin,tocolor(r,g,b,255))
		else
			dxDrawRectangle(rectanglePosX - startWidth, (i - 1) * dxFades.barHeight, rectangleWidth + startWidth, dxFades.barHeight - dxFades.barMargin,tocolor(r,g,b,255))
		end
	end

end


setTimer(function()
	fadeCameraDX(true, 255,0,0,20)
end, 2000, 1)

 

Edited by pa3ck
  • Like 1
Link to comment

There is a little problem right now. The moving and the sizes are fine, but it always starts the animation and ends it after. So I mean, it fades the screen if I don't give the state, and then it fades away, but it shouldn't. I want to make it work like the default fadeCamera function, like if the state argument is true then the rectangles come in and it only fades away if I set the state to false, not instatly after. How is this possible to make? So for example I have this test script right here:

fadeCameraDX(true)
setTimer(function()
	fadeCameraDX(false)
end, 15000, 1)

It should fade the camera away, so show the rectangles when the resource starts, and then after 15 seconds it should start fade it away. But when I use ANY argument at state, even if I use false on the resource start it starts the animation and then fades it away as well, same with argument true. Hope you know what I mean, if you don't then test it and you will see.

Edited by Dzsozi
Link to comment

Well it's up to you to modify it to your liking, of course. It fades out when the initial timeToFade ends, modify it so it fades when you turn it off. This is the part where you need to make changes:

	if tonumber(startEnd) and startEnd <= now and currentState == "in" then
		currentState = "out"
		outputDebugString("OUT")
		dxFades.outStart = now
	end

Whenever currentState is changed to "out", it will fade out. Good luck.

Link to comment

Sorry for asking alot, but I can't see the problem in my script and I don't understand why it does not work, I'm a bit tired, but I don't think that I miss something, I just don't understand. For me, I think it should work logically, but it does not, why?? I tried every possibilites I had idea of, but none of them worked, this one seems like the most logical, but it doesn't work either.

local screenX, screenY = guiGetScreenSize()
local dxFades = nil
local timeToFade = 2000
local currentState = nil
local state_ = false

function fadeCameraDX(state,r,g,b)
	if dxFades then return end
	if not state then return end
	
	dxFades = {}
	dxFades.timeStart = getTickCount()
	dxFades.barStartPoint = {}
	dxFades.barNumber = math.ceil(screenY / 35) -- editing this will change the number of bars | less bars -> increase it, more bars -> decrease it
	dxFades.barHeight = math.ceil(screenY / dxFades.barNumber)
	dxFades.barMargin = 4
	
	if state then
		state_ = state
		if state_ == true then
			currentState = "in"
		end
	end
	
	for i = 1, dxFades.barNumber do
		dxFades.barStartPoint[i] = math.random(300, 500)
	end
	
	if not tonumber(r) then
		r = math.random(100,255)
	end
	if not tonumber(g) then
		g = math.random(100,255)
	end
	if not tonumber(b) then
		b = math.random(100,255)
	end
	dxFades.color = {r,g,b}
	
	addEventHandler("onClientRender", root, renderDXCameraFading)
	outputDebugString("Num bars: " .. dxFades.barNumber)
end

function renderDXCameraFading()
	local r,g,b = unpack(dxFades.color)
	local rectangleWidth = screenX
	local rectanglePosX = 0
	local borderSize = screenY / 24
	local startEnd, outEnd
	local now = getTickCount()
	
	if currentState == "in" then
		startEnd = dxFades.timeStart + timeToFade
		local elapsedTime = now - dxFades.timeStart
		local duration = startEnd - dxFades.timeStart
		local progress = elapsedTime / duration
		rectangleWidth = interpolateBetween(
			0,0,0,
			screenX + 600,0,0,
			progress, "InOutQuad"
		)
	else
		outEnd = dxFades.outStart + timeToFade
		local elapsedTime = now - dxFades.outStart
		local duration = outEnd - dxFades.outStart
		local progress = elapsedTime / duration
		rectanglePosX = interpolateBetween(
			0,0,0,
			screenX + 600,0,0,
			progress, "InOutQuad"
		)
		if outEnd <= now then
			removeEventHandler("onClientRender", root, renderDXCameraFading)
			currentState = false
		end
	end
	
	if tonumber(startEnd) and startEnd <= now then
		if state_ == false then
			currentState = "out"
			outputDebugString("OUT")
			dxFades.outStart = now
		end
	end
	
	for i = 1, dxFades.barNumber do
		local startWidth = dxFades.barStartPoint[i]
		if currentState == "in" then
			dxDrawRectangle(0 - 500, (i - 1) * dxFades.barHeight, rectangleWidth + startWidth, dxFades.barHeight - dxFades.barMargin,tocolor(r,g,b,255))
			exports.vice_util:dxDrawBorder(0 - 500, (i - 1) * dxFades.barHeight, rectangleWidth + startWidth, dxFades.barHeight - dxFades.barMargin,dxFades.barHeight/10,tocolor(0,0,0,255))
		else
			dxDrawRectangle(rectanglePosX - startWidth, (i - 1) * dxFades.barHeight, rectangleWidth + startWidth, dxFades.barHeight - dxFades.barMargin,tocolor(r,g,b,255))
			exports.vice_util:dxDrawBorder(rectanglePosX - startWidth, (i - 1) * dxFades.barHeight, rectangleWidth + startWidth, dxFades.barHeight - dxFades.barMargin,dxFades.barHeight/10,tocolor(0,0,0,255))
		end
	end

end

fadeCameraDX(true)
setTimer(function()
	fadeCameraDX(false)
	outputChatBox("fading away now")
end, 5000, 1)

 

Edited by Dzsozi
Link to comment

Actually I already edited the script so it will only fade out when you set it to false I just didn't want to spoon feed you I tried to make you solve it. I'm away In Dublin now but I will send you the code tomorrow with some comments explaining how to do it.

Link to comment
36 minutes ago, pa3ck said:

Actually I already edited the script so it will only fade out when you set it to false I just didn't want to spoon feed you I tried to make you solve it. I'm away In Dublin now but I will send you the code tomorrow with some comments explaining how to do it.

I totally understand why you didn't just paste the working code, and I appreciate it, because I can learn new things that way (if I you just give me hints/little instructions), and I tried it so many ways and times, but I couldn't figure out, so thank you for helping me out. The explanation comments is a good idea, I will read through carefully so I wil understand how to do these things, maybe I will be able to figure out how to do the pager script, the thing I opened another topic about, I couldn't fix it yet, kinda the same like with this script, I have tried it so many times but couldn't figure out how to fix it. Waiting for your reply, thank you again for the help!

Link to comment

I think the custom fadeout is a bit complicated, so it would be difficult to understand it right away. I made a simple window animation, with the same principles as the custom fadeout. 

Spoiler

local start
local scrX, scrY = guiGetScreenSize()
local renderState

function drawPanel()
	local now, endTime, elapsedTime, duration, progress
	local x, y, z
	now = getTickCount()
			
	if renderState == "in" then -- make sure whenever you start to draw the panel, the renderState is set to "in"
		endTime = start + 800
		elapsedTime = now - start
		duration = endTime - start
		progress = elapsedTime / duration
		x, y, z = interpolateBetween ( 0, 0, 0, 350, 350, 200, progress, "Linear")
	elseif renderState == "out" then -- as soon as the state changes, do the fadeOut. NOTE: this variable should only be changed when the fadeIn is over
		endTime = start + 4000
		elapsedTime = now - start
		duration = endTime - start
		progress = elapsedTime / duration
		x, y, z = interpolateBetween (	350, 350, 200, 0, 0, 0, progress, "Linear") -- if you want to fadeOut the exact same way as the fadeIn all you have to do is to swap the 3 numbers
		if endTime <= now then -- if the endTime tick is less than the currentTick (now), it means the animation is over
			removeEventHandler("onClientRender", root, drawPanel) -- this is the last tick of the render, this is where you will no longer see the GUI
			outputDebugString("Animation: render removed")
		end
	end

	dxDrawRectangle(scrX / 2 - x / 2, scrY / 2 - y / 2, x, y, tocolor(0, 0, 0, z)) -- x, y and z variables are coming from the interPolate functions
	-- I'm using the same veriables for fadeIn and fadeOut, makes it easier
	
	if renderState == "in" and endTime <= now then -- only the draw panel title when, fadeIn animation is finished, but fadeOut hasn't started yet
		dxDrawText("Some random panel title", scrX / 2 - x / 2, scrY / 2 - y / 2, scrX / 2 + x / 2, scrY / 2 - y / 2 + 40, tocolor(255, 255, 255, 255), 1, "default-bold", "center", "center")
	end
	
end

addEventHandler("onClientResourceStart", resourceRoot, function()
	
	start = getTickCount()
	renderState = "in" -- always initialize to the fadeIn state
	addEventHandler("onClientRender", root, drawPanel)
	outputDebugString("Animation: render fadeIn start")
	setTimer(function()
		renderState = "out" -- change the renderState so it will start the fadeOut
		start = getTickCount() -- very, very, very important to do this
		outputDebugString("Animation: render fadeOut start")
	end, 6000, 1 )

end)

 

And this is the working custom fadeIn and fadeOut:

Spoiler

local screenX, screenY = guiGetScreenSize()
local dxFades = nil
local timeToFade = 2000
local currentState = false

function fadeCameraDX(state,r,g,b)
	if dxFades and state then return end
	if dxFades and not state then dxFades.canFadeOut = true return end
	
	dxFades = {}
	dxFades.timeStart = getTickCount()
	dxFades.barStartPoint = {}
	dxFades.barNumber = math.ceil(screenY / 55) -- editing this will change the number of bars | less bars -> increase it, more bars -> decrease it
	dxFades.barHeight = math.ceil(screenY / dxFades.barNumber)
	dxFades.barMargin = 4
	
	for i = 1, dxFades.barNumber do
		dxFades.barStartPoint[i] = math.random(300, 500)
	end
	
	if not tonumber(r) then
		r = math.random(100,255)
	end
	if not tonumber(g) then
		g = math.random(100,255)
	end
	if not tonumber(b) then
		b = math.random(100,255)
	end
	dxFades.color = {r,g,b}
	
	addEventHandler("onClientRender", root, renderDXCameraFading)
	outputDebugString("Num bars: " .. dxFades.barNumber)
end

function renderDXCameraFading()
	local r,g,b = unpack(dxFades.color)
	local rectangleWidth = screenX
	local rectanglePosX = 0
	local borderSize = screenY / 24
	local startEnd, outEnd
	local now = getTickCount()
	
	if not currentState then currentState = "in" end
	
	if currentState == "in" then
		startEnd = dxFades.timeStart + timeToFade
		local elapsedTime = now - dxFades.timeStart
		local duration = startEnd - dxFades.timeStart
		local progress = elapsedTime / duration
		rectangleWidth = interpolateBetween(
			0,0,0,
			screenX + 600,0,0,
			progress, "InOutQuad"
		)
	else
		outEnd = dxFades.outStart + timeToFade
		local elapsedTime = now - dxFades.outStart
		local duration = outEnd - dxFades.outStart
		local progress = elapsedTime / duration
		rectanglePosX = interpolateBetween(
			0,0,0,
			screenX + 600,0,0,
			progress, "InOutQuad"
		)
		if outEnd <= now then
			removeEventHandler("onClientRender", root, renderDXCameraFading)
			currentState = false
		end
	end
	
	if tonumber(startEnd) and startEnd <= now and currentState == "in" and dxFades.canFadeOut then
		currentState = "out"
		dxFades.outStart = now
	end
	
	for i = 1, dxFades.barNumber do
		local startWidth = dxFades.barStartPoint[i]
		if currentState == "in" then
			dxDrawRectangle(0 - 500, (i - 1) * dxFades.barHeight, rectangleWidth + startWidth, dxFades.barHeight - dxFades.barMargin,tocolor(r,g,b,255))
		else
			dxDrawRectangle(rectanglePosX - startWidth, (i - 1) * dxFades.barHeight, rectangleWidth + startWidth, dxFades.barHeight - dxFades.barMargin,tocolor(r,g,b,255))
		end
	end

end


setTimer(function()
	fadeCameraDX(true, 66, 173, 244,20)
	setTimer(function() fadeCameraDX(false) outputDebugString("Fading out...") end, 10000, 1)
end, 2000, 1)

 

 

  • 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...