• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Help with Javascript, dragging an object

New Here ,
Sep 06, 2020 Sep 06, 2020

Copy link to clipboard

Copied

So I Found a few example of what I want but I have questions. 

 

Links I'm looking at: 

https://www.createjs.com/tutorials/Mouse%20Interaction/

https://community.adobe.com/t5/animate/how-do-you-make-a-draggable-object-in-html5-canvas/td-p/11293...

 

Now both of those look to offer what I want to do at the basic level.

 

I have some nested movieclips. A measurment guage face with a needle pointing, the needle is a separate symbol inside the face movie clip.  When I move the face down I want to the needle to rotate. 

 

So far I'm on the moving down part... 

 

I only want to be able to click and drap on the y axis.  so someone clicking and moving can only move the face up and down.  I want to have a maximum and minimum dragability. 

 

The second link has this code:

 

var root = this;
var rec = root.rec;

createjs.Touch.enable(stage);

rec.on("mousedown", function(e)
{
	e.currentTarget.offsetX = stage.mouseX / stage.scaleX - e.currentTarget.x;
	e.currentTarget.offsetY = stage.mouseY / stage.scaleY - e.currentTarget.y;
});

rec.on("pressmove", function(e)
{
	e.currentTarget.x = stage.mouseX / stage.scaleX - e.currentTarget.offsetX;
	e.currentTarget.y = stage.mouseY / stage.scaleY - e.currentTarget.offsetY;
});

 

I'm trying to understand the code here.  why doesn't it just go var rec = this.rec;?  instead of the two var lines at the top?  And how to I get the ID of the object I want to move?  I don't really know where to find the name of my object is it the instance name? 

 

If I remove the lines with X will it just work on Y?  How to I set a max up and a max down?

 

The first link has this code:

 

circle.on("pressmove", function(evt) {
    evt.target.x = evt.stageX;
    evt.target.y = evt.stageY;
});
circle.on("pressup", function(evt) { console.log("up"); })

 

This is considerably less text.  But I have similar questions.  how to get the name of my object I want to use.  If I just remove the lines with X will it just work with Y?  How to add a max height and minimum? 

 

Also where do I put this code?  on the main timeline or in the movie clip somewhere? 

 

Then, Is it possible to use the distance dragged to control the rotation of a nested symbol?

 

I know that's a lot but I am pretty lost here and want to know how to get this to work.  I'm new to code and haven't used animate since...  Flash CS6.

TOPICS
Code

Views

634

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Sep 06, 2020 Sep 06, 2020

Copy link to clipboard

Copied

The first link is web and HTML5 only isn't it?  would it work in animate?  I saw it in the links that pop up when I type the title of my question. 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Sep 06, 2020 Sep 06, 2020

Copy link to clipboard

Copied

Ok, so this code works to drag the dial on the Y. 

 

 

this.top.on("mousedown", function(e)
{
	e.currentTarget.offsetY = stage.mouseY / stage.scaleY - e.currentTarget.y;
});

this.top.on("pressmove", function(e)
{
	e.currentTarget.y = stage.mouseY / stage.scaleY - e.currentTarget.offsetY;
});

 

 

Apparently I didn't need the other stuff which wasn't working in my scene. 

 

SO now how would I make a min and max distance it can travel? the position relative to the stage, I want it to go no higher than 220 on Y and no lower than 330

 

Then how would I connect the drag event to a rotation?  Like when I drag the object down I want a symbol nested inside to rotate. 

 

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 07, 2020 Sep 07, 2020

Copy link to clipboard

Copied

Hi.

 

A well structured, efficient, maintainable, and scalable code isn't necessarily small.

 

The variables at the top, in the second link, are used for clarity and also because it's a good practice to store properties and/or nested objects in variables for easier access.

 

Also imagine that you want to change the name of your rec instance on the stage. If your instance is being referenced in multiple places in your code, it will be much easier to maintain your code if you store a reference for your instance in a single variable.

 

Plus, as we writing a program in JavaScript, having objects stores in variables you'll prevent a lot of headaches when dealing with context.

 

And notice as well that this line...

createjs.Touch.enable(stage);

... is important if you want your content to function properly on mobile devices.

 

Here is a suggestion - meaning you can change it or agree with it as much as you want - that maybe will be what you want:

var root = this;
var rec = root.rec;
var circle = root.circle;

root.start = function()
{
	createjs.Touch.enable(stage);
	stage.mouseMoveOutside = true;
	
	rec.on("mousedown", root.mouseDownHandler);
	rec.on("pressmove", root.pressMoveHandler, this, false, { min: 220, max: 330 });
	
	circle.on("mousedown", root.mouseDownHandler);
	circle.on("pressmove", root.pressMoveHandler, this, false, { min: 0, max: 500 });
};

root.mouseDownHandler = function(e)
{
	e.currentTarget.offsetY = stage.mouseY / stage.scaleY - e.currentTarget.y;
};

root.pressMoveHandler = function(e, data)
{
	e.currentTarget.y = root.clamp(stage.mouseY / stage.scaleY - e.currentTarget.offsetY, data.min, data.max);
};

root.clamp = function(value, min, max)
{
	if (value < min)
		return min;
	
	if (value > max)
		return max;
	
	return value;
};

root.start();

 

I added this line...

stage.mouseMoveOutside = true;

... to support dragging events if the mouse cursor leaves the canvas and I also added a few lines for a circle instance so you can better understand the advantages of trading lines amount for better maintenance and scalability.

 

Also, I solved the drag limitation by creating a custom clamp method. About the rotation feature, I didn't quite understand exactly what you want to achieve. Can you elaborate more?

 

I hope this helps.

 

Regards,

JC

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Sep 07, 2020 Sep 07, 2020

Copy link to clipboard

Copied

Basically I want a it to do this.  But someone can click on the main dial portion and drag it down and up and when it's being dragged the needles spin between 0 and 360.  Your code worked great for dragging on Y and limiting how high and low it can go. 

dialAnim.gif

 

This question has a sample bit of code that kind of works:

https://community.adobe.com/t5/animate/rotating-a-movieclip-with-javascript-pressmove-method/m-p/935...

but the issue with it is that its not constrained to the drag.  dragging or clicking rotates the needle and I don't really understand what it's doing...  I tried to figure it out by playing with it and trying to comment outcertain bits and see if I can see/understand what is happening.  But I'm so lost... 

It also looks like your code can cover some of this already, like the mouse down and mousemove sections.  so some of it seems redundant.


I need to learn to code...  😞

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Sep 07, 2020 Sep 07, 2020

Copy link to clipboard

Copied

dumb reply

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 08, 2020 Sep 08, 2020

Copy link to clipboard

Copied

Hi again.

 

var root = this;
var rec = root.rec;
var circle = root.circle;

root.start = function()
{
	createjs.Touch.enable(stage);
	stage.mouseMoveOutside = true;

	rec.on("mousedown", root.mouseDownHandler);
	rec.on("pressmove", root.pressMoveHandler, this, false, { min: 220, max: 330, rotationTarget: rec.arrow });
	
	circle.on("mousedown", root.mouseDownHandler);
	circle.on("pressmove", root.pressMoveHandler, this, false, { min: 50, max: 350, rotationTarget: circle.arrow });
};

root.mouseDownHandler = function(e)
{
	e.currentTarget.offsetY = stage.mouseY / stage.scaleY - e.currentTarget.y;
};

root.pressMoveHandler = function(e, data)
{
	var ratio;
	
	e.currentTarget.y = root.clamp(stage.mouseY / stage.scaleY - e.currentTarget.offsetY, data.min, data.max);
	ratio = (e.currentTarget.y - data.min) / (data.max - data.min);
	data.rotationTarget.rotation = 360 * ratio;
};

root.clamp = function(value, min, max)
{
	if (value < min)
		return min;
	
	if (value > max)
		return max;
	
	return value;
};

root.start();

 

The idea is to calculate a ratio from 0 to 1 representing how much the instance has been dragged in the range that starts in the min position and ends in the max position. So if the instance is in the min position the ratio = 0, if the instance is in the middle the ratio = 0.5, if it is in the max position the ratio = 1, and so on.

 

Then we multiply this ratio by 360 which is the full rotation of an instance.

 

And please notice that when working with rotation in JavaScript, your symbol artwork should be pointing to the right.

 

File / Sample / FLA:

https://drive.google.com/file/d/1en9qIjGkves9xxOHydZqomMBY70Z6_gg/view?usp=sharing

 

Regards,

JC

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Apr 06, 2021 Apr 06, 2021

Copy link to clipboard

Copied

JC,

 

Your tips and code really helped me with my project. I'm a beginner in Animate and new to Javascript. But I was able to adapt your code to build a slider with a limited X range.

 

Question:

How would you code the slider to reveal different objects or different labeled frames depending on where the user drags the slider: to left, middle, or right? The dimensions of the stage inside the movie clip containing the slider is –175 to 175.

 

I'd like to use the slider to toggle back and forth between views of a graph showing traditional, both, and robotic sampling methods (for a marine research institute).

 

Initially I tried to add invisible buttons behind the silder to react to mouseover but there must be a better way!

 

Thanks,

 

Fiona

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 07, 2021 Apr 07, 2021

Copy link to clipboard

Copied

LATEST

Hi, Fiona!

 

Good to know that the code and the tips helped you!

 

Here is another sample.

 

This time I opted for an object oriented approach so it's easier to utilize the slider in different places.

 

The actual code for the slider is in the global script and a suggestion of how to control the an animation using two sliders is in the first frame of the main timeline.

 

To use the slider, you have to create an instance of it, pass the button and bar instances you want as the graphics for the slider and then you can customize the look and behavior of the slider using callbacks.

 

Try it:

https://bit.ly/39U13fF

 

Preview:

adobe_animate_html5_canvas_labels_slider.gif

 

JS / JavaScript code:

 

Global script:

function setup()
{
exportRoot.Slider = function(button, bar, props)
{
if (!props)
props = {};

this.button = button;
this.bar = bar;
this.minX = props.minX || 0;
this.maxX = props.maxX || this.bar.nominalBounds.width;
this.callBacks = {};
this.button.mouseEnabled = false;
this.setRatio();
this.bar.on("mousedown", this.mouseDownHandler, this);
this.bar.parent.on("rollover", this.rollOverHandler, this);
this.bar.parent.on("rollout", this.rollOutHandler, this);
};

exportRoot.Slider.prototype.mouseDownHandler = function(e)
{
var bounds = this.button.nominalBounds;

this.point = this.getPointerPosition(e.currentTarget.parent);
this.offsetX = this.point.x >= this.button.x - bounds.width * 0.5 && this.point.x <= this.button.x + bounds.width * 0.5 ? this.point.x - this.button.x : 0;
this.pressed = true;
this.positionPointerFromPointer();
this.pressMove = this.bar.on("pressmove", this.pressMoveHandler, this);
this.pressUp = this.bar.parent.on("pressup", this.pressUpHandler, this);

if (this.callBacks.mouseDownHandler)
this.callBacks.mouseDownHandler(e, this);
};

exportRoot.Slider.prototype.rollOverHandler = function(e)
{
if (this.callBacks.rollOverHandler)
this.callBacks.rollOverHandler(e, this);
};

exportRoot.Slider.prototype.rollOutHandler = function(e)
{
if (this.callBacks.rollOutHandler)
this.callBacks.rollOutHandler(e, this);
};

exportRoot.Slider.prototype.pressMoveHandler = function(e)
{
this.positionPointerFromPointer();

if (this.callBacks.pressMoveHandler)
this.callBacks.pressMoveHandler(e, this);
};

exportRoot.Slider.prototype.pressUpHandler = function(e)
{
this.pressed = false;
this.bar.on("pressmove", this.pressMove);
this.bar.parent.on("pressup", this.pressUp);

if (this.callBacks.pressUpHandler)
this.callBacks.pressUpHandler(e, this);
};

exportRoot.Slider.prototype.getPointerPosition = function(target)
{
return target.globalToLocal(stage.mouseX, stage.mouseY);
};

exportRoot.Slider.prototype.positionPointerFromPointer = function()
{
this.point = this.getPointerPosition(this.bar.parent);
this.button.x = this.clamp(this.point.x - this.offsetX, this.minX, this.maxX);
this.setRatio();
};

exportRoot.Slider.prototype.positionPointerFromRatio = function(ratio)
{
this.button.x = this.minX + (this.maxX - this.minX) * (ratio || this.ratio);
this.setRatio();
};

exportRoot.Slider.prototype.setRatio = function()
{
this.ratio = this.button.x / (this.maxX - this.minX);
};

exportRoot.Slider.prototype.clamp = function(value, min, max)
{
if (value < min)
return min;

if (value > max)
return max;

return value;
};
};

 

Main timeline script:

var root = this;
var targetAnim = root.anim;
var labels, slider, slider1;

root.main = function()
{
setup();
document.body.style.backgroundColor = lib.properties.color;
createjs.Touch.enable(stage);
stage.mouseMoveOutside = true;
root.stop();
labels = targetAnim.labels.map(function(label){ return label.label; });
slider = new root.Slider(root.slider0.button, root.slider0.bar);
slider1 = new root.Slider(root.slider1.button, root.slider1.bar);

slider.callBacks.mouseDownHandler = function(e, target)
{
target.button.gotoAndStop(2);
root.update(target, slider1);
};

slider1.callBacks.mouseDownHandler = function(e, target)
{
target.button.gotoAndStop(2);
root.update(target, slider);
};

slider.callBacks.rollOverHandler = slider1.callBacks.rollOverHandler = function(e, target)
{
if (!target.pressed)
target.button.gotoAndStop(1);
};

slider.callBacks.rollOutHandler = slider1.callBacks.rollOutHandler = function(e, target)
{
if (!target.pressed)
target.button.gotoAndStop(0);
};

slider.callBacks.pressMoveHandler = function(e, target)
{
root.update(target, slider1);
};

slider1.callBacks.pressMoveHandler = function(e, target)
{
root.update(target, slider);
};

slider.callBacks.pressUpHandler = slider1.callBacks.pressUpHandler = function(e, target)
{
target.button.gotoAndStop(1);
};

root.update(slider, slider1);
};

root.update = function(current, other)
{
targetAnim.gotoAndStop(labels[Math.floor(current.ratio * labels.length)]);
other.positionPointerFromRatio(current.ratio);
root.ratioText0.text = "RATIO: " + slider.ratio.toFixed(2);
root.ratioText1.text = "RATIO: " + slider1.ratio.toFixed(2);
};

if (!root.started)
{
root.main();
root.started = true;
}

 

Files / source / download / FLA:

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

 

Please let us know if you have any further questions and I wish you a great learning adventure!

 

Regards,

JC

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines