remove: Old exemples
This commit is contained in:
parent
6ce0759fac
commit
a857b9be51
3 changed files with 0 additions and 503 deletions
|
|
@ -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;
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
Loading…
Reference in a new issue