Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --@name Epic visualizer
- --@author NekerSqu4w
- //version 2.22 Please don't delete this line to have semi-auto update :D
- --@include ./lang.txt
- --@include ./color.txt
- //IMPORTANT Changelog 2.20
- //
- // Now loading YouTube playlist
- //
- //Changelog 2.21
- //
- // 1. Small bug adjustment.
- // 2. Changed visual effect:
- // 2.1. Better particle effect
- // 2.2. Added a loading bar when starting
- // 2.3. Better match with background color
- //
- // 3. Added modifications to lang.txt --> https://pastebin.com/pTkL06UW
- //
- //Changelog 2.22
- //
- // 1. Small bug adjustment.
- // 2. Changed visual effect:
- // 2.1. Smaller particle effect
- // 2.2. Better low frequency detecting
- // 2.3. Better pulsating effects
- //
- // 3. Addition of a new 'SynthWave' color palette to color.txt --> https://pastebin.com/n8fgDFww
- if SERVER then
- -- Auto link screen
- if chip():isWeldedTo() then
- chip():isWeldedTo():linkComponent(chip())
- end
- -------------------------------------------------------
- end
- if CLIENT then
- -- Important information (Before run the code for the first time)
- //Download the lang file here --> 'https://pastebin.com/pTkL06UW'
- //Download the color palettes file here --> 'https://pastebin.com/n8fgDFww'
- -- Settings
- local track = 50
- local playlist_id = "PLvL0CfXbtRGGvfWF9809g3q1aoieIFVp3" //Max track = 50 //Default = PLvL0CfXbtRGGvfWF9809g3q1aoieIFVp3
- local key = "YOUR_API_KEY" //Create your free api key here --> https://console.cloud.google.com/apis
- local max_hearing_distance = 1000
- -- Visual settings
- local lang_use = "EN_lang"
- local principal_color = Color(150,255,100)
- // Some cool color
- //
- // Apples: Color(150,255,100)
- // Orange: Color(255,150,70)
- // YouTube: Color(255,75,75)
- -------------------------------------------------------
- -- Variable
- local ver = 2.22
- local lang = require("./lang.txt")(lang_use)
- local color = require("./color.txt")
- local volume = 0.5
- local loaded = 0
- local bassfft = 0
- local shake1, shake2 = 0, 0
- local fft, smooth_fft, visualizer = {}, {}, {}
- local startup = 1
- local black, black2 = 0, 0
- local startUpSize = 1300
- local posRight = 0
- local r,g,b,r2,g2,b2 = 0,0,0,{},{},{}
- local time, duration = 0, 10
- local start_time = 0
- local color_menu, show_visualizer, show_cursor = false, true, true
- local sizeToX, sizeToY = 0, 0
- local sizeX, sizeY = 0, 0
- local pi2 = math.pi*2
- local loading = ""
- local mat = {}
- local looping = true
- local use_color = 1
- local click_possible = false
- local last_real = Color(0,0,0)
- local title = ""
- local id = ""
- local thumbnail = ""
- local URL = ""
- local url = ""
- local playlist = {}
- local real = {}
- local j = 0
- local fontName = "Akbar"
- local font = render.createFont(fontName, 250+50, 250+50, true, false, false, false, false, true)
- local font2 = render.createFont(fontName, 120+50, 120+50, true, false, false, false, false, true)
- local font3 = render.createFont(fontName, 180+50, 180+50, true, false, false, false, false, true)
- local last_max = 0
- local bc = 1
- local si = {}
- local ra = {}
- local up = {}
- local turn = {}
- for i=1, 15 do
- ra[i] = 512
- si[i] = 1
- up[i] = {}
- turn[i] = 0
- end
- render.createRenderTarget("visualizer")
- render.createRenderTarget("background")
- visualizer["1"] = { {x = 256, y = 256} }
- visualizer["2"] = { {x = 256, y = 256} }
- visualizer["3"] = { {x = 256, y = 256} }
- visualizer["4"] = { {x = 256, y = 256} }
- for h=1, 15 do
- for i = 2, 50 + 1 do visualizer["1"][i] = {} visualizer["2"][i] = {} visualizer["3"][i] = {} visualizer["4"][i] = {}
- up[h][i] = 0
- end
- end
- -------------------------------------------------------
- -- Custom function
- local cursor = {
- { x=0, y=0 },
- { x=3, y=2 },
- { x=1.1, y=2 },
- { x=2.1, y=3.9 },
- { x=1.9, y=4 },
- { x=0.9, y=2.1 },
- { x=0.1, y=4 },
- }
- function getMouse(curX, curY, scale)
- local copyMouse = table.copy(cursor)
- for i=1, #copyMouse do
- copyMouse[i].x = copyMouse[i].x*scale + curX
- copyMouse[i].y = copyMouse[i].y*scale + curY
- end
- return copyMouse
- end
- function drawMouse(curX, curY)
- render.setRenderTargetTexture()
- copyMouse = getMouse(curX, curY, 4)
- render.drawPoly(copyMouse)
- end
- local function quotaCheck(n)
- return math.max(quotaAverage(), quotaUsed()) < quotaMax() * n
- end
- local num = nil
- function changed(value)
- if not num == value then num = value val = true else val = false end
- return val
- end
- local max = 0
- function math.maxt(tbl,min,limit)
- for x=min, limit do
- for y=min, limit do
- if (tbl[x] or 0) > (tbl[y] or 0) then
- max = (tbl[x] or 0)
- elseif (tbl[x] or 0) < (tbl[y] or 0) then
- max = (tbl[y] or 0)
- end
- end
- end
- return max
- end
- local bassVal = 0
- function getBass(ft,limit)
- for h=1, limit do
- for w=1, limit do
- if (ft[h] or 0) < (ft[w] or 0) then
- bassVal = math.lerp(0.002,bassVal,(ft[w] or 0)*5)
- elseif (ft[h] or 0) > (ft[w] or 0) then
- bassVal = math.lerp(0.002,bassVal,(ft[h] or 0)*5)
- end
- end
- end
- return bassVal
- end
- function fftToRadius(i) return 54 + bassfft*20 - math.log10(i) - (smooth_fft[50-i] or 0)*100 end
- function inrange(x, y, w, h)
- local cx, cy = render.cursorPos()
- if not cx or not cy then return false end
- if cx > x and cx < x+w then
- if cy > y and cy < y+h then
- return true
- end
- end
- end
- function information(cx,cy,txt,res,use_font)
- render.setFont(use_font)
- local w,h = render.getTextSize(txt)
- render.setColor(Color(0,0,0,100))
- render.drawRect((cx/512)*res+50, (cy/512)*res-80, w, h)
- render.setColor(Color(255,255,255))
- render.drawText((cx/512)*res+50, (cy/512)*res-85, txt,0)
- return (w/res)*512,(h/res)*512
- end
- function render.drawPolyOutline(table)
- local lx,ly = table[2].x, table[2].y
- for i=2, #table do
- x = table[i].x
- y = table[i].y
- render.drawLine(x,y,lx,ly)
- lx = x
- ly = y
- end
- end
- -------------------------------------------------------
- -- Slider function
- local Slider = class("Slider")
- local objects = {}
- function Slider:initialize(x, y, w, h, min, max, val, round, info, show_title, can_change)
- self.x = x
- self.y = y
- self.w = w
- self.h = h
- self.min = min or 0
- self.max = max or 100
- self.val = val or 0
- self.round = round or 0
- self.info = info or ""
- self.normal = self.val or 0
- self.title = show_title or false
- self.can_change = can_change or false
- self.color1 = Color(100,100,100)
- self.color2 = Color(100,130,255)
- self.color3 = Color(230,230,230)
- table.insert(objects, self)
- end
- function Slider:think()
- if self.active then
- local cx, cy = render.cursorPos()
- if not cx or not cy then return end
- cx = math.clamp(cx, self.x, self.x + self.w)
- self.val = self.max / self.w * (cx - self.x)
- end
- if self.customThink then self:customThink() end
- end
- function Slider:paint()
- local m = Matrix()
- m:setScale(Vector(0.08))
- render.pushMatrix(m)
- local v = self.w / self.max * self.val
- render.setColor(self.color1/1.3)
- render.drawRect((self.x/512)*6400, ((self.y+self.h/2.6)/512)*6400, (self.w/512)*6400, ( (self.h/4 )/512)*6400)
- render.setColor(self.color2)
- render.drawRect((self.x/512)*6400, ((self.y+self.h/2.6)/512)*6400, (v/512)*6400, ( (self.h/4 )/512)*6400)
- if self.active then
- render.setColor((self.color2/1.3):setA(255))
- else
- render.setColor(self.color2)
- end
- render.drawRoundedBox( 1000, ((self.x+v - (self.h/3) )/512)*6400,((self.y+self.h/6)/512)*6400, ( (self.h/1.5)/512)*6400, ( (self.h/1.5)/512)*6400 )
- if self.active and self.title then
- render.setFont(render.createFont("akbar", 200, 200, true, false, false, false, false, false))
- local width, height = render.getTextSize( math.round(self.val,self.round) .. " (" .. tostring(math.round((self.val/1)*100)) .. self.info .. ")" )
- render.setColor(self.color3)
- render.setMaterial()
- render.drawRect(((self.x + v)/512)*6400 - (width+50)/2,((self.y-10)/512)*6400 - height/2,width+50,height)
- render.setColor(Color(255,255,255))
- render.setFont(render.createFont("akbar", 200, 200, true, false, false, false, false, false))
- render.drawSimpleText(((self.x + v)/512)*6400, ((self.y-10)/512)*6400, math.round(self.val,self.round) .. " (" .. tostring(math.round((self.val/1)*100)) .. self.info .. ")", 1, 1)
- end
- render.popMatrix()
- end
- function markElement(active)
- if not active then
- -- disable all elements
- for k, v in pairs(objects) do
- v.active = false
- end
- else
- -- find element under cursor
- for k, v in pairs(objects) do
- if inrange(v.x, v.y, v.w, v.h) then
- v.active = true
- break
- end
- end
- end
- end
- -------------------------------------------------------
- -- Particle function
- local Particle = class("Particle")
- function Particle:initialize(pos, scale, direction, clr, life_time)
- self.x = pos.x or 0
- self.y = pos.y or 0
- self.scale = scale or 0
- self.first_scale = scale or 0
- self.x_vel = direction.x or 0
- self.y_vel = direction.y or 0
- self.color = clr or Color(255, 255, 255, 255)
- self.life = life_time or 5
- self.life_start = life_time or 5
- end
- function Particle:think()
- self:draw()
- self.x = self.x + self.x_vel
- self.y = self.y + self.y_vel
- self.life = self.life - 0.01
- self.scale = (self.life/self.life_start) * self.first_scale
- end
- function Particle:draw()
- render.setColor(self.color:setA(255))
- render.setMaterial(mat[3])
- render.drawTexturedRect(self.x - self.scale/2, self.y - self.scale/2, self.scale, self.scale)
- render.setMaterial(nil)
- render.setColor(Color(255,255,255):setA(255))
- end
- local game = {}
- game.particles = {}
- -------------------------------------------------------
- -- Show the visualizer
- function load()
- bass.loadURL(URL,"noblock",function(snd)
- -- Setup slider
- timer.create("Setup",1,1,function()
- local volume_slider = Slider(400-150/2, 480-15/2, 150, 15, 0, 2, volume, 2, "%", true, false)
- volume_slider.customThink = function(self)
- self.color1 = Color(150, 150, 150):setA(75)
- self.color2 = principal_color
- self.color3 = Color(0,0,0,150)
- volume = self.max * self.val
- end
- local time_slider = Slider(256-480/2, 495-15/2, 480, 15, 0, length, snd:getTime(), 2, "%", false, true)
- time_slider.color1 = Color(150, 150, 150):setA(75)
- time_slider.color2 = principal_color
- time_slider.color3 = Color(0,0,0,150)
- time_slider.customThink = function(self)
- self.color1 = Color(150, 150, 150):setA(75)
- self.color2 = principal_color
- self.color3 = Color(0,0,0,150)
- snd:setTime(length / self.max * self.val)
- end
- snd:play()
- end)
- -------------------------------------------------------
- snd:pause()
- local Light = light.create(chip():getPos(),700,5,Color(0,0,0))
- hook.add("render","visualizer",function()
- if snd:isValid() then
- if snd:getTime() >= length then
- snd:setTime(0)
- end
- snd:setPos(render.getScreenEntity():getPos())
- local dist = player():getPos():getDistance(chip():getPos())
- if dist > max_hearing_distance then snd:setVolume(0) else snd:setVolume(volume - (dist/max_hearing_distance)*volume) end
- fft = snd:getFFT(4)
- if startup == 10 then
- bassfft = getBass(fft,20)
- end
- end
- local cx, cy = render.cursorPos()
- click_possible = false
- //shake1 = math.lerp(0.2,shake1,math.random(-bassfft*7,bassfft*7))
- //shake2 = math.lerp(0.2,shake2,math.random(-bassfft*7,bassfft*7))
- local real = color[use_color].color[1] or Color(0,0,0)
- r = math.lerp(0.2,r, real.r)
- g = math.lerp(0.2,g, real.g)
- b = math.lerp(0.2,b, real.b)
- Light:draw()
- Light:setPos( render.getScreenEntity():getPos() )
- Light:setColor(Color(r,g,b)*bassfft)
- -- Background
- render.selectRenderTarget("background")
- render.setMaterial(mat[1])
- render.setColor(Color(0, 0, 1):hsvToRGB())
- render.setCullMode(1)
- render.drawTexturedRect( 256, 0, -750, 750)
- render.setCullMode(0)
- render.drawTexturedRect( 256, 0, 750, 750)
- if startup == 5 then
- if startup && startup then render.capturePixels() end
- j = 1
- for i=1, 10 do
- for h=1, 10 do
- x = 512-(i/10)*(512-(1/10)*512)
- y = (h/10)*(512-(1/10)*512)
- real[j] = render.readPixel(x,y)
- j = j + 1
- end
- end
- for i=1, 10 do
- color[1].color[i] = real[i]
- end
- end
- render.setMaterial(nil)
- render.selectRenderTarget(nil)
- render.setColor(Color(0, 0, black+bassfft/4):hsvToRGB())
- render.setRenderTargetTexture("background")
- render.drawTexturedRect(0-bassfft/4*20,0-bassfft/4*20,1024+bassfft*20,1024+bassfft*20)
- -------------------------------------------------------
- if startup == 10 and show_visualizer == true then
- -- Setup and draw Particle
- if #game.particles <= 300 then
- local nP = Particle:new(Vector(256,256),math.random(10, 20),Vector(math.rand(-1,1),math.rand(-1,1)),color[use_color].color[math.random(1,#color[use_color].color)],3)
- table.insert(game.particles, nP)
- end
- for k, v in pairs(game.particles) do
- if v.scale <= 0 then table.remove(game.particles, k) continue end
- v:draw()
- v.x = v.x + (v.x_vel*(0.5+bassfft*4))
- v.y = v.y + (v.y_vel*(0.5+bassfft*4))
- v.life = v.life - 0.01
- v.scale = (v.life/v.life_start) * v.first_scale
- //v:think()
- end
- -------------------------------------------------------
- -- Setup visualizer
- for i=2, 50+1 do
- local theta = (((i - 1) - 1) * math.pi / (50 - 1))
- smooth_fft[i] = math.lerp((0.1*7.5),(smooth_fft[i] or 0), (fft[50+2-i+1] or 0) )
- visualizer["1"][i].x = 256 + shake1 + math.cos(math.pi/2+theta + timer.curtime()/4) * (58 + ((smooth_fft[50+2-i + 1] or 0) * 140) + (bassfft * 20) + 50/4)
- visualizer["1"][i].y = 256 + shake2 + math.sin(math.pi/2+theta + timer.curtime()/4) * (58 + ((smooth_fft[50+2-i + 1] or 0) * 140) + (bassfft * 20) + 50/4)
- visualizer["2"][i].x = 256 + shake1 + math.cos(math.pi/2-theta + timer.curtime()/4) * (58 + ((smooth_fft[50+2-i + 1] or 0) * 140) + (bassfft * 20) + 50/4)
- visualizer["2"][i].y = 256 + shake2 + math.sin(math.pi/2-theta + timer.curtime()/4) * (58 + ((smooth_fft[50+2-i + 1] or 0) * 140) + (bassfft * 20) + 50/4)
- end
- -------------------------------------------------------
- -- Draw visualizer
- render.selectRenderTarget("visualizer")
- render.setMaterial(nil)
- render.clear(Color(0,0,0,0))
- render.setColor(Color(255, 255, 255))
- render.setCullMode(0)
- render.drawPoly(visualizer["1"])
- render.setCullMode(1)
- render.drawPoly(visualizer["2"])
- render.setCullMode(0)
- render.selectRenderTarget(nil)
- for v=1, #color[use_color].color do
- local real = color[use_color].color[math.round(#color[use_color].color+1-v)] or Color(0,0,0)
- r2[v] = math.lerp(0.1,r2[v] or 0, real.r)
- g2[v] = math.lerp(0.1,g2[v] or 0, real.g)
- b2[v] = math.lerp(0.1,b2[v] or 0, real.b)
- render.setColor(Color(r2[v],g2[v],b2[v]):setA(255))
- render.setRenderTargetTexture("visualizer")
- render.drawTexturedRect(-200/4 + (v/#color[use_color].color)*200/4,-200/4 + (v/#color[use_color].color)*200/4,1024+200 - (v/#color[use_color].color)*200,1024+200 - (v/#color[use_color].color)*200)
- end
- end
- -------------------------------------------------------
- -- Starting animation
- if startup == 1 then if startUpSize >= -50 then startUpSize = startUpSize - 2 - (startUpSize/1300)*30 end end
- if startUpSize <= 100 and startup == 1 then if posRight <= 180 then posRight = posRight + 1 + (posRight/180)*2 black = (posRight/180)*0.2 else startup = 3 end end
- if startup == 3 then timer.create("aaaaa",2,1,function() startup = 5 end) startup = 4 end
- if startup == 5 then if posRight >= 0 then posRight = posRight - 5 black = 0.4-(posRight/180)*0.2 black2 = 1-(posRight/180)*1 end end
- if startup == 5 then if startUpSize <= 50 then startUpSize = startUpSize + 3 - (startUpSize/50)*2.9 else startup = 10 end end
- if startup == 2 or startup == 3 or startup == 4 or startup == 5 or startUpSize <= 5 then
- render.setMaterial(mat[2])
- render.setColor(Color(255, 255, 255):setA(math.clamp( 255-black2*600,0,255)))
- render.drawTexturedRect(256 - 70/4 * posRight*1.2, 256 - 70/4, 70, 70)
- render.drawTexturedRect(256 - 70/4 + posRight*1.2, 256 - 70/4, 70, 70)
- render.setColor(Color(255, 255, 255):setA(math.clamp( 255-black2*1000,0,255)))
- render.drawTexturedRect(256 - 110/4 - posRight/1.1, 256 - 110/4, 110, 110)
- render.drawTexturedRect(256 - 110/4 + posRight/1.1, 256 - 110/4, 110, 110)
- render.setColor(Color(255, 255, 255):setA(math.clamp( 255-black2*1400,0,255)))
- render.drawTexturedRect(256 - 140/4 - posRight/2, 256 - 140/4, 140, 140)
- render.drawTexturedRect(256 - 140/4 + posRight/2, 256 - 140/4, 140, 140)
- render.setMaterial(nil)
- end
- -------------------------------------------------------
- -- Draw punch circle
- if startup == 10 and show_visualizer == true then
- if (math.maxt(fft,1,7) - last_max) > 0.1 then
- bc = bc + 1
- if bc >= 15 then bc = 1 end
- si[bc] = 1 + math.maxt(fft,3,7)*10
- ra[bc] = 50
- turn[bc] = timer.curtime()
- for h=2, 51 do
- up[bc][h] = ((smooth_fft[50+2-h + 1] or 0) * 140) + (bassfft * 20) + 50/4
- end
- end
- last_max = math.maxt(fft,1,7)
- for i=1, 15 do
- if ra[i] < 512 then ra[i] = ra[i] + si[i] end
- render.setColor(Color(principal_color.r,principal_color.g,principal_color.b,100))
- //render.drawCircle(256,256,ra[i])
- for h=2, 51 do
- local theta = (((h - 1) - 1) * math.pi / (50 - 1))
- visualizer["3"][h].x = 256 + shake1 + math.cos(math.pi/2+theta + turn[i]/4) * (ra[i] + up[i][h])
- visualizer["3"][h].y = 256 + shake2 + math.sin(math.pi/2+theta + turn[i]/4) * (ra[i] + up[i][h])
- visualizer["4"][h].x = 256 + shake1 + math.cos(math.pi/2-theta + turn[i]/4) * (ra[i] + up[i][h])
- visualizer["4"][h].y = 256 + shake2 + math.sin(math.pi/2-theta + turn[i]/4) * (ra[i] + up[i][h])
- end
- render.drawPolyOutline(visualizer["3"])
- render.drawPolyOutline(visualizer["4"])
- end
- render.setCullMode(0)
- end
- -------------------------------------------------------
- if show_visualizer == true then
- -- Logo
- render.setMaterial(mat[2])
- render.setColor(Color(255, 255, 255))
- render.drawTexturedRect(512/2 - 220/4 - bassfft*80*0.25 + shake1 - startUpSize/4, 512/2 - 220/4 - bassfft*80*0.25 + shake2 - startUpSize/4, 220 + bassfft*80 + startUpSize, 220 + bassfft*80 + startUpSize)
- -------------------------------------------------------
- end
- -- Visualizer in logo
- if startup == 10 and show_visualizer == true then
- render.setMaterial(nil)
- for i=1, 29 do
- local theta = (i-1)*2*(math.pi/2.5)/(30-1)
- render.setColor(principal_color)
- render.drawTexturedRectRotated( 256 + shake1 + math.sin(-math.pi/2.5+theta) * fftToRadius(i), 256 + shake2 + math.cos(-math.pi/2.5+theta) * fftToRadius(i), 4, 2 + (smooth_fft[50-i] or 0)*200, -360/3.3+(360/2.5)/29+i*-(360/2.5)/29)
- end
- -------------------------------------------------------
- end
- -- Visualizer GUI
- if startup == 10 then
- local m = Matrix()
- m:setScale(Vector(0.08))
- render.pushMatrix(m)
- -- Time bar
- render.setColor(Color(255))
- render.setFont(font3)
- render.drawSimpleText(800, 6000, string.toMinutesSeconds(snd:getTime()),1,1)
- render.setColor(Color(120,120,120))
- render.drawSimpleText(1400, 6000," / "..string.toMinutesSeconds(length),1,1)
- render.setColor(principal_color)
- render.drawRoundedBox( 1000, 450-70/2, 6010-70/2, 70, 70)
- render.setColor(Color(120,120,120))
- render.setFont(font)
- render.drawSimpleText(200, 200, "" .. track,1,1)
- render.setColor(Color(255))
- render.setFont(font)
- render.drawSimpleText(400, 150, "" .. (playlist[track].snippet.title or "Deleted video"),0,1)
- render.setColor(Color(180,180,180))
- render.setFont(font2)
- render.drawSimpleText(400, 320, "" .. url,0,1)
- sizeX = math.lerp(0.4,sizeX,sizeToX)
- render.setColor(Color(0, 0, 0, 255))
- render.setMaterial(mat[4])
- render.drawTexturedRect(0,0,6400,450)
- render.setColor(Color(0, 0, 0, 255))
- render.setMaterial(mat[5])
- render.drawTexturedRect(0, 5800, 6400, 600)
- render.setColor(Color(0, 0, 0, 255))
- render.setMaterial(mat[6])
- render.drawTexturedRect(0, 0, 0 + sizeX, 6400)
- render.setColor(Color(0, 0, 0, 75))
- render.drawRect(sizeX/2, 500, 300, 300)
- ------------------------------------------------
- if inrange(((sizeX/2)/6400)*512, (500/6400)*512, (300/6400)*512, (300/6400)*512) then
- click_possible = true
- if color_menu == true then
- information(cx+4,cy+23,lang.color_on,6400,font3)
- else
- information(cx+4,cy+23,lang.color_off,6400,font3)
- end
- end
- if color_menu == true then
- render.setColor(Color(255,255,255))
- render.setFont(font3)
- if show_visualizer == true then
- render.drawSimpleText(sizeX/2-100, 1600 + #color*180, lang.visualizer_on.."",0,1)
- else
- render.drawSimpleText(sizeX/2-100, 1600 + #color*180, lang.visualizer_off.."",0,1)
- end
- if show_cursor == true then
- render.drawSimpleText(sizeX/2-100, 1300 + #color*180, lang.cursor_on.."",0,1)
- else
- render.drawSimpleText(sizeX/2-100, 1300 + #color*180, lang.cursor_off.."",0,1)
- end
- sizeToX = 1500
- render.setColor(Color(255, 255, 255))
- render.setMaterial(mat[7])
- render.drawTexturedRectRotated(sizeX/2+190, 500+150, 300, 300,-45)
- for i=1, #color do
- if use_color == i then
- render.setColor(Color(255, 255, 255))
- render.setMaterial(mat[7])
- render.drawTexturedRectRotated(sizeX/2, 750 + i*180, 150, 150,-45)
- end
- render.setColor( ( color[i].color[1] ):setA(255))
- render.drawRoundedBox(120, -1400+sizeX, 680 + i*180, 150, 150)
- render.setMaterial(nil)
- render.drawPoly( {{ x = sizeX/2-150, y = 680 + i*180 }, { x = sizeX/2-200, y = 680 + i*180 + 150 }, { x = sizeX/2-450, y = 680 + i*180+150 }, { x = sizeX/2-400, y = 680 + i*180 }} )
- if inrange(8, 54 + i*14.5, 40, 12) then
- click_possible = true
- information(cx+4,cy+23, "" .. color[i].name .. " palettes" ,6400,font3)
- end
- end
- render.setMaterial(nil)
- if show_visualizer == true then render.setColor(principal_color) else render.setColor(Color(255,255,255):setA(75)) end
- render.drawPoly( {{ x = sizeX/2-150, y = 1500 + #color*180 }, { x = sizeX/2-200, y = 1500 + #color*180 + 200 }, { x = sizeX/2-650, y = 1500 + #color*180 + 200 }, { x = sizeX/2-600, y = 1500 + #color*180 }} )
- if show_cursor == true then render.setColor(principal_color) else render.setColor(Color(255,255,255):setA(75)) end
- render.drawPoly( {{ x = sizeX/2-150, y = 1200 + #color*180 }, { x = sizeX/2-200, y = 1200 + #color*180 + 200 }, { x = sizeX/2-650, y = 1200 + #color*180 + 200 }, { x = sizeX/2-600, y = 1200 + #color*180 }} )
- render.setColor(Color(255,255,255))
- render.setFont(font2)
- render.drawText(sizeX/2-600, 1800 + #color*180, "ver. "..ver,0,1)
- else
- sizeToX, sizeToY = 0, 0
- render.setColor(Color(255, 255, 255))
- render.setMaterial(mat[7])
- render.drawTexturedRectRotated(sizeX/2+110, 500+150, 300, 300,135)
- end
- render.popMatrix()
- -------------------------------------------------------
- -- Click logic
- --Pressed
- if changed(player():keyDown(IN_KEY.USE)) and player():keyDown(IN_KEY.USE) then
- markElement(true)
- if inrange(((sizeX/2)/6400)*512, (500/6400)*512, (300/6400)*512, (300/6400)*512) then
- color_menu = !color_menu
- end
- for i=1, #color do
- if inrange(8, 54 + i*14.5, 40, 12) and color_menu == true then
- use_color = i
- end
- end
- if inrange(((sizeX/2-650)/6400)*512, ((1500 + #color*180)/6400)*512, ( (sizeX/2-250) /6400)*512, (200/6400)*512) then
- show_visualizer = !show_visualizer
- end
- if inrange(((sizeX/2-650)/6400)*512, ((1200 + #color*180)/6400)*512, ( (sizeX/2-250) /6400)*512, (200/6400)*512) then
- show_cursor = !show_cursor
- end
- end
- --Released
- if player():keyDown(IN_KEY.USE) == false then
- markElement(false)
- end
- -------------------------------------------------------
- if inrange(((sizeX/2)/6400)*512, (500/6400)*512, (300/6400)*512, (300/6400)*512) then
- click_possible = true
- end
- if inrange(((sizeX/2-650)/6400)*512, ((1500 + #color*180)/6400)*512, ( (sizeX/2-250) /6400)*512, (200/6400)*512) then
- click_possible = true
- end
- if inrange(((sizeX/2-650)/6400)*512, ((1200 + #color*180)/6400)*512, ( (sizeX/2-250) /6400)*512, (200/6400)*512) then
- click_possible = true
- end
- -- Draw slider
- for k, v in pairs(objects) do
- v:paint()
- if v.can_change then
- if v.active then
- v:think()
- else
- if k == 2 then
- v.val = snd:getTime()
- end
- end
- else
- v:think()
- end
- if inrange(v.x,v.y,v.w,v.h) then
- click_possible = true
- end
- end
- -------------------------------------------------------
- if cx and cy and show_cursor then
- if click_possible then
- render.setColor((principal_color/1.3):setA(255))
- else
- render.setColor(principal_color)
- end
- drawMouse(cx, cy)
- end
- end
- end)
- end)
- end
- -- Load playlist data
- function load_youtube()
- loading = "playlistItems.json"
- loaded = loaded + 1
- http.get("https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=50&playlistId="..playlist_id.."&key="..key,function(data)
- loaded = loaded + 1
- if track > json.decode(data).pageInfo.totalResults then
- track = math.clamp(json.decode(data).pageInfo.totalResults,0,50)
- end
- for v, item in pairs(json.decode(data).items) do
- if v == track then
- url = "https://www.youtube.com/watch?v="..item.snippet.resourceId.videoId
- end
- playlist[v] = item
- end
- loading = url
- timer.create("a",1,1,function()
- loaded = loaded + 1
- http.get("https://michaelbelgium.me/ytconverter/convert.php?youtubelink=" .. url, function(data)
- loaded = loaded + 1
- if json.decode(data).error then
- loading = "An error occurred cannot load the song.\nERROR: " .. json.decode(data).message
- else
- URL = json.decode(data).file
- title = json.decode(data).title
- id = json.decode(data).youtube_id
- length = json.decode(data).duration
- timer.create("b",1,1,function()
- loaded = loaded + 1
- loading = "googleapis.com/youtube/v3/videos?part=snippet&id="..id.."&key=#######"
- http.get("https://www.googleapis.com/youtube/v3/videos?part=snippet&id="..id.."&key="..key, function(data)
- loaded = loaded + 1
- for v, item in pairs(json.decode(data).items) do
- if item.snippet.thumbnails.maxres then
- thumbnail = item.snippet.thumbnails.maxres.url
- else
- thumbnail = "https://i.imgur.com/trTUlBW.png?1"
- end
- end
- timer.create("c",1,1,function()
- loaded = loaded + 1
- loading = "googleapis.com/youtube/v3/playlists?part=snippet&id="..playlist_id.."&key=#######"
- http.get("https://www.googleapis.com/youtube/v3/playlists?part=snippet&id="..playlist_id.."&key="..key, function(data)
- loaded = loaded + 1
- for v, item in pairs(json.decode(data).items) do
- list = item.snippet
- end
- timer.create("d",1,1,function()
- hook.remove("render", "loading")
- load_texture()
- end)
- end)
- end)
- end)
- end)
- end
- end)
- end)
- end)
- local l = 0
- hook.add("render","loading",function()
- local m = Matrix()
- m:setScale(Vector(0.08))
- render.pushMatrix(m)
- render.setColor(Color(255))
- render.setFont(font2)
- render.setFilterMag(1)
- if loading == "" then
- render.drawText(3200, 3400, lang.load_error.."",1,1)
- if http.canRequest() then
- load_youtube()
- end
- else
- render.drawText(3200, 3400, loading,1,1)
- render.drawText(1200, 2800, "Loaded " .. loaded .. "/8",0,1)
- end
- render.popMatrix()
- render.setColor(Color(170,170,170))
- render.drawRect(256-320/2,256-10,320,20)
- l = math.lerp(0.2,l,loaded)
- render.setColor(principal_color)
- render.drawRect(256-320/2+1,256-10+1,(l/8) * 320-2,20-2)
- end)
- end
- -------------------------------------------------------
- -- Load texture
- function load_texture()
- for i=1, 7 do mat[i] = material.create("UnlitGeneric") end
- mat[1]:setTextureURL("$basetexture", thumbnail)
- mat[2]:setTextureURL("$basetexture", "https://i.imgur.com/bEtY4vd.png?1") // Use 512x512 resolution
- //mat[2]:setTextureURL("$basetexture", "https://i.imgur.com/tXeR0gy.png") // Discord logo lol
- mat[3]:setTexture("$basetexture", "particle/particle_glow_04")
- mat[4]:setTexture("$basetexture", "vgui/gradient-u")
- mat[5]:setTexture("$basetexture", "vgui/gradient-d")
- mat[6]:setTexture("$basetexture", "vgui/gradient-l")
- mat[7]:setTexture("$basetexture", "vgui/cursors/arrow")
- hook.remove("render", "loading")
- load()
- end
- -------------------------------------------------------
- -- Find update
- function findUpdate()
- if http.canRequest() then
- http.get("https://pastebin.com/raw/sEvNPKaZ",function(data)
- version = string.split(data:sub(string.find(data:sub(1,150),"//version"),150)," ")[2]
- if version != tostring(ver) then
- print(Color(255,150,70), "[SF Visualizer ver. "..ver.."] " .. lang.new_update .. "" .. version)
- else
- print(Color(70,255,70), "[SF Visualizer ver. "..ver.."] " .. lang.no_update .. "")
- end
- end)
- end
- end
- -------------------------------------------------------
- -- Permission setup
- local perms = {
- "render.screen",
- "bass.loadURL",
- "bass.play2D",
- "material.create",
- "material.urlcreate",
- "light.create",
- "http.get"
- }
- if owner() == player() then
- findUpdate()
- timer.create("load",1,1,function()
- if http.canRequest() then
- load_youtube()
- end
- end)
- else
- setupPermissionRequest(perms, lang.perm_description.."", true)
- if hasPermission("render.screen") then
- hook.add("render", "perms", function()
- render.drawSimpleText(256, 256, lang.accept_perm.."", 1, 1)
- end)
- end
- hook.add("permissionrequest", "perms", function()
- if permissionRequestSatisfied() then
- hook.remove("permissionrequest", "perms")
- hook.remove("render", "perms")
- if http.canRequest() then
- load_youtube()
- end
- end
- end)
- end
- -------------------------------------------------------
- end
Add Comment
Please, Sign In to add comment