Skip to content

ZIM 016

Latest
Compare
Choose a tag to compare
@danzen danzen released this 28 Jan 21:09
· 38 commits to master since this release

1. SHADERS

https://zimjs.com/016/shaders.html
ZIM now supports shaders converted to 2D canvas as a dynamic Bitmap (similar to video in ZIM).
This means that shaders can be layered into ZIM features the same as other DisplayObjects.

// makes a gradient changing across the width
// note the multiline back tick quote - that is just JavaScript 6
// but inside is GLSL and in particular OpenGL shader coding language
const fragment = `  
    void mainImage(out vec4 fragColor, in vec2 fragCoord) {
        fragColor = mix(vec4(1,1,0,1), vec4(0,1,1,1), fragCoord.x/iResolution.x);
    }
`; 
new Shader(W, H, fragment).center();

shaders_updates

WHAT ARE SHADERS
Shaders have their own language GLSL to code the GPU (Graphical Processor Unit).
They are the basis of 3D and can also make very cool 2D effects!

The code is in two parts: Vertex Shaders and Fragment Shaders.
Vertex shaders control the points (vertices) of shapes (triangles).
Fragment Shaders control the color the pixels of the shapes.
We tend to use fragment shaders on the Canvas 2D.
The code is very low level and tricky so that it runs as fast as possible.

You will probably start by using existing code as there are lots of examples.
For instance - see ShaderToy:
https://www.shadertoy.com/

Also see the Docs for more information and examples:
https://zimjs.com/docs.html?item=Shaders

Note that the site banner is a shader that can be controlled with a little slider at right.
We control shaders from the outside with Uniforms (shader properties we can set)

2. EMITTER CONFIGURATOR

https://zimjs.com/016/emitter.html
On request, we have made an Emitter Configurator that uses sliders and checkboxes to set the many parameters,
visually see the results, and copy the resulting code.

emitter_updates

Emitters can emit any DisplayObject as a particle
so not all configurations are shown here. Also the Shape option for the obj is not here.
See https://zimjs.com/docs.html?item=Emitter for more possibilities.

We are keeping ZIM a coding language rather than moving into an authoring environment like Flash.
Recall our discontinued (draft) visual editor https://zimjs.com/snips/
But perhaps we can make a few CONFIGURATORS over time - like for a Button next?
These we can list in the tools section - but will not call them raw tools like our set of tools so far:
Distill, Zapps, Wonder, AssetList and Doctor which are more HTML-based admin tools.
We have made a new line there for the Configurators.

3. NORMALIZE AND RATIO - IMPROVEMENT

https://zimjs.com/016/normalize.html
ZIM animate() with sequence animates each item in a container,
but this can be awkward when animating a tile for instance.
The sequence starts at to left and goes across the columns and down the rows.
Or a sequenceReverse will do the opposite.
But what about animating from the middle and out radially?
We noticed that GSAP was doing very cool effects from the center (or any sides) of containers.

Introducing the normalize() method and ratio property of a Container to solve this!
Normalize can take any property and assign a ratio for each child in a container
that is how close 1-0 that child is to the maximum property (among all the children).
Using a sequence time of 0 to animate each child individually
and setting the rate property relative to the ratio will have the same effect as the cool GSAP animations.

// animate based on how far from the center 
// "reg" will also automatically adjust the registration points to the start position 
const tile = new Tile(new Rectangle(10, 10, series(green,blue,yellow)), 20, 20, 5, 5)
	.normalize("reg", CENTER)
	.center()
	.noMouse()
	.animate({
		props:{scale:2},
		time:2,
		ease:"elasticOut",
		rate:target=>{return 1 + target.ratio*4},
		sequence:0 // turn on per item animation
	});

The ratio can also be used on its own without animate().
For instance, the scale of the child could be set to the ratio
depending on how close it is to the center of the container.

normalize_updates

const tile = new Tile(new Rectangle(70,70,white,black).reg(CENTER), 9, 1, 20)
	.normalize("x", CENTER)
	.center();

// scale the items based on the distance from the center
// note, could set the strokeObj:{ignoreScale:true} param of Rectangle above too
tile.loop(item=>{
	zogy(decimals(item.ratio)); // 0, .3, .5, .8, 1, .8, .5, .3, 0
	item.sca(.5 + item.ratio*2);
});

// adjust the spacing by re-tiling the scaled items
const final = new Tile({
	obj:tile.items, 
	cols:tile.items.length,
	rows:1,
	spacingH:-10, // or make positive to avoid overlapping
	unique:true, // make sure we do not pick (ZIM VEE) from the array
	valign:CENTER
}).center()

tile.dispose();

final.sortBy("ratio"); // make more central objects come to front

4. SORTBY

https://zimjs.com/016/normalize.html
The Container now has a sortBy(prop, inverse) method to sort children levels based on a numeric property.
This uses the CreateJS sortChildren(sortFunction) but reduces thinking needed to construct the sortFunction.
However, if a more complex sort function is needed, then use sortChildren() - see CreateJS docs.
Also, see the last example up above where we sortBy("ratio")
Using sortBy("ratio", true); for inverse would make the middle objects behind the side objects.

5. RANGE - IMPROVEMENT

https://zimjs.com/016/range.html
ZIM Slider() now has a range parameter to set two buttons on the slider that give range values:

range_updates

// SLIDER RANGE PARAMETERS
range - (default null) make the slider a range slider with two circle buttons
this will provide read and write rangeMin, rangeMax and rangeAve values instead of currentValue
also will provide a read only rangeAmount
rangeBar, rangeSliderA, rangeSliderB, rangeButtonA and rangeButtonB properties will be added
rangeColor - (default purple) set the color of the range bar
rangeWidth - (default 3 pixels wider than the barWidth on both sides) set the thickness of the range bar (not its lenght)
rangeMin - (default min) set the minimum value of the range
rangeMax - (default (max-min)/2) set the maximum value of the range
rangeAve - (default null) set the range average value - this may relocate rangeMin and rangeMax settings

SLIDER RANGE PROPERTIES
rangeBar - access to the ZIM Rectangle that makes the bar between the range buttons
rangeSliderA - access to the first slider made - which is the same as this (the Slider object)
rangeSliderB - access to the second slider made which is a ZIM Slider added to this slider with the bar, ticks, labels, accents removed
rangeButtonA - access to the first slider's button - so the same as button
rangeButtonB - access to the second slider's button - so the same as ranageSilderB.button
rangeMin - get or set the minimum value of the range
in some cases, it may be better to animate the rangeSliderA.currentValue and rangeSliderB.currentValue
rather than the rangeMin and rangeMax for instance when wiggling to avoid crossover issues
rangeMax - get or set the maximum value of the range
rangeAve - get or set the average value of the range
rangeAmount - read only get the range amount

6. WIGGLE DEFAULT BASEAMOUNT AND END ON START - IMPROVEMENT

https://zimjs.com/docs.html?item=wiggle
ZIM wiggle() now has a default baseAmount that matches the property's current value
amd now ends on its start position if totalTime is set. Thanks Ami Hanya for the prompting.
There is an endOnStart parameter added to the end that defaults to true - set to false to not force end on start.

// the baseAmount parameter is null which means it will wiggle about the target's current x in this case
// after 4 seconds the circle will end its wiggle at the start x (in the center)
new Circle().centerReg().wiggle("x", null, 10, 100, .5, 1, 4);

7. NEW FORUM - IMPROVEMENT

forum_updates

ZIM has a new Forum and we will phase out Slack over the next couple months.
We are keeping Discord. There are two main reasons for moving:
The forum content will show in Web searches

The messages will persist and not be removed after three months

Discourse has been used for many tech communities including three.js, Cloudflare, FreeCodeCamp, OpenAI, etc. We hope you like it!
We will refer to this as the ZIM Forum, not Discourse, as we are still keeping Discord - and it would just be too confusing.
We will post the URL to the forum once we get settled there a bit more.
We are looking into setting up an invite system as well.

8. LABELWORDS - IMPROVEMENT

https://zimjs.com/016/labelwords.html
ZIM LabelWords() splits text up into individual word labels.
LabelWords is similar to LabelLetters but extends a Wrapper so it has all the settings of a Wrapper.

new LabelWords({
	label:"Here is LabelWords that divides text into words for individual control!",
	color:white, 
	itemRegY:BOTTOM, 
	itemCache:true,
	backgroundColor:series(red,orange,pink,green,blue,purple),
	size:50,
	width:700,
	align:CENTER
}).center().animate({
	props:{scaleY:0},
	time:.5,
	rewind:true,
	loop:true,
	sequence:.1
});

9. OBJECTCONTROLS - IMPROVEMENT

https://zimjs.com/016/objectcontrols.html
ObjectControls were coded outside ZIM for three.js
We have added them automatically to the zim_three helper module.
They come from https://github.com/albertopiras/threeJS-object-controls
They allow any object in three.js to be rotated or animated independently.
This will appear somewhat like OrbitControls
but OrbitControls move and rotate the camera around the scene - not individual objects.
Thanks Pettis Brendan for the suggestion.

10. FADE AND PAN SOUND METHODS - IMPROVEMENT

https://zimjs.com/016/sound.html
The ZIM Aud() play() method returns a CreateJS AbtractSoundInstance.
We have added a fade(volume, time, call) method to the AbstractSoundInstance
and a panSound(pan, time, call) - this cannot be pan() as there is a pan property.
We could have called fade() as fadeSound() to be consistent,
but fadeSound() will probably be rarely used whereas fade() quite a lot.
So chose the shorter name.

let sound; // do not try and play sound before interacting
const toggle = new Toggle(100, 60, "SOUND").center().change(()=>{  

	// if there is not a sound then make one
	if (!sound) sound = new Aud("caves.mp3").play(0, true);

	// fade in or out the sound
	if (toggle.toggled) sound.fade(1); // default fade time is 2 seconds
	else sound.fade(0, 1.5); // fade out a little faster
});

11. SPEECH

https://zimjs.com/016/speech.html
https://zimjs.com/016/speech2.html
https://zimjs.com/016/voices.html
Create a new Speech() and use talk() or listen()
The talk() will speak words
The listen() will turn voice into words
This is a short wrapper class for the Web Speech API
https://developer.mozilla.org/en-US/docs/Web/API/Web_Speech_API/Using_the_Web_Speech_API
Thanks Karel Rosseel for the initial research on Speech.
Just a note - this has been around for about 6 years...
The performance now is excellent!
Read more options at https://zimjs.com/docs.html?item=Speech

const speech = new Speech();  // new Speech object
speech.talk("words") // tell Speech to say words 
speech.listen(); // tell Speech to listen
speech.on("result", e=>{zog(e.words, e.confidence)});

12. PERMISSION ASK - IMPROVEMENT

https://zimjs.com/docs.html?item=PermissionAsk
Renamed SensorsAsk() to PermissionAsk() to handle mic and cam on iOS - BREAK
as well as the deviceorientation and devicemotion

// on iOS, the app must be interacted with before using mic or cam
// this goes right to permissions on computer and android
// but pops up a PermissionAsk Pane on iOS then if yes, goes to permissions on iOS
new PermissionAsk(init, "mic"); // or "cam" or "miccam" - see docs for orientation and motion
function init(val) {
	zog(val); // media stream if yes to permissions otherwise false
	S.update();
}

13. GOOGLE FONTS SHORTCUT - IMPROVEMENT

https://zimjs.com/016/fonts.html
Added a Google Fonts shortcut - use gf_ then the font name with capital first letter
The spacing can be left + in the assets parameter or left as a space.
But the spacing cannot be + in the font name so just put spaces.
Note that case matters and they are all uppercase first letters.

new Frame(FIT, 1024, 768, light, dark, ready, "gf_Roboto");
function ready() {    
    new Label({text:"Am I a Robot?", font:"Roboto"}).center();
}

14. TILE BACKGROUND PADDING - IMPROVEMENT

https://zimjs.com/016/fonts.html
Added backgroundPadding, backgroundPaddingH, backgroundPaddingV parameters to ZIM Tile() - BREAK
These come just after the backgroundColor parameter

tilepadding_updates

15. ZIM CIRCLE PERCENT ARC

https://zimjs.com/016/percentarc.html
Added a percentArc parameter before the strokeObj and a percentArc property - BREAK
that makes an arc when used with percent.
This is good for making moon shapes.
Note, due to canvas winding, the arc will not do very thin cresents as expected
instead once the inner arc is as wide as the outer arc, it makes a straight line.
For thin crecents, overlap the circle with a circle that matches the background color.
Or if the background is an image, etc. then mask a clone of the background with the arc circle.

// make a moon - use 60% of the circle 
// then cut into that with a circle at point 30% the radius in towards middle
new Circle({percent:60, percentArc:-30, radius:200, color:white})
	.rot(-120)
	.center();

16. INDICATOR DISPLAY OBJECT - IMPROVEMENT

https://zimjs.com/016/indicator.html
The ZIM Indicator() indicatorType can now accept any DisplayObject (watch the size).
Thanks Karel Rosseel for the suggestion.

new Indicator({
	indicatorType:new Label("Z",40,null,white), // using a label to make indicator lights
	foregroundColor:white,
	backgroundColor:red,
	backgroundAlpha:1,
	selectedIndex:1,
	fill:true,
	interactive:true
}).sca(2.5).center();

17. STYLE GROUP ONLY - IMPROVEMENT

https://zimjs.com/docs.html?item=STYLE
ZIM STYLE now will use group styles even if style=false on the object.
This is handy as all object styles except for the group styles can be turned off.

// the circle will not be red but will get percent 50
STYLE = {color:red, wonder:{percent:50}};
new Circle({style:false, group:"wonder"}).center();

18. GENERAL

fixed ZIM Series reverse to not automatically start at the end - but rather from its current state - IMPROVEMENT BREAK
unless the current state is 0 then it goes from the end. Thanks Karel Rosseel for the report.
Adjusted ZIM convertColor() to accept HEX NUMBER in the form of 0x as input - IMPROVEMENT
Updated ZIM Skool - Statements image to include const.
Changed all anonymous functions to arrow functions.
Fixed bug in Pane so "display" property also points to backing.
Made transformControls methods return the transformControls object rather than the object the transforms are on - BREAK
Added decimals to List().slider() to set the decimals for the Stepper - IMPROVEMENT
Also added a call property to List.slider(), List.checkBox() and List.colorPicker() - IMPROVEMENT
Fixed Pane and Panel so textArea, tag, loader are removed and added as opened and closed - IMPROVEMENT
Note - in general, do not add these to Window() unless non-scrolling and then must manually handle collapsing, closing, resizing, dragging
The overhead is too much for a Window in general as it handles things like Wrappers and Lists that may have many items - usually not TextAreas, etc.
Fixed Button() so roll background color on toggle and wait operates properly - was being overridden by new down background color - IMPROVEMENT
Also added wait, waitTime and toggle to STYLE - this was an oversight.
Made Button not show default "CLICK" if showing icon or backing - IMPROVEMENT
Fixed trace setting on Emitter - it needed to be adjusted due to moving particles into their own container - IMPROVEMENT
Now the cache size is the stage and setting traceShiftX and traceShiftY will move both sides of the bounds bigger (or smaller)
Fixed Emitter to use that.trace, that.sinkForce, and that.width so these update on property change.
Fixed default traceDecayTime needed to be put after decayTime gets its defaults
No "" needed if icon or backing provided and no label set - IMPROVEMENT
Added a RANDOM constant with value of "random"
Added uppercase as a convenience STYLE to set any object with a label or text property to uppercase
cursor and shadow have been added for STYLE - these were an oversight - IMPROVEMENT
Made Pane() have a keyboardActive parameter - so it invisibly sets F.keyboardMessage
to get keyboard on iFrame and close pane when pressed - IMPROVEMENT
Added Keyboard entry to TIPS
Fixed a bug in animate() where animating the same properties over again was not removing the previous ticker function - IMPROVEMENT
This is basically a blank function in the queue to tell the stage to update but it would then leave the app on permanent stage.update()
To put this in perspective, three.js, P5js, etc. have permanent update - still we are glad we found the bug.
Adjusted corner for Rectangle to be 0 of array is missing any of its 4 points - IMPROVEMENT
Added rounded corners to Blob Rectangle points

// use a rounded Rectangle to make a Blob with a rounded rectangle shape
new Blob({
	points:new Rectangle(200,200,red,null,null,50)
}).sca(2).center();

Label italic will skew(10) a background on the label if there is one - IMPROVEMENT
Made transformControls methods return the transformControls object rather than the object the transforms are on - BREAK
ZIM TextInput() no longer dispatches an input event if the text property is changed progromattically - BREAK
Generally, events are not triggered if the value is programmatically changed.
For instance, setting slider.currentValue = 10 will no trigger a change event - only the user using the slider triggers the event.
Made the ZIM TextEditor() show the placeholder text in the label for the TextEditor - IMPROVEMENT
Added adjustBounds property to options of cache() so that when set to true - IMPROVEMENT
cached items with dimensions not equal to their original have their bounds and registraction adjusted as expected.
This was not the default for CreateJS which was keeping the original, full object bounds and registration point.
See https://codepen.io/zimjs/pen/RwdbdRg - where we have added the adjustment (here patched in ZIM 015).
Making this default breaks many ZIM things from transform handles to TextureActives, etc.
So we have added it as an option property to use when needed. See cache() in the docs for more info.
On Container(), Bitmap() and Shape()
Fixed the cursor spacing on TextInput when the size is changed and resize() called - IMPROVEMENT
ZIM loop() with interval now works properly with start and end values different than defaults - thanks Kirk Goble for the report - IMPROVEMENT
Fixed Window scrollbar so it ignores the top corner curve if there is a titleBar as that curve is up in the title bar - IMPROVEMENT
Adjusted ZIM Frame() so assetObject uses a path provided to the assetObject even if there is no id (just src) - IMPROVEMENT
and font in assetObject uses a path provided in assetObject - was missing the path addition.
Fixed tap() equation for distance - was using Math.abs(lastX+lastY-currentX-currentY) < distance - IMPROVEMENT
well, this equation does not work if the mouse is moved on a 45 degree angle
so long distance taps were happening on a 45 degree angle List - hahaha!
have to test Math.abs(lastX-currentX) < distance && Math.abs(lastY-currentY) < distance