ZIM BITS TUTORIAL
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>ZIM BITS - Drawing Lines with Blitting</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 - Drawing Lines with Blitting (2016 - updated 2022)
// SEE ZIM Pen() - https://zimjs.com/docs?item=pen for an update on all this!
// lines are made up of many little lines made on a mousemove event or in a Ticker event, etc.
// (really, this should be on a Ticker so the damping works even if the mouse is not moving)
// we use damping to smoothen out the line
// we can use curveTo or lineTo to accomplish this - see the CreateJS curveTo example on GitHub
// it is more efficient to use blitting to reduce the number of vectors the computer needs to keep track of
// blitting is when you draw your vector Shape to a Bitmap - or here we are caching our Shape and using that
// there are many artistic things that we can do with lines
// we can change their color, thickness, segments
// we can make lines out of shapes or add crazy patterns as we go
// the world of dynamic drawing or making art with code is fantastic!
// we experiment a bit in this example
// the notes tell you how you can adjust the example back to just a plain line if that is what you need!
// STEPS
// 1. make a shape to draw in and add it to the stage
// 2. cache the shape (with optional off stage padding)
// 3. create the Bitmap that will display our cached content and add it to the stage
// 4. prepare ZIM Damp objects to handle damping in x and y
// 5. turn on mouseMoveOutside to capture movement outside the stage
// 6. create a stagemousedown event and set initial mouse x and y positions
// 7. create a stagemousemove event to draw the line
// 8. set the new x and y to the coverted damped rawX and rawY mouse position
// 9. draw the line from the old position to the new position (clearing shape graphic each time!)
// 10. cache the drawing using the source-over blend mode so it adds to what was there before
// 11. set a stagemouseup event to remove the stagemousemove event
// we make a function to set up our drawing
// because we have to do it every time we mousedown
// this is optional - we could have just had one drawing for all time
// and perhaps added a clear button, etc.
// but in this case, we are letting the user draw a new shape each time and we fade out the old one
// set up the drawing and blit variables that we need for other functions too
let drawing;
let blit;
function setDrawing() {
// 1. make a shape to draw in and add it to the stage
drawing = new Shape().addTo()
// 2. cache the shape (with optional off stage padding)
// we are setting up our drawing to allow off stage control
// so when we fade out and shrink our old drawing we will see off stage
// set the cache size to handle this on all sides (note *3 not *2 which would not be big enough)
if (mobile() == "ios") { // iOS has issues with canvas bigger than screen size
drawing.cache(W, H);
} else {
drawing.cache(-W, -H, W*3, H*3);
}
// 3. create the Bitmap that will display our cached content and add it to the stage
// we point the Bitmap to the drawn image
blit = new Bitmap(drawing.cacheCanvas).addTo();
}
setDrawing();
// 4. prepare ZIM Damp objects to handle damping in x and y
// lines look much smoother when we apply damping to even out our mouse movement
const dampX = new Damp();
const dampY = new Damp();
// 5. turn on mouseMoveOutside to capture movement outside the stage
// when we are drawing expressive lines as in this example
// we want to capture our movement outside the stage
// this needs to be turned on for CreateJS
// then inside the mousemove event we will use the rawX and rawY instead of stageX and stageY
S.mouseMoveOutside = true;
// EXTRA
// fat makes the line thicker the faster you move your mouse
// try .3 for a thin line with some adjustment for mouse move
// try 1 for a nice thick line - works well with colors active
// dashed sets how far apart the rectangles that make the line will be
// try -.1 for a smooth line
// try .1 for segmented or go crazy with .6, etc.
// colors is just a fun experiment
// you can override this in the move event by setting a specific color to see what a traditional line would be like
const fat = 1.5;
const dashed = .1;
const colors = [pink, green, yellow, brown, blue, orange, silver];
let currentColor = 0;
// the moveEvent will be removed outside this function so declare it in this scope
let moveEvent;
// 6. create a stagemousedown event and set initial mouse x and y positions
S.on("stagemousedown", function() {
// the drawing is made up of a bunch of shorter lines
// lastX and lastY are used as the starting position for each line we draw
let lastX = F.mouseX;
let lastY = F.mouseY;
// we want to start our damping from the mousedown position
// not damp from 0 to the mousedown position
// so we use the immediate() method of the Damp object
dampX.immediate(lastX);
dampY.immediate(lastY);
// EXTRA
// we will make the last line drawn shrink and fade out
// to do this we copy the current blit Bitmap and animate that
// but then we need to clear the blit Bitmap by reseting the cache and creating the drawing objects again
const old = blit.clone()
.centerReg() // center registration point for scaling effect (centerReg also does adds the first parameter to the second parameter)
.animate({alpha:0, scale:.7}, 4, null, function(tweenTarget){S.removeChild(tweenTarget);});
resetDrawing(); // clear the current cache and reset the drawing objects
// 7. create a stagemousemove event to draw the line
moveEvent = S.on("stagemousemove", function(e) {
// EXTRA
// here we are cycling through the colors to make the colorful effect!
// the ++ adds one each time
// the % is the modulus and just takes the remainder so we never go larger than the color array's length!
// we could have drawn several lines at the same time with slightly different easing Damp(null, .08), Damp(null, .06), etc.
// this would have made the streamers curve at different rates - would be cool!
const color = colors[++currentColor%colors.length];
// const color = blue; // or just choose a single color for a traditional line (and read about the fat and dashed settings above)
// 8. set the new x and y to the coverted damped rawX and rawY mouse position
const newX = dampX.convert(e.rawX);
const newY = dampY.convert(e.rawY);
// EXTRA
// adjusting the thickness to relate to the speed of the mouse
const thickness = Math.max(1, (Math.abs(lastX-newX) + Math.abs(lastY-newY)) * fat);
// 9. draw the line from the old position to the new position (clearing shape graphic each time!)
// this means that we only have one vector line at any given time to give us optimum performance
// you can use clear(), setStrokeStyle(), setStroke(), moveTo() and lineTo() as well
drawing.graphics.c().ss(thickness).s(color).mt(lastX, lastY).lt(newX, newY);
// EXTRA
// adjust the lastX and lastY depending on a dashed value
// otherwise this would just be lastX = newX, lastY = newY
lastX = newX-(lastX-newX) * dashed;
lastY = newY-(lastY-newY) * dashed;
// 10. cache the drawing using the source-over blend mode so it adds to what was there before
drawing.updateCache("source-over");
S.update();
});
});
// 11. set a stagemouseup event to remove the stagemousemove event
S.on("stagemouseup", function() {
S.off("stagemousemove", moveEvent);
});
// EXTRA
// code to reset the blitting on mousedown
function resetDrawing() {
drawing.uncache();
drawing.removeFrom();
blit.removeFrom();
setDrawing();
}
const title = "Drawing Lines with Blitting (use mouse or finger)";
new Label(title, 30, null, "#666")
.pos(40, 40);
const docItems = "Frame,Shape,Bitmap,Label,animate,pos,addTo,removeFrom,centerReg,Damp,zog,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>