diff --git a/exemple/elasticScrollFrame.lua b/exemple/elasticScrollFrame.lua deleted file mode 100644 index fa09c5c..0000000 --- a/exemple/elasticScrollFrame.lua +++ /dev/null @@ -1,381 +0,0 @@ -local Quad = require(game.ReplicatedStorage:WaitForChild "Quad"); ---@module "Quad.src" -local _ = Quad.init "components"; local round,class,mount,store,event,tween = _.round,_.class,_.mount,_.store,_.event,_.tween; -local RunService = game:GetService"RunService"; -local IsRunning = RunService:IsRunning(); -local max = math.max; -local min = math.min; -local abs = math.abs; - --- init quad -local scrollFrame = class.extend(); -local connection = event.new; -local frame = class "Frame"; -frame.BorderSizePixel = 0; -local button = class "TextButton"; -button.BorderSizePixel = 0; -button.Text = ""; -button.AutoButtonColor = false; -local image = class "ImageLabel"; -image.BackgroundTransparency = 1; - --- const -local white = Color3.fromRGB(255,255,255); -local scrollMut = 100; -- Used for multiply input when using mosue scroll -local elasticMut = 18; -- Used for multiply input when overscrolling -local fitTime = 0.26; -- Used for reset overscroll when mouse scroll -local tweenTime = 0.71; -- Used for tween time -local mouseUpMut = 6; -- Used for multiply input when drag input ended -local scrollbarOverMut = 0.18; -- Used for multiply size of scrollbar when overscrolling - --- tween for moving -local out = tween.EasingDirections.Out; -local exp2 = tween.EasingFunctions.Exp2; -local tweenData = { - Time = tweenTime; - Direction = out; - EasingFunction = exp2; -}; -local runTween = tween.RunTween; -local stopTween = tween.StopTween; - --- user input service -local userInputService = game:GetService "UserInputService"; -local inputEnded = userInputService.InputEnded; -local inputChanged = userInputService.InputChanged; -local mouseMovement = Enum.UserInputType.MouseMovement; -local mouseWheel = Enum.UserInputType.MouseWheel; -local shiftModifier = Enum.ModifierKey.Shift; -local mouseButton1 = Enum.UserInputType.MouseButton1; -local touch = Enum.UserInputType.Touch; - --- Calc Elastic -local calcElastic do - local maxLogX = 30; - local mlog = math.log; - local maxlog = mlog(maxLogX+1,2); - local function log(x) - return min(mlog(x*maxLogX+1,2),maxlog)/maxlog; - end - function calcElastic (elastic,pos,max) - if pos < 0 then - return - (log(abs(pos)/scrollMut*elasticMut/elastic)*elastic); - elseif pos > max then - return max + (log((pos-max)/scrollMut*elasticMut/elastic)*elastic); - end - return pos; - end -end - --- Init class -function scrollFrame:init(props) - local CanvasPosition = props.CanvasPosition or Vector2.new(0,0); - self._targetX = CanvasPosition.X; - self._targetY = CanvasPosition.Y; - props.CanvasPosition = CanvasPosition; - self._inputIndex = -20000000; - self._mouseConnection = connection(); - self._overscrollX = false; - self._overscrollY = false; - props:default("CanvasPosition",CanvasPosition); - props:default("CanvasSize",UDim2.fromScale(1,2)); - props:default("Size",UDim2.new(1,0,1,0)); - props:default("Position",UDim2.new(0,0,0,0)); - props:default("Elastic",142); - props:default("OverscrollX",false); - props:default("OverscrollY",true); - props:default("BackgroundTransparency",0); - props:default("ZIndex",1); - props:default("BackgroundColor3",white); - props:default("ScrollbarSizeX",2); - props:default("ScrollbarPositionY","Right"); - props:default("ScrollbarPositionX","Bottom"); - props:default("ScrollbarVisibleY",true); - props:default("ScrollbarSizeY",2); - props:default("ScrollbarVisibleX",true); - props:default("ScrollbarPadding",2); - props:default("ScrollbarColor3",Color3.fromRGB(145, 145, 145)); - props:default("ScrollbarTransparency",0.3); - -- props "ScrollbarPadding":register(function () - -- self:fit(); - -- self.__prop - -- end); - -- props "ScrollbarPadding":register(function () - -- self:fit(); - -- self.__prop - -- end); - -- ScrollbarSizeX -end - --- Render objects -function scrollFrame:render(props) - return button { - Size = props "Size"; - Position = props "Position"; - BackgroundTransparency = props "BackgroundTransparency"; - BackgroundColor3 = props "BackgroundColor3"; - ZIndex = props "ZIndex"; - ClipsDescendants = true; - [event.created] = function (this) - this.InputChanged:Connect(function (input) - if self._mouseDown or self._scrollbarDown then - return; - end - local inputType = input.UserInputType; - if inputType == mouseWheel then - local x,y = 0,1; - if input:IsModifierKeyDown(shiftModifier) then - x,y = 1,0; - end - local scroll = input.Position.Z * scrollMut; - local inputIndex = self:update(self._targetX + x*scroll,self._targetY - y*scroll); - delay(fitTime,function () - if inputIndex == self._inputIndex then - self:fit(); - end - end); - end - end); - end; - [event "MouseButton1Down"] = function (this,downX,downY) - local lastX,lastY = self._targetX,self._targetY; - local upX,upY = downX,downY; - self._mouseDown = true; - local mouseConnection = self._mouseConnection; - mouseConnection:disconnect(); - mouseConnection:add(inputEnded:Connect(function (input) - self._mouseDown = false; - local inputType = input.UserInputType; - if inputType == mouseButton1 or inputType == touch then - local position = input.Position; - local x = position.X; - local y = position.Y + (IsRunning and 36 or 0); - self:update(self._targetX + ((x - upX) * mouseUpMut),self._targetY + ((- y + upY)*mouseUpMut)); - mouseConnection:disconnect(); - self:fit(); - end - end)); - mouseConnection:add(inputChanged:Connect(function (input) - if input.UserInputType == mouseMovement then - local position = input.Position; - local x,y = position.X,position.Y + (IsRunning and 36 or 0); - - self:update(lastX + (downX - x),lastY + (downY - y)); - upX,upY = x,y; - end - end)); - end; - frame { - [event.prop "AbsoluteSize"] = function () - self:fit(); - end; - BackgroundTransparency = 1; - Size = props "CanvasSize"; - ZIndex = props "ZIndex"; - Position = UDim2.fromOffset(self._targetX,self._targetY); - [event.created] = function (this) - self._holder = this; - end; - }; - button { - AnchorPoint = props "ScrollbarPositionY":with(function (_,value) - return value == "Right" and Vector2.new(1,0) or Vector2.new(0,0); - end); - [event.created] = function (this) - self._scrollbarY = this; - end; - Position = props.ScrollbarPositionY == "Right" and UDim2.new(1,0,0,0) or UDim2.new(0,0,0,0); - BackgroundTransparency = 1; - Visible = props "ScrollbarVisibleY"; - image { - roundSize = 2000; - ImageColor3 = props "ScrollbarColor3"; - ImageTransparency = props "ScrollbarTransparency"; - Size = props "ScrollbarSizeY,ScrollbarPadding":with(function (store) - return UDim2.new(0,store.ScrollbarSizeY,1,store.ScrollbarPadding * -2); - end); - Position = UDim2.fromScale(0.5,0.5); - AnchorPoint = Vector2.new(0.5,0.5); - }; - }; - button { - AnchorPoint = props "ScrollbarPositionX":with(function (_,value) - return value == "Top" and Vector2.new(0,0) or Vector2.new(0,1); - end); - [event.created] = function (this) - self._scrollbarX = this; - end; - Position = props.ScrollbarPositionX == "Top" and UDim2.new(0,0,0,0) or UDim2.new(0,0,1,0); - BackgroundTransparency = 1; - Visible = props "ScrollbarVisibleX"; - image { - roundSize = 2000; - ImageColor3 = props "ScrollbarColor3"; - ImageTransparency = props "ScrollbarTransparency"; - Size = props "ScrollbarSizeX,ScrollbarPadding":with(function (store) - return UDim2.new(1,store.ScrollbarPadding * -2,0,store.ScrollbarSizeX); - end); - Position = UDim2.fromScale(0.5,0.5); - AnchorPoint = Vector2.new(0.5,0.5); - }; - }; - }; -end - --- Set scroll position with allowing overflow -function scrollFrame:update(x,y) - x,y = x or self._targetX,y or self._targetY; - local inputIndex = self._inputIndex + 1; - self._inputIndex = inputIndex; - - local holder = self._holder; - local holderAbsSize = holder.AbsoluteSize; - local objectAbsSize = self.__object.AbsoluteSize; - local holderX,holderY = holderAbsSize.X,holderAbsSize.Y; - local objectX,objectY = objectAbsSize.X,objectAbsSize.Y; - holderX,holderY = max(holderX,objectX),max(holderY,objectY); - local maxX = holderX - objectX; - local maxY = holderY - objectY; - - local elastic = self.Elastic; - x = self.OverscrollX and calcElastic(elastic,x,maxX) or max(min(maxX,x),0); - y = self.OverscrollY and calcElastic(elastic,y,maxY) or max(min(maxY,y),0); - - local overflowX = (x<0 and -1) or (x>maxX and 1); - local overflowY = (y<0 and -1) or (y>maxY and 1); - self._overscrollX = overflowX; - self._overscrollY = overflowY; - - runTween(holder,tweenData,{ - Position = UDim2.fromOffset(-x,-y); - }); - self._targetX,self._targetY = x,y; - self:updateScrollbar( - x,y,objectX,objectY,holderX,holderY,elastic, - (overflowX == -1 and abs(x)) or (overflowX == 1 and x-maxX), - (overflowY == -1 and abs(y)) or (overflowY == 1 and y-maxY) - ); - return inputIndex; -end - --- Get canvas position -function scrollFrame.getter:CanvasPosition() - return Vector2.new(self._targetX,self._targetY); -end - --- Set canvas postion -function scrollFrame.setter:CanvasPosition(pos) - local inputIndex = self:update(pos.X,pos.Y); - delay(fitTime,function () - if inputIndex == self._inputIndex then - self:fit(); - end - end); -end - --- Fit position (remove overflow) -function scrollFrame:fit() - local targetY = self._targetY; - local targetX = self._targetX; - local holder = self._holder; - local holderAbsoluteSize = holder.AbsoluteSize; - local objectAbsSize = self.__object.AbsoluteSize; - local objectX,objectY = objectAbsSize.X,objectAbsSize.Y; - local maxX = max(holderAbsoluteSize.X,objectX) - objectX; - local maxY = max(holderAbsoluteSize.Y,objectY) - objectY; - if targetX<0 or targetY<0 or targetX>maxX or targetY>maxY then - self:update( - max(min(targetX,maxX),0), - max(min(targetY,maxY),0) - ); - else - self:updateScrollbar(targetX,targetY); - end -end - --- update scrollbar -function scrollFrame:updateScrollbar(x,y,objectX,objectY,holderX,holderY,elastic,overflowX,overflowY) - local scrollbarY = self._scrollbarY; - local scrollbarX = self._scrollbarX; - - local objectSize; - if not objectY then - objectSize = self.__object.AbsoluteSize; - objectY = objectSize.Y; - end - if not objectX then - if not objectSize then - objectSize = self.__object.AbsoluteSize; - end - objectX = objectSize.X; - end - - local holderSize; - if not holderY then - holderSize = self._holder.AbsoluteSize; - holderY = max(holderSize.Y,objectY); - end - if not holderX then - if not holderSize then - holderSize = self._holder.AbsoluteSize; - end - holderX = max(holderSize.X,objectX); - end - - elastic = elastic or self.Elastic; - if scrollbarY then - local size; - if objectY >= holderY then - size = 0; - else - size = objectY / holderY; - if overflowY then - size = size * (1-overflowY/elastic) * scrollbarOverMut; - end - end - local sizeUdim = UDim2.new(0,self.ScrollbarSizeY+(self.ScrollbarPadding*2),size,0); - local pos = 0; - if size ~= 0 then - pos = (1-size)*(min(max(y/(holderY-objectY),0),1)); - end - local posUdim = UDim2.new(self.ScrollbarPositionY == "Right" and 1 or 0,0,pos,0); - if self._mouseDown then - stopTween(scrollbarY); - scrollbarY.Position = posUdim; - scrollbarY.Size = sizeUdim; - else - runTween(scrollbarY,tweenData,{ - Position = posUdim; - Size = sizeUdim; - }); - end - end - if scrollbarX then - local size; - if objectX >= holderX then - size = 0; - else - size = objectX / holderX; - if overflowX then - size = size * (1-overflowX/elastic) * scrollbarOverMut; - end - end - local sizeUdim = UDim2.new(size,0,0,self.ScrollbarSizeX+(self.ScrollbarPadding*2)); - local pos = 0; - if size ~= 0 then - pos = (1-size)*(min(max(x/(holderX-objectX),0),1)); - end - local posUdim = UDim2.new(pos,0,self.ScrollbarPositionX == "Top" and 0 or 1,0); - if self._mouseDown then - stopTween(scrollbarX); - scrollbarX.Position = posUdim; - scrollbarX.Size = sizeUdim; - else - runTween(scrollbarX,tweenData,{ - Position = posUdim; - Size = sizeUdim; - }); - end - end -end - -return scrollFrame; diff --git a/exemple/mybutton.lua b/exemple/mybutton.lua deleted file mode 100644 index d47ec95..0000000 --- a/exemple/mybutton.lua +++ /dev/null @@ -1,55 +0,0 @@ -local quad = require(script.Parent.quad); -local render = quad.init(); -local class = render.class; -local event = render.event; - -local myButton = class.extend(); -- 클래스 만들기 -local imageButton = class.import "ImageButton"; -- 로블 인스턴스 클래스화 -local textLabel = class.import "TextLabel"; -local textButton = class.import "TextButton"; - --- 인스턴스의 기본값 설정 -imageButton.BackgroundTransparency = 1; -textButton.BorderSizePixel = 0; -textLabel.Size = UDim2.fromScale(1,1); -textLabel.BackgroundTransparency = 1; - --- 기본 값 설정 -function myButton:init(props) - props.style = props.style or "round"; -- flat ... - props.roundSize = props.roundSize or 12; - props.Text = props.Text or "Button Text"; - props.Size = props.Size or UDim2.fromOffset(120,32); -end - --- 렌더링 -function myButton:render(props) - if props.style == "round" then - return imageButton { - Size = props "Size"; - Image = "http://www.roblox.com/asset/?id=4668069300"; - ScaleType = Enum.ScaleType.Slice; - SliceCenter = Rect.new(Vector2.new(516,516),Vector2.new(516,516)); - SliceScale = props "roundSize":with(function (value) - return 0.0019166666666667 * props.roundSize; - end); - [event "MouseButton1Click"] = { - self = self; - func = props.MouseButton1Click; - }; - textLabel { - Text = props "Text"; - }; - }; - elseif props.style == "flat" then - return textButton { - Size = props "Size"; - BorderSizePixel = 2; - } - else error ("unknown style " .. props.style); - end -end - -myButton.updateTriggers.style = true; - -return myButton diff --git a/exemple/readme.lua b/exemple/readme.lua deleted file mode 100644 index f1a28c2..0000000 --- a/exemple/readme.lua +++ /dev/null @@ -1,67 +0,0 @@ --- 이렇게 모듈을 부를 수 있다, 뒤에 if 가 붇은것은 자동완성이 뜨도록 하기 위해서 사용된다 ----@module "src/init.lua" -local quad = require(game.ReplicatedStorage:WaitForChild "Quad"); -local render = quad.init(); --- init 함수를 이용해 여러 스크립트가 이 모듈을 호출해도 완전히 별계의 --- 환경에서 실행될 수 있도록 만든다, init 를 호출하면 완전히 새로운 store 와 style --- 등을 가진 모듈을 새로 생성한다 - --- 하위 모듈을 이렇게 부른다 -local class = render.class; -local mount = render.mount; -local store = render.store; - --- 오브젝트를 이렇게 불러온다 -local frame = class "Frame"; -- 이렇게 원하는 오브젝트를 불러올 수 있다 -local text = class "TextLabel"; -text.TextSize = 17; -- 이렇게 오브젝트의 기본값도 정할 수 있다 -text.Size = UDim2.new(1,0,0,30); -local titleText = class "TextLabel"; --- 당연 이렇게 똑같은 className 을 가진 오브젝트를 여러번 import 도 된다 --- 다른 임포트에서 설정한 기본값은 여기에 적용되지 않는다 - -local gui = script.Parent; -local app = mount(gui,frame "testFrame" { -- mount 로 트리를 마운트한다, 이후 app 에서 unmount 호출가능 - Size = UDim2.fromOffset(120,60); - Position = UDim2.fromScale(0.5,0.5); - AnchorPoint = Vector2.new(0.5,0.5); - text "texts" { -- 이렇게 단순히 child 개체를 만들 수 있다 - Text = "We can make ui like this"; - }; - text "texts" { - Position = UDim2.fromOffset(0,30); - Text = "qweiufnwlqef"; - }; - titleText { -- 아이디를 명명하지 않아도 오브젝트를 바로 만들 수 있다 - Text = "test"; - }; -}); - -print(store.getObject("texts")); --- getObject 를 호출하면 해당 id 로 명명된 오브젝트중 --- 가장 처음으로 생성된 객체를 반환한다 -store.getObjects("texts"):each(function(index,this) - this.Text = "이렇게 모든 택스트를 한꺼번에 바꿀 수도 있습니다"; -end); --- getObjects 를 이용하면 해당 id 로 명명된 오브젝트가 담긴 array 를 가져온다 --- for 을 돌릴 수 있지만 each 를 이용해 async 된 작업을 수행할 수 있다 -store.getObjects("texts"):eachSync(function(index,this) - this.Text = "또한, 기본적으로 Aync 를 이용하기 때문에 순차적인 실행이 필요한 경우 Sync 를 붇여야합니다"; -end); --- sync 를 하면 일반 스크립트를 실행하는것 처럼 순차적으로 실행되도록 만들 수도 있다 --- 이 때 순서는 먼저 생생된 순서이다, 항상 같음을 유지한다는 보장이 없으므로 순서가 중요한경우 --- 직접 for 을 이용해 순서 검증을 한 뒤 task 를 수행해야한다 - --- 이렇게 어떤 오브젝트를 가지고 task 수행하는 thread 를 만들 수 있다 -do local this = store.getObject("testFrame"); - spawn(function () - local flip = false; - while wait(0.5) do - flip = not flip; - this.BackgroundTransparency = flip and 1 or 0; - end - end); -end - -app.unmount(); -- 트리의 객체들을 모두 파기한다, 플러그인에서 unload 같은곳에 쓰는 함수 -return app;