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

Improve bit editing alt #20

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@


<!--
<p class="ui-widget-header"></p>-->
<p class="bit__drag-handle"></p>-->

</div>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,43 +6,36 @@ makeBitDraggable = function makeBitDraggable($bitElement){
// // via manual transforms get overwritten by Draggable
// // http://greensock.com/docs/#/HTML5/GSAP/Utils/Draggable
var draggable = Draggable.create($bitElement, {

throwProps:false,
zIndexBoost:false,

onDragStart:function(event){

// var x = this.endX;
// var y = this.endY;
// Parallels.log.debug(event.type, " : dragStart: ", x, " : ", y, " : ", this.getDirection("start"), " : ");
Parallels.Audio.player.play('fx-cinq-drop');
},

onPress: function(event){

// TODO: improve performance
// use image asset instead of CSS shadow:
// https://stackoverflow.com/questions/16504281/css3-box-shadow-inset-painful-performance-killer

// TODO: ensure this happens only when in Draggable and mouse is held down
// and not on regular taps/clicks of bit
timeline.to($bitElement, 0.20, {
scale: 1.05,
boxShadow: "rgba(0, 0, 0, 0.2) 0 16px 32px 0",
ease: Expo.easeOut
});
timeline
.to($bitElement,
0.10,
{
scale: 1.05,
boxShadow: "rgba(0, 0, 0, 0.2) 0 16px 32px 0",
ease: Expo.easeOut
})
.to($bitElement.find('.bit__drag-handle'), 0.1, { scale: 1.5, opacity: "0.1", ease: Expo.easeOut }), "-=0.10";
},

onRelease: function(event){
timeline.to(
$bitElement,
0.1,
{
scale: 1,
boxShadow: "0",
ease: Expo.easeOut
}
);
timeline
.to($bitElement, 0.1, { scale: 1, boxShadow: "0", ease: Expo.easeOut })
.to($bitElement.find('.bit__drag-handle'), 0.1, { scale: 1, opacity: "1", ease: Expo.easeOut }), "-=0.10";
},

onDragStart:function(event){
// var x = this.endX;
// var y = this.endY;
// Parallels.log.debug(event.type, " : dragStart: ", x, " : ", y, " : ", this.getDirection("start"), " : ");
Parallels.Audio.player.play('fx-cinq-drop');
},

onDragEnd:function( event ) {
Expand All @@ -62,7 +55,8 @@ makeBitDraggable = function makeBitDraggable($bitElement){
// a random tone, in the mid-range of the scale
Parallels.Audio.player.play('tone--aalto-dubtechno-mod-' + _.random(4, 8));

timeline.to($bitElement, 0.1, { scale: 1, boxShadow: "0", ease: Expo.easeOut });
timeline
.to($bitElement, 0.1, { scale: 1, boxShadow: "0", ease: Expo.easeOut });
}
});

Expand Down
87 changes: 65 additions & 22 deletions meteor-app/client/components/bits/base/events.js
Original file line number Diff line number Diff line change
@@ -1,52 +1,95 @@
BitEvents = {

// TODO: clean up

hoverInBit: function (event, template) {
Session.set('bitHoveringId', template.data._id);
Parallels.Audio.player.play('fx-ting3');
// prevents bits that were under the bit person is dragging, from starting to highlight
// TODO: refactor to use GSAP built in methods, to test if something is being dragged?
if (!Session.get('mousedown')) {
Session.set('bitHoveringId', template.data._id);

Parallels.Audio.player.play('fx-ting3');

// SD: OQ/TODO: this fails on bit:delete, how can we reuse this function?
var $bit = $(template.firstNode);
$bit.addClass('hovering');
// SD: OQ/TODO: this fails on bit:delete, how can we reuse this function?
var $bitElement = $(template.firstNode);
$bitElement.addClass('hovering');
$bitElement.find('.bit__controls-persistent').show();
}
},

hoverOutBit: function (event, template){
Session.set('bitHoveringId', null);
var $bit = $(template.firstNode);
$bit.removeClass('hovering');
if (!Session.get('mousedown')) {
Session.set('bitHoveringId', null);

var $bitElement = $(template.firstNode);
$bitElement.removeClass('hovering');
$bitElement.find('.bit__controls-persistent').hide();

}
}
};



// for more bit events see /client/lib/key-bindings.js
Template.bit.events({

'mouseenter .bit': BitEvents.hoverInBit,

'mouseleave .bit': BitEvents.hoverOutBit,

'keyup .bit': function (event, template) {
'mousedown .bit': function () {
Session.set('mousedown', true);
},

'mouseup .bit': function () {
Session.set('mousedown', false);
},

if(event.which === 13){
'dblclick .bit': function (event, template) {
event.stopPropagation() // so map doesnt register a double click

var $bitElement = $(template.firstNode);
if (template.data.type === "text" && !(Session.get('textBitEditingId'))) {
Session.set('textBitEditingId', template.data._id);
Parallels.AppModes['edit-text-bit'].enter($bitElement, template);
}
},

'click .controls__icon-save': function (event, template) {
if (Session.get('textBitEditingId')){
var $bitElement = $(template.firstNode);
var withSave = true;
Parallels.AppModes['edit-text-bit'].exit($bitElement, template, withSave);
}
},

'click .controls__icon-delete': function (event, template) {
var bitDeleteId = Session.get('textBitEditingId');

if (bitDeleteId){
Parallels.log.debug("starting bit:delete on ", bitDeleteId);
Parallels.Audio.player.play('fx-tri');

if (this.content != template.find('.editbit').value) {
Meteor.call('changeState', {
command: 'updateBitContent',
command: 'deleteBit',
data: {
canvasId: Session.get('canvasId'),
_id: this._id,
content: template.find('.editbit').value
_id: bitDeleteId
}
});
}

Parallels.Audio.player.play('fx-cha-ching');

Session.set('bitEditingId', null);
var $bitElement = $(template.firstNode);
var withSave = false;
Parallels.AppModes['edit-text-bit'].exit($bitElement, template, withSave);
}
},

if (event.which === 27) {
Session.set('bitEditingId', null);
}
'click .controls__icon-cancel': function (event, template) {

// Parallels.Audio.player.play('fx-tri');
var $bitElement = $(template.firstNode);
var withSave = false;
Parallels.AppModes['edit-text-bit'].exit($bitElement, template, withSave);
}

});
34 changes: 34 additions & 0 deletions meteor-app/client/components/bits/base/experiment.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//$(function() {
// // changes mouse cursor when highlighting loawer right of box
// $(document).on('mousemove', 'textarea', function(e) {
// var a = $(this).offset().top + $(this).outerHeight() - 16, // top border of bottom-right-corner-box area
// b = $(this).offset().left + $(this).outerWidth() - 16; // left border of bottom-right-corner-box area
// $(this).css({
// cursor: e.pageY > a && e.pageX > b ? 'nw-resize' : ''
// });
// })
// // the following simple make the textbox "Auto-Expand" as it is typed in
// .on('keyup', 'textarea', function(e) {
// // the following will help the text expand as typing takes place
// while($(this).outerHeight() < this.scrollHeight + parseFloat($(this).css("borderTopWidth")) + parseFloat($(this).css("borderBottomWidth"))) {
// $(this).height($(this).height()+1);
// };
// })
// .on('keydown', 'textarea', function (e) {
// var keyCode = e.keyCode || e.which;
// if (keyCode == 9) {
// e.preventDefault();
// var start = $(this).get(0).selectionStart;
// var end = $(this).get(0).selectionEnd;
//
// // set textarea value to: text before caret + tab + text after caret
// $(this).val($(this).val().substring(0, start)
// + "\t"
// + $(this).val().substring(end));
//
// // put caret at right position again
// $(this).get(0).selectionStart =
// $(this).get(0).selectionEnd = start + 1;
// }
// });
//});
20 changes: 12 additions & 8 deletions meteor-app/client/components/bits/base/helpers.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
Template.bit.helpers({

isEditingTextBit: function() {
return Session.equals('bitEditingId', this._id);
},

isTextBit: function() {
return this.type === "text";
},

contentOrPlaceholder: function () {
var hasContent = this.content && this.content.length > 0;
return hasContent ? this.content : '[enter text]';
isImageBit: function() {
return this.type === "image";
},

imageSrc: function () {
return this.imageDataUrl || this.imageSource;
},
Expand All @@ -29,5 +24,14 @@ Template.bit.helpers({
} else {
return 'complete';
}
},

// TODO: rendering contenteditbable from inside a helper due to the following outstanding meteor issues:
// https://github.com/meteor/meteor/issues/2980
// https://github.com/meteor/meteor/issues/1964
// https://github.com/meteor/meteor/issues/3635
// possible alternative workaround: https://github.com/eluck/contenteditable/commit/b406d83863341c376f21f7de5056fdc8d4100877
editor: function () {
return '<div class="bit--editing" contenteditable="false">' + this.content + '</div>';
}
});
32 changes: 31 additions & 1 deletion meteor-app/client/components/bits/base/rendered.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,36 @@ Template.bit.onRendered(function (){

makeBitDraggable($bitElement);

if (template.data.type === 'text'){
var $content = $bitElement.find('.bit__content');
var $editbitElement = $content.find('.bit--editing');

$content.css("height", bit.height);
$content.css("width", bit.width);

// // TODO: reusable function
// $editbitElement.bind('mousewheel DOMMouseScroll', function(e) {
// var scrollTo = null;

// if (e.type == 'mousewheel') {
// scrollTo = (e.originalEvent.wheelDelta * -1);
// }
// else if (e.type == 'DOMMouseScroll') {
// // TODO: refactor '40' value to variable name for readability
// scrollTo = 40 * e.originalEvent.detail;
// }

// if (scrollTo) {
// e.preventDefault();
// $(this).scrollTop(scrollTo + $(this).scrollTop());
// }
// });

if (Session.get('textBitEditingId')){
Parallels.AppModes['edit-text-bit'].enter($bitElement, template);
}
}


// When a Bit position is updated during a concurrent session (by someone else)
// move the bit to it's new position on all other sessions/clients
Expand All @@ -30,7 +60,7 @@ Template.bit.onRendered(function (){
/*
AB: OQ: would show a friendly error message but the next line we remove the bit
so it isn't worth it. Should we figure out how to keep the Bit even if upload fails?
$bitElement.find('.content')[0].classList.add('complete', 'error');
$bitElement.find('.bit__content')[0].classList.add('complete', 'error');
*/
computation.stop();
Meteor.call('changeState', {
Expand Down
Loading