Last active
November 2, 2023 20:46
-
-
Save spillz/add3090abd2f65e6dfc3516d89e0dc30 to your computer and use it in GitHub Desktop.
Widget spam examples
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<title>ESKV Widget Spam Example</title> | |
<!-- The CSS in the style tag is used to set a black background and maximize available client space for the canvas--> | |
<style> | |
body{ | |
background-color: rgb(0, 0, 0); | |
text-align: center; | |
} | |
html, body, canvas { | |
margin: 0 !important; | |
padding: 0 !important; | |
position: absolute; | |
top:0; | |
left:0; | |
} | |
</style> | |
<!-- IMPORTANT: The ESKV App draws to a canvas that must be ID'd as canvas--> | |
<canvas id="canvas"></canvas> | |
<script type="module"> | |
import {App, Widget, Vec2, Button, rand, math} from '../lib/eskv.js'; //Import ESKV objects | |
//We'll create a moving widget by augmenting the update loop to move widgets with fixed velocity | |
class MovingWidget extends Widget { | |
vel = new Vec2([0,0]); //add a velocity property | |
update(app, millis) { | |
super.update(app, millis); //make sure to call super or the widget will be broken | |
// Now move the widget and bounce off walls defined by the parent. | |
this.x=math.clamp(this.x+this.vel.x*millis, this.parent.x, this.parent.right-this.w); | |
this.y=math.clamp(this.y+this.vel.y*millis, this.parent.y, this.parent.bottom-this.h); | |
if(this.x==this.parent.x || this.x==this.parent.right-this.w) this.vel.x*=-1; | |
if(this.y==this.parent.y || this.y==this.parent.bottom-this.h) this.vel.y*=-1; | |
} | |
} | |
//Create a new app instance | |
var wsDemo = new App(); | |
//Add widgets by setting the children property of the baseWidget (you can alternatively call addChild) | |
wsDemo.baseWidget.children = [ | |
//Adds 2 Buttons | |
new Button({text:'Add 100 Widgets', wrap:true, hints:{center_x:0.25,y:0,w:0.4,h:0.1}, id:'button1'}), | |
new Button({text:'Clear', wrap:true, hints:{center_x:0.75,y:0,w:0.4,h:0.1}, id:'button2'}), | |
new Widget({hints:{center_x:0.5,y:0.1,w:1,h:0.9}, id:'frame'}), | |
] | |
// Retrieve widgets so we can wire up some button logic | |
let but1 = wsDemo.findById('button1'); | |
let but2 = wsDemo.findById('button2'); | |
let frame = wsDemo.findById('frame'); | |
let r = rand.randomFloat; | |
//Logic for button presses | |
but1.on_press = (e,o,v) => { | |
for(let i=0;i<100;i++) { | |
let x = r(0.1,0.9); | |
let y = r(0.1,0.9) | |
let size = r(1,2); | |
let color = math.colorString([r(), r(), r()]); | |
let w = new MovingWidget({bgColor: color, w:size, h:size, x:frame.x+frame.w*x, y:frame.y+frame.h*y}) | |
let dx = Math.random()>0.5?Math.random()*0.5+0.5:-Math.random()*0.5-0.5 | |
let dy = Math.random()>0.5?Math.random()*0.25+0.25:-Math.random()*0.25-0.25 | |
w.vel = new Vec2([dx,dy]).scale(0.005); | |
frame.addChild(w); | |
} | |
} | |
but2.on_press = (e,o,v) => { | |
frame.children = []; | |
} | |
//Start the app | |
wsDemo.start(); | |
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from kivy.app import App | |
from kivy.uix.widget import Widget | |
from kivy.uix.floatlayout import FloatLayout | |
from kivy.uix.button import Button | |
from kivy.graphics import Rectangle, Color | |
from kivy.vector import Vector | |
from kivy.clock import Clock | |
from random import random | |
class MovingWidget(Widget): | |
def __init__(self, **kwargs): | |
super().__init__(**kwargs) | |
self.vel = Vector(2 * (0.5 - random()), 2 * (0.5 - random())) | |
with self.canvas: | |
self.color = Color(random(), random(), random()) | |
self.rect = Rectangle(pos=self.pos, size=self.size) | |
self.bind(pos=self.update_rect, size=self.update_rect) | |
def update_rect(self, *args): | |
self.rect.pos = self.pos | |
self.rect.size = self.size | |
def move(self): | |
self.pos = Vector(*self.pos) + self.vel | |
if self.x < 0 or (self.x + self.width) > self.parent.width: | |
self.vel.x *= -1 | |
if self.y < 0 or (self.y + self.height) > self.parent.height: | |
self.vel.y *= -1 | |
def on_touch_down(self, touch): | |
if self.collide_point(*touch.pos): | |
self.parent.remove_widget(self) | |
class Frame(Widget): | |
counter = [] | |
def update(self, dt): | |
self.counter.append(dt) | |
if len(self.counter)>=60: | |
print(sum(self.counter)/len(self.counter)) | |
self.counter.clear() | |
for child in self.children: | |
if isinstance(child, MovingWidget): | |
child.move() | |
class WidgetSpamApp(App): | |
def build(self): | |
root = FloatLayout(size_hint=(1,1)) | |
frame = Frame(size_hint=(1.0, 0.9), pos_hint={'x':0,'top':0.1}) | |
add_btn = Button(text='Add 100 Widgets', size_hint=(0.4,0.1), pos_hint={'x':0,'top':1}) | |
clear_btn = Button(text='Clear', size_hint=(0.4,0.1), pos_hint={'right':1,'top':1}) | |
add_btn.bind(on_press=self.spawn_widgets) | |
clear_btn.bind(on_press=self.clear_widgets) | |
root.add_widget(frame) | |
root.add_widget(add_btn) | |
root.add_widget(clear_btn) | |
Clock.schedule_interval(frame.update, 1.0 / 60.0) | |
self.frame = frame | |
return root | |
def spawn_widgets(self, instance): | |
for i in range(100): | |
size = (20 * (random() + 1), 20 * (random() + 1)) | |
widget = MovingWidget(size=size, pos=(random() * (self.frame.width - size[0]), random() * (self.frame.height - size[1]))) | |
self.frame.add_widget(widget) | |
def clear_widgets(self, instance): | |
for child in list(self.frame.children): | |
if isinstance(child, MovingWidget): | |
self.frame.remove_widget(child) | |
if __name__ == '__main__': | |
WidgetSpamApp().run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment