Skip to content

Instantly share code, notes, and snippets.

@spillz
Last active November 2, 2023 20:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save spillz/add3090abd2f65e6dfc3516d89e0dc30 to your computer and use it in GitHub Desktop.
Save spillz/add3090abd2f65e6dfc3516d89e0dc30 to your computer and use it in GitHub Desktop.
Widget spam examples
<!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>
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