ZIM BITS TUTORIAL
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>ZIM BITS - Scrollbar with Slider Component</title>
<!-- Welcome to ZIM at https://zimjs.com - Code Creativity! -->
<!-- ZIM runs on the HTML Canvas powered by JavaScript and CreateJS https://createjs.com -->
<!-- Founded by Inventor Dan Zen - http://danzen.com - Canadian New Media Award Winner -->
<!-- ZIM is free to use. You can donate to help improve ZIM at http://zimjs.com/donate -->
<script src="https://zimjs.org/cdn/1.3.4/createjs.js"></script>
<script src="https://zimjs.org/cdn/01/zim_min.js"></script>
<!-- use zimjs.com/distill for minified individual functions! -->
<script src="https://zimjs.com/bits/footer10.js"></script><!-- you will not need this -->
<script>
// SCALING OPTIONS
// scaling can have values as follows with full being the default
// FIT sets canvas and stage to dimensions and scales to fit inside window size
// FILL sets canvas and stage to dimensions and scales to fit outside window size
// FULL sets stage to window size with no scaling
// "tagID" add canvas to HTML tag of ID - set to dimensions if provided - no scaling
const scaling = FIT; // this will resize to fit inside the screen dimensions
const width = 1000;
const height = 800;
const color = dark; // or any HTML color such as "violet" or "#333333"
const outerColor = light;
new Frame(scaling, width, height, color, outerColor, ready);
function ready() {
// given F (Frame), S (Stage), W (width), H (height)
// ZIM BITS - Scrollbar using ZIM Slider (2016 - updated 2022)
// *****************************
// ******* ALL THIS GOES AWAY WITH ZIM Window() and ZIM List() *********
// see also ZIM BITS Window example with the Window() class
// also see ZIM List() in Docs
// the Slider class can act as a scrollbar setting the inside parameter to true
// this example shows two different scrollbars styled differently
// the second one adds damping to the page movement and keyboard functionality
// in both cases we make the scoll button change to reflect the percentage of content showing
// STEPS
// 1. make assets to scroll - put these in a mask
// 2. make a Button for the scrollbar that will be passed into the slider
// 3. add a Slider with the inside property set to true
// 4. capture the change event and scroll the page to the right location
// with this setting, components will not update the stage - we need to in our event functions!
OPTIMIZE = true;
// now a single createjs Ticker is made that will handle stage update
// we do this for the second example which uses damping which requires continuous update
Ticker.update = true;
// 1. make assets to scroll - put these in a mask
let viewerW = 400;
let viewerH = 300;
let scrollW = 25;
const mask = new Rectangle(viewerW,viewerH)
.addTo()
.pos(70, 200);
const page = new Container()
.addTo()
.pos(mask.x, mask.y);
let pageH = viewerH*2;
const back = new Rectangle(viewerW, pageH, darker)
.addTo(page);
const circle = F.makeCircles(viewerW/2*.8)
.centerReg(page);
page.setMask(mask);
// 2. make a Button for the scrollbar that will be passed into the slider
// width, height, label, color, rollColor, borderColor, borderWidth, corner, shadowColor, shadowBlur, hitPadding
const button = new Button({
width:scrollW,
height:viewerH/pageH*viewerH, // note the proportion of viewable height / total height (then * viewable height)
label:"",
color:pink,
rollColor:green,
corner:0
}).expand(); // helps on mobile
// 3. add a Slider with the inside property set to true
// min really is the slider start value and max is the slider end value
// in this case, we want the page to go from 0 to negative the height of the hidden part of the page
// min and step default to 0 anyway but including them just as a reminder
// min, max, step, button, barLength, barWidth, barColor, vertical, useTicks, inside
const scrollbar = new Slider({
min:0,
max:pageH-viewerH,
step:0,
button:button,
barLength:viewerH,
barWidth:scrollW,
barColor:grey,
vertical:true,
keyArrows:false,
inside:true,
currentValue:pageH-viewerH
})
.addTo()
.pos(page.x + viewerW, page.y);
// 4. capture the change event and scroll the page to the right location
scrollbar.on("change", function() {
page.y = mask.y + scrollbar.currentValue - scrollbar.max;
// S.update(); // would normally just update stage here - but we have a Ticker doing this for damping below
});
//////////////// SECOND EXAMPLE //////////////////////////
viewerW = 300;
viewerH = 300;
scrollW = 25;
const mask2 = new Rectangle(viewerW,viewerH)
.addTo()
.pos(600, 200);
pageH = viewerH*4; // make a longer page this time
const page2 = new Container()
.addTo()
.pos(mask2.x, mask2.y);
const back2 = new Rectangle(viewerW, pageH, lighter)
.addTo(page2);
const s = back2.height/(4);
let c;
for (let i=0; i<4; i++) {
c = F.makeCircles(viewerW/2*.8)
.loc(viewerW/2, s/2 + s*i, page2);
}
page2.setMask(mask2);
// width, height, label, color, rollColor, borderColor, borderWidth, corner, shadowColor, shadowBlur, hitPadding
const button2 = new Button({
width:scrollW,
height:viewerH/pageH*viewerH, // note the proportion of viewable height / total height (then * viewable height)
label:"",
backgroundColor:silver,
rollBackgroundColor:tin,
corner:scrollW*.5
}).expand(); // helps on mobile
// min, max, step, button, barLength, barWidth, barColor, vertical, useTicks, inside
const scrollbar2 = new Slider({
min:0,
max:pageH-viewerH,
step:0,
button:button2,
barLength:viewerH,
barWidth:scrollW,
barColor:light,
vertical:true,
inside:true,
currentValue:pageH-viewerH
})
.addTo()
.pos(page2.x + viewerW, page2.y);
let desiredY = page2.y;
const damp = new Damp(desiredY, .1);
scrollbar2.on("change", doScroll2);
function doScroll2() {
desiredY = mask2.y + scrollbar2.currentValue - scrollbar2.max;
};
Ticker.add(function() {
page2.y = damp.convert(desiredY);
});
// EXTRA
// ALL THIS GOES AWAY WHEN USING ZIM Window() and ZIM List()
// can set the scrollbar position like so:
// scrollbar2.currentValue = -200;
// desiredY = mask2.y + scrollbar2.currentValue;
// damp.immediate(desiredY);
// doScroll2();
// below we will use the keyboard commands for the second scroll
// you could use them for either by adding your own focus variable for the last scrolled
// see the https://zimjs.com/tabs.html example for the technique
//////////////// KEYBOARD //////////////////////////
F.on("keydown", function(e) {
const arrowAmount = 20;
const pageAmount = viewerH*.95;
if (e.keyCode == 38) { // up
scrollbar2.currentValue += arrowAmount;
} else if (e.keyCode == 40) { // down
scrollbar2.currentValue -= arrowAmount;
} else if (e.keyCode == 33) { // page up
scrollbar2.currentValue += pageAmount;
} else if (e.keyCode == 34) { // page down
scrollbar2.currentValue -= pageAmount;
}
desiredY = mask2.y + scrollbar2.currentValue;
doScroll2();
});
//////////////// SCROLLWHEEL //////////////////////////
window.removeEventListener("wheel", F.zil[1]);
window.removeEventListener("DOMMouseScroll", F.zil[2]);
function displaywheel(e){
const wheelAmount = 40;
const evt=window.event || e;
//check for detail first so Opera uses that instead of wheelDelta
const delta=evt.detail? evt.detail*(-120) : evt.wheelDelta;
//delta returns +120 when wheel is scrolled up, -120 when down
if (delta > 0) {
scrollbar2.currentValue += wheelAmount;
} else {
scrollbar2.currentValue -= wheelAmount;
}
desiredY = mask2.y + scrollbar2.currentValue;
doScroll2();
}
//FF doesn't recognize mousewheel as of FF3.x
const mousewheelevt=(/Firefox/i.test(navigator.userAgent))? "DOMMouseScroll" : "mousewheel"
if (document.attachEvent) { //if IE (and Opera depending on user setting)
document.attachEvent("on"+mousewheelevt, displaywheel);
} else if (document.addEventListener) { //WC3 browsers
document.addEventListener(mousewheelevt, displaywheel, false);
}
// EXTRA EXTRA
// could add buttons on top and bottom that do what the arrows are doing
const title = "Scrollbar with Slider Component";
new Label(title, 30, null, "#666")
.pos(40, 40);
const docItems = "Frame,Container,Rectangle,Label,Button,Window,List,Slider,pos,addTo,centerReg,expand,setMask,Damp,zog,OPTIMIZE,Ticker";
makeFooter(S, W, H, null, docItems); // ZIM BITS footer - you will not need this
} // end of ready
</script>
<meta name="viewport" content="width=device-width, user-scalable=no" />
</head>
<body>
<!-- canvas with id="myCanvas" is made by zim Frame -->
</body>
</html>