Skip to content

Instantly share code, notes, and snippets.

@szmeku
Created December 16, 2013 16:32
Show Gist options
  • Save szmeku/7989938 to your computer and use it in GitHub Desktop.
Save szmeku/7989938 to your computer and use it in GitHub Desktop.
(function ($)
{
// jquery fix
jQuery.curCSS = jQuery.css;
$.ajaxSetup({
data: {
_token: config.token,
'XDEBUG_SESSION_START': 'PHPSTORM'
}
});
can.view.ext = ".mustache";
// ---- development settings ---
can.view.cache = false;
// -----------------------------
Mustache.registerHelper("planObjectToImage", function (plan_object)
{
if (plan_object.type === 'image')
{
return plan_object.getElement().src;
}
return 'http://placehold.it/150&text=group';
});
Mustache.registerHelper("renderPartial", function (name)
{
return can.view.render(config.BASE + '/admin/views/' + name, this);
});
Mustache.registerHelper('debug',
function (label, object)
{
console.log(label, ':::', object);
}
);
window.Floor = can.Model({
findOne: 'GET ' + config.venueURL + '/floors/{id}',
create: 'POST ' + config.venueURL + '/floors',
update: 'PUT ' + config.venueURL + '/floors/{id}',
// destroy: 'DELETE '+ config.venueURL + '/booths/{id}',
attributes: {
booths: 'Booth.List.newInstance',
name: 'string',
background: 'string'
}
}, {})
window.Booth = can.Model.extend({
findAll: 'GET ' + config.venueURL + '/booths',
findOne: 'GET ' + config.venueURL + '/booths/{id}',
create: 'POST ' + config.venueURL + '/floors/{floor_id}/booths',
update: 'PUT ' + config.venueURL + '/booths/{id}',
destroy: 'DELETE ' + config.venueURL + '/booths/{id}',
attributes: {
name: 'string',
price_limit: 'number',
bottle_limit: 'number',
plan_object: 'plan_object'
},
serialize: {
plan_object: function (raw)
{
if (typeof raw === 'object')
{
raw = JSON.stringify(raw.toJSON(['smart_image']));
}
return raw;
}
},
clone: function (booth)
{
var clone = new Booth(booth.attr()),
plan_object = fabric.util.object.clone(clone.plan_object);
clone.plan_object = plan_object;
clone.attr('name', booth.name + " clone");
clone.removeAttr('id');
plan_object.setLeft(plan_object.left + plan_object.width / 2);
plan_object.setTop(plan_object.top + plan_object.height / 2);
plan_object.model = clone;
canvas.add(plan_object);
canvas.renderAll();
booths().push(clone);
}
}, {
init: function ()
{
if (!this.name) this.attr('name', 'Unnamed');
this.convertPlanObject();
var test = 0;
},
convertPlanObject: function ()
{
if (typeof this.plan_object === 'string')
{
var dis = this,
plan_object = JSON.parse(this.plan_object);
fabric.util.enlivenObjects([plan_object], function (objects)
{
canvas.add(objects[0]);
canvas.renderAll();
setSmartImages(objects[0]);
dis.attr('plan_object', objects[0]);
});
}
}
});
Booth.List.prototype.remove = function (model)
{
this.splice(this.indexOf(model), 1);
}
window.SmartImage = can.Model({
findAll: 'GET ' + config.venueURL + '/smart_images',
findOne: 'GET ' + config.venueURL + '/smart_images/{id}',
create: 'POST ' + config.venueURL + '/smart_images',
update: 'PUT ' + config.venueURL + '/smart_images/{id}',
destroy: 'DELETE ' + config.venueURL + '/smart_images/{id}'
}, {
attributes: {
available: 'string',
reserved: 'string'
}
});
SmartImage.List.prototype.findById = function (id)
{
for (var i in this)
{
if (this[i].id == id)
{
return this[i];
}
}
}
window.booths = can.compute(new Booth.List());
window.smart_images = new SmartImage.List();
window.editing_booth = can.compute(new Booth());
SmartImage.findAll().then(function (items)
{
items.each(function (item)
{
smart_images.push(item);
});
Floor.findOne({id: 1}).then(function (item)
{
window.floor = item;
window.booths(floor.booths);
})
});
// Controllers
window.Plan = can.Control.extend({
init: function (element, options)
{
this.canvas = null;
this.canvas = new fabric.Canvas(element.get(0).id, {
backgroundColor: 'gray',
backgroundImageStretch: false,
selectionLineWidth: 0
});
this.canvas.setWidth(845);
this.canvas.setHeight(630);
this.canvas.renderAll();
// Debug
window.canvas = this.canvas;
},
'.date-picker click': function ()
{
var test = 432;
},
' dateChange': function (elem, event, date)
{
}
})
window.Background = can.Control.extend({
init: function (element, options)
{
element.html(view('background'));
},
'input change': function (elem, ev)
{
var file = elem.get(0).files[0];
readImage(file, function (url)
{
canvas.setBackgroundImage(url, canvas.renderAll.bind(canvas));
});
}
});
window.Booths = can.Control.extend({
init: function (element, options)
{
element.html(view('booths', {
booths: booths,
editing_booth: editing_booth,
smart_images: smart_images
}));
},
'click': function (elem, ev)
{
canvas.deactivateAll().renderAll();
},
'.add click': function (elem, ev)
{
booths().push(new Booth());
},
'.group click': function (elem, ev)
{
var active = canvas.getActiveGroup(),
model = new Booth(active.objects[0].model.attr());
active.forEachObject(function (obj)
{
booths().remove(obj.model);
});
var group = groupPlanObjects(active);
group.model = model;
model.attr('plan_object', group);
booths().push(model);
},
'.available, .reserved click': function (elem, ev)
{
var variant = elem.attr('class');
booths().forEach(function (item)
{
if (item.plan_object)
{
replaceImage(item.plan_object, variant);
}
})
},
'.delete click': function (elem, ev)
{
var model = elem.closest('.model').data('model');
if (model.plan_object)
{
canvas.remove(model.plan_object);
canvas.renderAll();
}
booths().remove(model);
},
'.edit click': function (elem, ev)
{
var model = elem.closest('.model').data('model');
editing_booth(model);
},
'.clone click': function (elem, ev)
{
var model = elem.closest('.model').data('model');
Booth.clone(model);
},
'#edit-booth input change': function (elem, ev)
{
var model = elem.closest('.model').data('model');
model.attr(elem.attr('name'), elem.get(0).value);
},
'#edit-booth .select-smart-image click': function (elem, ev)
{
var model = elem.closest('.model').data('model'),
smart_image = elem.closest('li.smart-image').data('model');
fabric.Image.fromURL(elem.attr('src'), function (img)
{
if (!!model.plan_object)
{
model.plan_object.remove();
}
model.attr('plan_object', img);
img.model = model;
img.smart_image = smart_image;
img.left = 80;
img.top = 80;
canvas.add(img);
});
}
});
window.SmartImages = can.Control.extend({
init: function (element, options)
{
element.html(view('smart_images', {
smart_images: smart_images
}));
},
'input change': function (elem, ev)
{
var model = elem.closest('.model').data('model'),
file = elem.get(0).files[0];
elem.attr('disabled', true);
uploadImage(file, {
success: function (key)
{
var imageURL = config.S3URL + key;
model.attr(elem.attr('class'), imageURL);
model.save();
elem.attr('disabled', false);
},
error: function (data)
{
console.log(data);
elem.attr('disabled', false);
}
})
},
'.add click': function (elem, ev)
{
smart_images.push({});
}
})
window.planController = new Plan('#plan', {});
window.backgroundController = new Background('.background', {});
window.boothsController = new Booths('.booths', {});
window.smartImagesController = new SmartImages('.smart-images', {});
// Helpers
function view(name, data)
{
return can.view(config.BASE + '/admin/views/' + name, data);
}
function updateFormData(formData)
{
var ajaxSetup = $.ajaxSetup().data;
for (var i in ajaxSetup)
{
formData.append(i, ajaxSetup[i]);
}
}
function uploadImage(file, callbacks)
{
var formdata = new FormData();
if (isImage(file) && formdata)
{
updateFormData(formdata);
formdata.append('image', file);
$.ajax({
url: config.uploadURL,
type: "POST",
data: formdata,
processData: false,
contentType: false,
success: function (data)
{
if (data.key)
{
callbacks.success(data.key);
} else
{
callbacks.error(data);
}
},
error: function (data)
{
callbacks.error(data);
}
});
} else
{
callbacks.error('upload error');
}
}
function isImage(file)
{
return file && !!file.type.match(/image.*/);
}
function readImage(file, callback)
{
if (window.FileReader)
{
var reader = new FileReader();
reader.onloadend = function (e)
{
callback(e.target.result);
};
reader.readAsDataURL(file);
}
}
function groupPlanObjects(active)
{
var clones = [];
active.forEachObject(function (obj)
{
var clone = fabric.util.object.clone(obj);
clone.hasBorders = false;
clones.push(clone);
obj.remove();
})
var group = new fabric.Group(clones, {
left: active.getLeft(),
top: active.getTop()});
canvas.add(group);
canvas.renderAll();
return group;
}
window.replaceImage = function (planObject, smartImageVariant)
{
if (planObject.type === 'group')
{
planObject.getObjects().forEach(function (item)
{
replaceImage(item, smartImageVariant);
});
} else if (planObject.type === 'image' && planObject.smart_image)
{
if (planObject.smart_image[smartImageVariant])
{
planObject.getElement().src = planObject.smart_image[smartImageVariant];
} else
{
alert("there's a Smart Image '" + smartImageVariant + "' variant missing");
}
}
canvas.renderAll();
}
window.setSmartImages = function(planObject){
if (planObject.type === 'group')
{
planObject.getObjects().forEach(function (item)
{
setSmartImages(item);
});
} else if (planObject.type === 'image')
{
if (!!planObject.smart_image && !!planObject.smart_image.id)
{
planObject.smart_image = smart_images.findById(planObject.smart_image.id);
} else
{
alert("some deserialized fabric object doesn't have smart_image or smart_image doesn't have id");
}
}
}
})(jQuery);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment