Skip to main content
July 28, 2020
Question

Ease and Orient Custom Mouse Cursor

  • July 28, 2020
  • 2 replies
  • 306 views

Hi! I am creating an interactive HTML Animate story for the web. I have this worm png that I want to follow my cursor around the stage. I would ideally like it to ease with the cursor and orient itself, with the head following the cursor. 

 

I have found some examples using JS but I have NO IDEA how to transfer the JS code into animate. As in I'm not familiar with references elements on the stage in animate.

 

Any help would be much appreciated. 

This topic has been closed for replies.

2 replies

JoãoCésar17023019
Community Expert
Community Expert
July 29, 2020

Hi.

 

Thanks for the private message.

 

If I understood correctly, you are looking for a scratch interactivity. Alternatively to kglad’s answer, I have a sample here.

 

Preview:

 

Play:

https://bit.ly/2X6xHV1

 

JS code:

 

var root = this;
var minProgressToReveal = 0.9; // minimum mask area that needs to be cleared to reveal what is behind
var cursorType = "default";
var strokeTickness = 48;
var strokeCaps = "round";
var strokeJoints = "round";
var strokeColor = "rgba(0,0,0,1)"; // change the 4th argument for the stroke density
var mkContainer = root.scratchable; // mask container instance
var cursor = root.cursor; // cursor instance
var friction = 0.8; // cursor friction
var scratchable, mkBounds, grid, isDrawing, oldPt, oldMidPt, maskFilter;

root.start = function()
{
	createjs.Touch.enable(stage);
	stage.enableMouseOver();
	stage.mouseMoveOutside = true;
	document.body.style.backgroundColor = "black";
	grid = {};
	scratchable = mkContainer.children[0];
	mkBounds = root.scratchable.nominalBounds;
	scratchable.cache(-mkBounds.width * 0.5, -mkBounds.height * 0.5, mkBounds.width, mkBounds.height);
	maskFilter = new createjs.AlphaMaskFilter(scratchable.cacheCanvas);
	scratchable.cursor = cursorType;
	root.stop();
	root.mouseDown = stage.on("stagemousedown", root.mouseDownHandler);
	root.mouseUp = stage.on("stagemouseup", root.mouseUpHandler);
	root.tick = createjs.Ticker.on("tick", root.tickHandler);
}

root.mouseDownHandler = function(event)
{
	var stageX = ((stage.mouseX / stage.scaleX) - mkBounds.width * 0.5);
	var stageY = ((stage.mouseY / stage.scaleY) - mkBounds.height * 0.5);
	
	oldPt = new createjs.Point(stageX, stageY);
	oldMidPt = oldPt;
	isDrawing = true;
}

root.tickHandler = function(event)
{
	var stageX = stage.mouseX / stage.scaleX;
	var stageY = stage.mouseY / stage.scaleY;
	
	cursor.rotation = root.rotateToCursor(stageY - cursor.y, stageX - cursor.x);
	cursor.x = root.lerp(cursor.x, stageX, friction);
	cursor.y = root.lerp(cursor.y, stageY, friction);
	
	if (!isDrawing)
		return;
	
	var midPoint;
	
	stageX -= mkBounds.width * 0.5;
	stageY -= mkBounds.height * 0.5;	
	midPoint = new createjs.Point(oldPt.x + stageX >> 1, oldPt.y + stageY >> 1);
	root.trackProgress(midPoint);

	scratchable.graphics.clear()
		.setStrokeStyle(strokeTickness, strokeCaps, strokeJoints)
		.beginStroke(strokeColor)
		.moveTo(midPoint.x, midPoint.y)
		.curveTo(oldPt.x, oldPt.y, oldMidPt.x, oldMidPt.y);
	
	oldPt.x = stageX;
	oldPt.y = stageY;

	oldMidPt.x = midPoint.x;
	oldMidPt.y = midPoint.y;

	scratchable.updateCache("destination-out");
}

root.mouseUpHandler = function(event)
{
	isDrawing = false;
}

root.trackProgress = function(point)
{
	var columns = Math.round(mkBounds.width / strokeTickness) + 1;
	var rows = Math.round(mkBounds.height / strokeTickness) + 1;
	var total = columns * rows;
	var gridX = Math.round((point.x + mkBounds.width * 0.5) / strokeTickness);
	var gridY = Math.round((point.y + mkBounds.height * 0.5) / strokeTickness);
	
	grid[gridX + "_" + gridY] = true;
	
	if (Object.keys(grid).length >= Math.round(total * minProgressToReveal))
		root.revealCallback();	
}

root.revealCallback = function()
{	
	createjs.Tween.get(scratchable).to({ alpha: 0 }, 500).call(function()
	{
		scratchable.visible = false;
	});
	
	createjs.Tween.get(cursor).to({ alpha: 0 }, 500).call(function()
	{
		cursor.visible = false;
	});	
	
	stage.off("stagemousedown", root.mouseDown);
	stage.off("stagemouseup", root.mouseUp);
	createjs.Ticker.off("tick", root.tick);
}

root.lerp = function(v1, v2, f)
{
	 return f * v1 + (1 - f) * v2;
};

root.rotateToCursor = function(distY, distX)
{
	return Math.atan2(distY, distX) * 180 / Math.PI;
};

root.start();

 

 

FLA / source / files:

https://github.com/joao-cesar/adobe/tree/master/animate%20cc/html5_canvas/scratch

 

I hope this helps.

 

Regards,

JC

kglad
Community Expert
Community Expert
July 28, 2020

you can pretty much just copy and paste js into the actions panel.  on stage objects are referenced by their instance name (in the properties panel) preceded by "this".  eg, to ease movieclip mc to the cursor when the mouse is down:

 

stage.addEventListener("stagemousedown", startEaseToMouseF.bind(this));
stage.addEventListener("stagemouseup", stopEaseToMouseF.bind(this));

var F = easeToMouseF.bind(this);
var speed = .1;

function startEaseToMouseF(e) {
createjs.Ticker.addEventListener("tick", F);
}
function stopEaseToMouseF() {
createjs.Ticker.removeEventListener("tick", F);
}

function easeToMouseF() {
this.mc.x = (1-speed)*this.mc.x +speed*stage.mouseX/stage.scaleX;
this.mc.y = (1-speed)*this.mc.y +speed*stage.mouseY/stage.scaleY;
}