<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<img class="absPos img1 hidden" src="https://d4n5pyzr6ibrc.cloudfront.net/media/27FB7F0C-9885-42A6-9E0C19C35242B5AC/4785B1C2-8734-405D-96DC23A6A32F256B/thul-90efb785-97af-5e51-94cf-503fc81b6940.jpg?response-content-disposition=inline"></img>
<img class="absPos img2 " src="https://www.petalatino.com/wp-content/uploads/lil-bub-rotator.jpg"></img>
<canvas id="myCanvas" class="absPos" width="320px" height="180px"></canvas>
</body>
</html>
var img1 = document.querySelector('.img1');
var img2 = document.querySelector('.img2');
var canvas = document.querySelector('#myCanvas');
var context = canvas.getContext('2d');
var canvas_w = canvas.width; // 320px
var canvas_h = canvas.height; // 180px
// to do: map() maximumradius to rgb color
// i: apply opacity mask circle after it being clipped
// to tansition between colors ( & later between pixel colors )
// also adjust lineWidth & opacity mask as transparent-filled-transparent
var circleObj = {center_x: 160, center_y: 90};
var updateCanvas = function(){
context.save();
context.clearRect(0, 0, canvas_w, canvas_h); // clear canvas
//context.strokeStyle = "rgba(90, 90, 90, 0.1)";
//context.fillStyle = "transparent";
//context.lineWidth = 3; // "5" also seems to work ;)
//context.strokeRect(10, 10, 300, 160); // works fine
context.beginPath();
// hacky way to control the strokeWidth or our arc ;)
// bonus: added no visible outer edges ;p
// R: could allow further blending modding the inner/outer <n> "edgy" circles
// ex: by map()-ing maxI/2 to [0..1] rgbA [ & act only on n inner ||/ outer ]
// Don't forget to add the call to 'stroke' or it 'll draw weird lines
/*
for(var i=0; i<= 10; i++){
if(i == 0 || i == 10) context.strokeStyle = "transparent";
else context.strokeStyle = "rgba(0, 0, 0, 1)"; // only care 'bout a
context.arc(circleObj.center_x, circleObj.center_y, 50+i, 0, 2*Math.PI);
context.stroke();
}
*/
// same as above via helper fcn
//strokedArc(circleObj.center_x, circleObj.center_y, 50+i, 0, 2*Math.PI, false, 5);
//drawHardcodedCircle(); // works
drawHardcodedCircle2(50, 30); // innerRadius, strokeWidth
//context.strokeStyle = "rgba(0, 0, 0, 1)";
//context.arc(circleObj.center_x, circleObj.center_y, 50, 0, 2*Math.PI, false);
//context.arc(circleObj.center_x, circleObj.center_y, 51, 0, 2*Math.PI, false);
//context.arc(circleObj.center_x, circleObj.center_y, 52, 0, 2*Math.PI, false);
//context.stroke();
//context.fill();
context.clip();
// drawing anything 'll get it constrained to the above circle stroke
context.globalCompositeOperation="source-in";
context.drawImage(img1, 0, 0);
context.restore();
}
// helper fcn to draw arcs with a "strokeWidth"
/*
var strokedArc = function(x0, y0, r, from, to, ccw, strokeWidth){
var cntr = 0;
for(cntr; cntr<= 10; cntr++){
if(cntr == 0 || cntr == 10) context.strokeStyle = "transparent";
else context.strokeStyle = "rgba(0, 0, 0, 1)"; // only care 'bout a
context.arc(x0, y0, r+cntr, from, to);
context.stroke();
}
};
*/
var drawHardcodedCircle2 = function(radius, strokeWidth){
for(var i=0; i<= strokeWidth+2; i++){
if(i === 0 || i === 10) context.strokeStyle = "transparent";
else context.strokeStyle = "rgba(0, 0, 0, 1)"; // only care 'bout a
context.arc(circleObj.center_x, circleObj.center_y, radius+i, 0, 2*Math.PI);
context.stroke();
}
}
var drawHardcodedCircle = function(){
//function drawHardcodedCircle(){
for(var i=0; i<= 10; i++){
if(i === 0 || i === 10) context.strokeStyle = "transparent";
else context.strokeStyle = "rgba(0, 0, 0, 1)"; // only care 'bout a
context.arc(circleObj.center_x, circleObj.center_y, 50+i, 0, 2*Math.PI);
context.stroke();
}
}
// R:
// 1: handle mvmt => done ( using mouse ) ;)
// 2: handle pressure
/*
// for non-compatible devices, use slider to in/decrease grd_r1
var depthController = document.querySelector('#depthController');
var depthController2 = document.querySelector('#depthController2');
depthController.addEventListener('input', function(e){ // on move thumb
console.log(this.value);
grdProps.grd_r0 = this.value; // we could map() if necessary ( .. )
updateCanvas(); // refresh the stuff
});
depthController2.addEventListener('input', function(e){ // on move thumb
console.log(this.value);
grdProps.grd_r1 = this.value; // we could map() if necessary ( .. )
updateCanvas(); // refresh the stuff
});
*/
// 3: replace with timelapse imgs/video(s)
// 4: ..
/* debug move the focus using mouse moves */
var startPos = null;
var mouseIsDown = false;
canvas.onmousedown = function(e){
console.log('mousedown evt !')
startPos = { x: e.clientX, y: e.clientY };
mouseIsDown = true;
}
canvas.onmousemove = function(e){
if( mouseIsDown == true ){
evt = e;
console.log('mouse move !');
var currPos = { x: e.clientX, y: e.clientY };
var diffX = startPos.x - currPos.x;
var diffY = startPos.y - currPos.y;
// re: the following is drawn by the fcn mixing stuff on the canvas
//grdProps = { grd_x0: 160, grd_y0: 80, grd_r0: 0, grd_x1: 160, grd_y1: 80, grd_r1: 50, }
//grdProps.grd_x0 -= diffX;
//grdProps.grd_x1 -= diffX;
//grdProps.grd_y0 -= diffY;
//grdProps.grd_y1 -= diffY;
circleObj.center_x -= diffX;
circleObj.center_y -= diffY;
//grdProps.grd_r1 += // pressure/depth relative
updateCanvas(); // refresh the stuff
startPos = { x: e.clientX, y: e.clientY }; // to NOT have increasing mvmts
}
}
canvas.onmouseup = function(e){
startPos = null;
mouseIsDown = false;
}
updateCanvas(); // refresh the stuff once on start, to display initial stuff
Output
You can jump to the latest bin by adding /latest
to your URL
Keyboard Shortcuts
Shortcut | Action |
---|---|
ctrl + [num] | Toggle nth panel |
ctrl + 0 | Close focused panel |
ctrl + enter | Re-render output. If console visible: run JS in console |
Ctrl + l | Clear the console |
ctrl + / | Toggle comment on selected lines |
ctrl + ] | Indents selected lines |
ctrl + [ | Unindents selected lines |
tab | Code complete & Emmet expand |
ctrl + shift + L | Beautify code in active panel |
ctrl + s | Save & lock current Bin from further changes |
ctrl + shift + s | Open the share options |
ctrl + y | Archive Bin |
Complete list of JS Bin shortcuts |
JS Bin URLs
URL | Action |
---|---|
/ | Show the full rendered output. This content will update in real time as it's updated from the /edit url. |
/edit | Edit the current bin |
/watch | Follow a Code Casting session |
/embed | Create an embeddable version of the bin |
/latest | Load the very latest bin (/latest goes in place of the revision) |
/[username]/last | View the last edited bin for this user |
/[username]/last/edit | Edit the last edited bin for this user |
/[username]/last/watch | Follow the Code Casting session for the latest bin for this user |
/quiet | Remove analytics and edit button from rendered output |
.js | Load only the JavaScript for a bin |
.css | Load only the CSS for a bin |
Except for username prefixed urls, the url may start with http://jsbin.com/abc and the url fragments can be added to the url to view it differently. |