Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Authoring API #88

Closed
bartaz opened this issue Feb 2, 2012 · 6 comments
Closed

Authoring API #88

bartaz opened this issue Feb 2, 2012 · 6 comments
Labels

Comments

@bartaz
Copy link
Member

bartaz commented Feb 2, 2012

Just to fork the discussion about API in #9 this issue is about providing additional 'extended' API with functions useful for authoring tools to build impress.js presentations.

For sure there is a need to manipulate the position of the 'camera' (transform of the canvas), ability to change the position, scale and rotation of steps, maybe dynamically adding steps, etc...

Please comment if you have any suggestions. Feedback from anyone already trying to build an authoring tools is more than welcome :)

@naugtur
Copy link

naugtur commented Feb 2, 2012

My proof of concept actually used a single method that I revealed from the impress.js internals. You can see details in my fork of impress.js or on naugtur.github.com

If you are not planning to include all authoring logic in impress, then I guess it's the most important method that needs to be in the API. The editor I started just changes the HTML attributes (like the user would) and triggers redrawing of the slide with your code. So the method would be .drawSlide(a) where a is a dom node or a collection of dom nodes.

Second method I would use in my editor would be .overviewMode(toggle) where toggle is true or false. Turning on the overview mode would make the camera show all the slides and turn off switching between slides.

That's all I would need to implement my authorng tool. I have already started it, but it was just to explore ideas and I need to find a long evening to get down to it.

@robinwyss
Copy link

I did something similar to naugtur.

I added a method to show an overview of the presentation (like the overview step in your demo presentation, but it is computed, this way it doesn't have to be adjusted if the presentation changes) and one which updates a step.

I used the mouse to select an element and the arrow keys to move it or, if the 'r' key is hold down, to rotate/scale it. I also used the html5 drag and drop to move the elements, but i had some problems with it (only small drags worked).

The methods i would add to the api are:
updateStep(step)
addStep(step)
removeStep(step)

  • the step argument could either be an id or an element.

showOverview()

  • zooms out to show all slides

Maybe a method to disable the eventlisteners, this way the arrow keys could be used to edit the elements and the mouse to select them.

It would also be nice to be able to change the order of the steps.

@SiegeWizard
Copy link

I would say that the showOverview() method should be a specific case of the setCamera() method, as next() and prev() are specific cases of the goto() method.
The setCamera method should have an argument:
position = {
rotate : {x,y,z},
translate : {x,y,z},
scale
}
If this method was applied, I think that the goto() method should use it internally not to have duplicated code.
The showOverview() would just compute the overview values and call this method.

About the addStep(), removeStep(), updateStep(): I don't think they should be included in an API. An API should help the plugin integration and I have to say that an slide-editor is not a plugin. Don`t get me wrong, I'm making an editor myself, but I don't consider it a plugin.

Other methods and functionality that may be useful are:

  • Video integration: Autoplay when entering its slide, pause when leaving, and pre-charge while in other steps after the rest of the steps have been charged.
  • Pointer events: Getting the position of the cursos may be interesting for some plugins, as well as dragging and all that kind of events.
  • Slide jumps: Let me try to explain this point. Sometimes when you are presenting something, you want the user to see the slides in this order:
    Slide 1 -> Slide 2 -> Slide 3 -> Slide 1 -> Slide 4 -> Slide 5 -> Slide 1 -> Slide 6
    The Slide 1 may be for example an index that you want to show to the viewers before any of the points. I suggest adding the funcionality to add empty divs with the data-step variable so that if it gets it instead of getting its dataset, it gets the dataset of the step whose id is the one in data-step. In my example it would be: (not using the < simbol so that it doesn`t remove the div tag)

div id="index" data-scale="2" ...>...</ div>
div id="point_1_1" data-scale="1" ...>...</ div>
div id="point_1_2" data-scale="1" ...>...</ div>
div id="index2" data-step="index"></ div>
div id="point_2_1" data-scale="1" ...>...</ div>
div id="point_2_2" data-scale="1" ...>...</ div>
div id="index3" data-step="index"></ div>
div id="point_3" data-scale="1" ...>...</ div>

@SiegeWizard
Copy link

I found some time and I made this change into impress.js goto method. There is nothing new, some of the tasks that were performed by goto are now performed by setCamera, that returns duration + delay as goto needs this value for the setTimeout. I think you will be able to understand everything as it is mainly your code so I removed the comments and spaces so that it didnt take that much space. If I knew how to use Github i would made a pull request but I have never tried to understand github. My main objetive while doing this was changing the less posible. And here you have the new functions.

var setCamera = function ( target, duration ) {
window.scrollTo(0, 0);
var target = {
rotate: {
x: toNumber(target.rotate.x),
y: toNumber(target.rotate.y),
z: toNumber(target.rotate.z)
},
translate: {
x: toNumber(target.translate.x),
y: toNumber(target.translate.y),
z: toNumber(target.translate.z)
},
scale: toNumber(target.scale, 1)
};
var zoomin = target.scale >= currentState.scale;
duration = toNumber(duration, config.transitionDuration);
var delay = (duration / 2);
if (el === activeStep) {
windowScale = computeWindowScale(config);
}
var targetScale = target.scale * windowScale;
if (activeStep) {
onStepLeave(activeStep);
}
css(root, {
transform: perspective( config.perspective / targetScale ) + scale( targetScale ),
transitionDuration: duration + "ms",
transitionDelay: (zoomin ? delay : 0) + "ms"
});
css(canvas, {
transform: rotate(target.rotate, true) + translate(target.translate),
transitionDuration: duration + "ms",
transitionDelay: (zoomin ? 0 : delay) + "ms"
});
if ( currentState.scale === target.scale ||
(currentState.rotate.x === target.rotate.x && currentState.rotate.y === target.rotate.y &&
currentState.rotate.z === target.rotate.z && currentState.translate.x === target.translate.x &&
currentState.translate.y === target.translate.y && currentState.translate.z === target.translate.z) ) {
delay = 0;
}
currentState = target;
return (duration + delay);
};

var goto = function ( el, duration ) {
if ( !initialized || !(el = getStep(el)) ) {
return false;
}
var step = stepsData["impress-" + el.id];
if ( activeStep ) {
activeStep.classList.remove("active");
body.classList.remove("impress-on-" + activeStep.id);
}
el.classList.add("active");
body.classList.add("impress-on-" + el.id);
var target = {
rotate: {
x: -step.rotate.x,
y: -step.rotate.y,
z: -step.rotate.z
},
translate: {
x: -step.translate.x,
y: -step.translate.y,
z: -step.translate.z
},
scale: 1 / step.scale
};
var time = setCamera(target, duration);
activeStep = el;
window.clearTimeout(stepEnterTimeout);
stepEnterTimeout = window.setTimeout(function() {
onStepEnter(activeStep);
}, time);
return el;
};

@perrybutler
Copy link

We have built an authoring tool around impress.js with a virtual camera/infinite canvas which can be used to create an entire presentation through a simple drag-drop UI, but the 30-slide/overview limit in Chrome still hasn't been resolved for over a year and that doesn't shed much hope on our attempts at designing a user-friendly authoring tool. The issue was reported somewhere in Chrome 18 but we are now at Chrome 30...hopefully the Chromium team will address it soon. I've just sent additional details to vangelis in an attempt to make some headway.

My concern is that we won't see very many truly capable authoring tools given the current state of Chrome's hardware rendering path.

See here:
https://code.google.com/p/chromium/issues/detail?id=318311
https://code.google.com/p/chromium/issues/detail?id=110457
#96
#244

Screenshots of the bug happening (we can reproduce it):

Starting with 30 visible elements (29 step divs and one background image div):

![screenshot 1](http://files.glassocean.net/software development/cc/chrome-hwa1.jpg)

Adding one more step div causes the gray background color to disappear:

![screenshot 2](http://files.glassocean.net/software development/cc/chrome-hwa2.jpg)

Adding another step div causes the background image div to disappear:

![screenshot 3](http://files.glassocean.net/software development/cc/chrome-hwa3.jpg)

Adding another step div causes a random visible step div to disappear:

![screenshot 4](http://files.glassocean.net/software development/cc/chrome-hwa4.jpg)

Adding another step div causes another random visible step div to disappear:

![screenshot 5](http://files.glassocean.net/software development/cc/chrome-hwa5.jpg)

Deleting the 4 recently added step divs restores everything that just disappeared:

![screenshot 6](http://files.glassocean.net/software development/cc/chrome-hwa1.jpg)

But as you can see, Chrome's software rendering is capable of TONS more divs:

![screenshot 7](http://files.glassocean.net/software development/cc/chrome-sw1.jpg)

@henrikingo
Copy link
Member

I think my people on this thread should check out my work-in-progress Impressionist 3D editor for impress.js.

A couple of things that are now in impress.js core were added to enable creating an editor: initAllSteps() is now called inside each goto(), so that dynamic changes to the presentation (add new slide) are taken into account when you call goto(). Also the new tear() method - to "uninitialize" impress back to original state - I added for Impressionist, although others had asked for that as well.

Other than that, all the editing/authoring functionality is in Impressionist itself. For example it was a lot of fun to implement a camera functionality as is also discussed here. impress.js is used to render the presentation, and impressionist adds its own functionality on top. But for the most part these remain separate and independent, and there was no need for a particular "Authoring API" in impress.js itself.

PS: I intend to move impressionist into the impress project too, once I finish cleaning up the state of impress.js first. (Which is still expected to take weeks.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants