konva.js transformer crop box behavior problem - html

Is there any way to do the same with the cropbox action in the link below?
I am using the latest version of konva, but it seems that the link does not work after version 4.
https://codepen.io/kade87/pen/vYavQMp?editors=1011
How can I use it to work like a link in the latest version?
We must solve this problem. Or is there a javascript crop library that supports both pc and mobile? If so, please recommend. However, most of the libraries didn't work the way we wanted.
<script src="https://unpkg.com/konva#^4/konva.min.js"></script>
<div id="container"></div>
<script>
// noprotect
const stage = new Konva.Stage({
container: 'container',
width: window.innerWidth,
height: window.innerHeight
});
const layer = new Konva.Layer();
stage.add(layer);
Konva.Image.fromURL('https://i.imgur.com/ktWThtZ.png', img => {
img.setAttrs({
width: stage.width(),
height: stage.height(),
opacity: 0.5
});
layer.add(img)
})
Konva.Image.fromURL('https://i.imgur.com/ktWThtZ.png', img => {
var group = new Konva.Group({
clipFunc: (ctx) => {
ctx.save();
ctx.translate(fakeShape.x(), fakeShape.y())
ctx.rotate(Konva.getAngle(fakeShape.rotation()))
ctx.rect(0, 0, fakeShape.width() * fakeShape.scaleX(), fakeShape.height() * fakeShape.scaleY());
ctx.restore()
}
})
layer.add(group);
img.setAttrs({
width: stage.width(),
height: stage.height(),
});
group.add(img);
var fakeShape = new Konva.Rect({
width: 100,
height: 100,
x: 100,
y: 100,
fill: 'rgba(0,0,0,0)',
draggable: true
})
layer.add(fakeShape);
var tr = new Konva.Transformer({
enabledAnchors: ['top-left', 'bottom-right'],
rotateEnabled: false,
keepRatio: false,
flipEnabled: true,
node: fakeShape,
boundBoxFunc: (oldBox, newBox) => {
if(newBox.width < 50) {
newBox.width = 50
// newBox.x = oldBox.x
}
if(newBox.height < 50) {
newBox.height = 50
// newBox.y = oldBox.y
}
return newBox
}
});
layer.add(tr);
layer.draw();
});
</script>

Related

JoinJS - fromJSON method error: "dia.ElementView: markup required"

I have a problem that I can't solve. I want to use JointJS fromJSON function to reconstruct the flowchart from a JSON (previously exported using JoinJS's toJSON function.
The problem is that the call to the fromJSON function always returns the following error:
Whether I call it inside the hook mounted () or call it from the click of a button.
For completeness I also want to say that I am using Vue.js.
The code I'm using instead is the following:
<template>
<div class="wrapper">
<button v-on:click="getGraphJSON">Get graph JSON</button>
<button v-on:click="resetGraphJSON">Restore graph from JSON</button>
<div id="myholder"></div>
</div>
</template>
<script>
const _ = require('lodash')
const joint = require('jointjs')
const g = require('../../node_modules/jointjs/dist/geometry.js')
const backbone = require('../../node_modules/backbone/backbone.js')
const $ = require('../../node_modules/jquery/dist/jquery.js')
import '../../node_modules/jointjs/dist/joint.css';
var CustomRectangle = joint.shapes.standard.Rectangle.define('CustomRectangle', {
type: 'CustomRectangle',
attrs: {
body: {
rx: 10, // add a corner radius
ry: 10,
strokeWidth: 1,
fill: 'cornflowerblue'
},
label: {
textAnchor: 'left', // align text to left
refX: 10, // offset text from right edge of model bbox
fill: 'white',
fontSize: 18
}
}
}, {
markup: [{
tagName: 'rect',
selector: 'body',
}, {
tagName: 'text',
selector: 'label'
}]
}, {
createRandom: function() {
var rectangle = new this();
var fill = '#' + ('000000' + Math.floor(Math.random() * 16777215).toString(16)).slice(-6);
var stroke = '#' + ('000000' + Math.floor(Math.random() * 16777215).toString(16)).slice(-6);
var strokeWidth = Math.floor(Math.random() * 6);
var strokeDasharray = Math.floor(Math.random() * 6) + ' ' + Math.floor(Math.random() * 6);
var radius = Math.floor(Math.random() * 21);
rectangle.attr({
body: {
fill: fill,
stroke: stroke,
strokeWidth: strokeWidth,
strokeDasharray: strokeDasharray,
rx: radius,
ry: radius
},
label: { // ensure visibility on dark backgrounds
fill: 'black',
stroke: 'white',
strokeWidth: 1,
fontWeight: 'bold'
}
});
return rectangle;
}
});
export default {
name: 'JointChartRestorable',
data() {
return {
graph: null,
paper: null,
// graphJSON: JSON.parse('{"cells":[{"type":"standard.Rectangle","position":{"x":100,"y":30},"size":{"width":100,"height":40},"angle":0,"id":"049776c9-7b6d-4aaa-8b02-1edc3bea9852","z":1,"attrs":{"body":{"fill":"blue"},"label":{"fill":"white","text":"Rect #1"}}},{"type":"standard.Rectangle","position":{"x":400,"y":30},"size":{"width":100,"height":40},"angle":0,"id":"b6e77973-1195-4749-99e1-728549329b11","z":2,"attrs":{"body":{"fill":"#2C3E50","rx":5,"ry":5},"label":{"fontSize":18,"fill":"#3498DB","text":"Rect #2","fontWeight":"bold","fontVariant":"small-caps"}}},{"type":"standard.Link","source":{"id":"049776c9-7b6d-4aaa-8b02-1edc3bea9852"},"target":{"id":"b6e77973-1195-4749-99e1-728549329b11"},"id":"4ed8e3b3-55de-4ad2-b79e-d4848adc4a58","labels":[{"attrs":{"text":{"text":"Hello, World!"}}}],"z":3,"attrs":{"line":{"stroke":"blue","strokeWidth":1,"targetMarker":{"d":"M 10 -5 0 0 10 5 Z","stroke":"black","fill":"yellow"},"sourceMarker":{"type":"path","stroke":"black","fill":"red","d":"M 10 -5 0 0 10 5 Z"}}}}],"graphCustomProperty":true,"graphExportTime":1563951791966}')
// graphJSON: JSON.parse('{"cells":[{"type":"examples.CustomRectangle","position":{"x":90,"y":30},"size":{"width":100,"height":40},"angle":0,"id":"faa7f957-4691-4bb2-b907-b2054f7e07de","z":1,"attrs":{"body":{"fill":"blue"},"label":{"text":"Rect #1"}}}]}')
graphJSON: JSON.parse('{"cells":[{"type":"CustomRectangle","position":{"x":100,"y":30},"size":{"width":100,"height":40},"angle":0,"id":"f02da591-c03c-479f-88cf-55c291064ca8","z":1,"attrs":{"body":{"fill":"blue"},"label":{"text":"Rect #1"}}}]}')
};
},
methods: {
getGraphJSON: function() {
this.graphJSON = this.graph.toJSON();
console.log(JSON.stringify(this.graphJSON));
this.graph.get('graphCustomProperty'); // true
this.graph.get('graphExportTime');
},
resetGraphJSON: function() {
if(this.graphJSON !== undefined && this.graphJSON !== null && this.graphJSON !== '') {
this.graph.fromJSON(this.graphJSON);
// this.paper.model.set(this.graphJSON);
} else {
alert('Devi prima cliccare sul tasto "Get graph JSON" almeno una volta');
}
}
},
mounted() {
this.graph = new joint.dia.Graph();
this.graph.fromJSON(this.graphJSON);
// this.graph.set('graphCustomProperty', true);
// this.graph.set('graphExportTime', Date.now());
this.paper = new joint.dia.Paper({
el: document.getElementById('myholder'),
model: this.graph,
width: '100%',
height: 600,
gridSize: 10,
drawGrid: true,
background: {
color: 'rgba(0, 255, 0, 0.3)'
},
// interactive: false, // disable default interaction (e.g. dragging)
/*elementView: joint.dia.ElementView.extend({
pointerdblclick: function(evt, x, y) {
joint.dia.CellView.prototype.pointerdblclick.apply(this, arguments);
this.notify('element:pointerdblclick', evt, x, y);
this.model.remove();
}
}),
linkView: joint.dia.LinkView.extend({
pointerdblclick: function(evt, x, y) {
joint.dia.CellView.prototype.pointerdblclick.apply(this, arguments);
this.notify('link:pointerdblclick', evt, x, y);
this.model.remove();
}
})*/
});
/*this.paper.on('cell:pointerdblclick', function(cellView) {
var isElement = cellView.model.isElement();
var message = (isElement ? 'Element' : 'Link') + ' removed';
eventOutputLink.attr('label/text', message);
eventOutputLink.attr('body/visibility', 'visible');
eventOutputLink.attr('label/visibility', 'visible');
});*/
/***************************************************/
/************** GRAPH ELEMENT SAMPLE ***************/
/***************************************************/
// var rect = new joint.shapes.standard.Rectangle();
// var rect = new CustomRectangle();
// rect.position(100, 30);
// rect.resize(100, 40);
// rect.attr({
// body: {
// fill: 'blue'
// },
// label: {
// text: 'Rect #1',
// fill: 'white'
// }
// });
// rect.addTo(this.graph);
/***************************************************/
/************** GRAPH ELEMENT SAMPLE ***************/
/***************************************************/
}
}
</script>
Right now I'm using a custom element, previously defined, but I've also done tests using the standard Rectangle element of JointJS.
Can anyone tell me if I'm doing something wrong?
Many thanks in advance.
Markup object could not be found in element that's reason why this error is getting. After it's imported jointjs to the vueJS project through jointjs or rabbit dependency;
import * as joint from 'jointjs' or import * as joint from 'rabbit'
window.joint = joint;
joint should be adjusted as global in environment by using window.

Fabric JS object alignment not working as expected

I tried to align an object within a group. When I align the first object to the left, center or right it was successful, then I tried for the second object, the first object moved by itself!
Please see the image below (GIF):
Fabric JS Object Alignment
I used HTML5 Canvas, fabric JS & jQuery for the development.
Here is the fiddle: https://jsfiddle.net/mt0ccqq2/
Here is the Code:
$(document).ready(function() {
var canvas = new fabric.Canvas("canvas", { preserveObjectStacking: true });
// create rectangle
var rect = new fabric.Rect({
left: 50,
top: 50,
width: 300,
height: 100,
fill: '#ff0000'
});
// create circle
var text = new fabric.Text("Align Me next", {
left: 190,
top: 320,
fontSize: 20
});
// create text
var text2 = new fabric.Text("Align me first", {
left: 100,
top: 200,
fontSize: 20
});
canvas.add(rect, text, text2);
canvas.renderAll();
// GROUP ON SELECTION
canvas.on("selection:created", function(e) {
var activeObj = canvas.getActiveGroup();
if(activeObj.type === "group") {
console.log("Group created");
var groupWidth = e.target.getWidth();
var groupHeight = e.target.getHeight();
e.target.forEachObject(function(obj) {
var itemWidth = obj.getBoundingRect().width;
var itemHeight = obj.getBoundingRect().height;
// ================================
// OBJECT ALIGNMENT: " H-LEFT "
// ================================
$('#objAlignLeft').click(function() {
obj.set({
left: -(groupWidth / 2),
originX: 'left'
});
obj.setCoords();
canvas.renderAll();
});
// ================================
// OBJECT ALIGNMENT: " H-CENTER "
// ================================
$('#objAlignCenter').click(function() {
obj.set({
left: (0 - itemWidth/2),
originX: 'left'
});
obj.setCoords();
canvas.renderAll();
});
// ================================
// OBJECT ALIGNMENT: " H-RIGHT "
// ================================
$('#objAlignRight').click(function() {
obj.set({
left: (groupWidth/2 - itemWidth/2),
originX: 'center'
});
obj.setCoords();
canvas.renderAll();
});
});
}
}); // END OF " SELECTION:CREATED "
});
Any help would be appreciated. Thanks in advance.
I think this is what you're looking for, right?
Here's the tweak to your code...
canvas.on("selection:cleared", function(e) {
$('#objAlignLeft').off('click');
$('#objAlignCenter').off('click');
$('#objAlignRight').off('click');
});
And here's the all important JSFiddle, https://jsfiddle.net/rekrah/xxrqbhph/.
Let me know if you have any further questions. Happy to help!

Google Street View with deviceorientation (Full Tilt)

I am trying to create a Google Street View that can be controlled via a devices orientation.
I am using Full Tilt to normalize devices / OS and it seems to be doing a really good job. In fact, it seems very close indeed to the solution I'm after.
However, at various positions, the view seems to jump rapidly (although it seems to resolve to the correct location) and is not as smooth as I would like. This seems particularly obvious if the device is held at around 90 degrees (upright) and rotated slightly to the left or right.
JS Fiddle has an example and would need to be viewed on a mobile device or tablet to see the effect. Following the link further down will only work if you can get to the edit mode where the deviceorientation is allowed to work.
Any ideas if there is a way to resolve this? Or if I'm on to a loser here?
var map;
google.maps.event.addDomListener(window, "load", function () {
// Set up map
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 9,
// Initial
center:{
lat: 35.6735408,
lng: 139.570305,
},
disableDefaultUI: true,
streetViewControl: true,
});
// Set up street view
google.maps.streetViewViewer = 'photosphere';
var street_view = new google.maps.StreetViewPanorama(document.getElementById('street-view'), {
addressControl: false,
fullscreenControl: false,
zoomControl: false,
});
street_view.setPano('2qVB_HA94-kQCAzwffO44g');
// When street view ready, update map position and pov
street_view.addListener('status_changed', function(){
var position = street_view.getPosition();
if( map ){
map.setCenter(position);
map.setStreetView(street_view);
}
});
// FULL TILT ORIENTATION
var promise = new FULLTILT.getDeviceOrientation({ 'type': 'world' });
var deviceOrientation;
promise
.then(function(controller) {
deviceOrientation = controller;
})
.catch(function(message) {
console.error(message);
});
(function draw() {
if (deviceOrientation) {
var euler = deviceOrientation.getScreenAdjustedEuler();
// debug
console.log('alpha: %d, beta: %d, gamma: %d', euler.alpha, euler.beta, euler.gamma);
document.getElementById('alpha').innerHTML = euler.alpha.toFixed(2);
document.getElementById('beta').innerHTML = euler.beta.toFixed(2);
document.getElementById('gamma').innerHTML = euler.gamma.toFixed(2);
// Set POV
if( euler.alpha != 0 && euler.beta != 0 && euler.gamma !=0 ){
street_view.setPov({
heading: euler.alpha*-1,
pitch: euler.beta-90,
});
}
}
requestAnimationFrame(draw);
})();
});
/*! Full Tilt v0.5.2 / http://github.com/richtr/Full-Tilt */
!function(a){function b(a){return a=+a,0===a||isNaN(a)?a:a>0?1:-1}function c(a){var b=new Promise(function(b,c){var d=function(e){setTimeout(function(){a&&a.data?b():e>=20?c():d(++e)},50)};d(0)});return b}function d(){o=n?(a.screen.orientation.angle||0)*j:(a.orientation||0)*j}function e(a){l.orientation.data=a;for(var b in l.orientation.callbacks)l.orientation.callbacks[b].call(this)}function f(a){l.motion.data=a;for(var b in l.motion.callbacks)l.motion.callbacks[b].call(this)}if(void 0===a.FULLTILT||null===a.FULLTILT){var g=Math.PI,h=g/2,i=2*g,j=g/180,k=180/g,l={orientation:{active:!1,callbacks:[],data:void 0},motion:{active:!1,callbacks:[],data:void 0}},m=!1,n=a.screen&&a.screen.orientation&&void 0!==a.screen.orientation.angle&&null!==a.screen.orientation.angle?!0:!1,o=(n?a.screen.orientation.angle:a.orientation||0)*j,p=h,q=g,r=i/3,s=-h,t={};t.version="0.5.2",t.getDeviceOrientation=function(a){var b=new Promise(function(b,d){var e=new t.DeviceOrientation(a);e.start();var f=new c(l.orientation);f.then(function(){e._alphaAvailable=l.orientation.data.alpha&&null!==l.orientation.data.alpha,e._betaAvailable=l.orientation.data.beta&&null!==l.orientation.data.beta,e._gammaAvailable=l.orientation.data.gamma&&null!==l.orientation.data.gamma,b(e)}).catch(function(){e.stop(),d("DeviceOrientation is not supported")})});return b},t.getDeviceMotion=function(a){var b=new Promise(function(b,d){var e=new t.DeviceMotion(a);e.start();var f=new c(l.motion);f.then(function(){e._accelerationXAvailable=l.motion.data.acceleration&&l.motion.data.acceleration.x,e._accelerationYAvailable=l.motion.data.acceleration&&l.motion.data.acceleration.y,e._accelerationZAvailable=l.motion.data.acceleration&&l.motion.data.acceleration.z,e._accelerationIncludingGravityXAvailable=l.motion.data.accelerationIncludingGravity&&l.motion.data.accelerationIncludingGravity.x,e._accelerationIncludingGravityYAvailable=l.motion.data.accelerationIncludingGravity&&l.motion.data.accelerationIncludingGravity.y,e._accelerationIncludingGravityZAvailable=l.motion.data.accelerationIncludingGravity&&l.motion.data.accelerationIncludingGravity.z,e._rotationRateAlphaAvailable=l.motion.data.rotationRate&&l.motion.data.rotationRate.alpha,e._rotationRateBetaAvailable=l.motion.data.rotationRate&&l.motion.data.rotationRate.beta,e._rotationRateGammaAvailable=l.motion.data.rotationRate&&l.motion.data.rotationRate.gamma,b(e)}).catch(function(){e.stop(),d("DeviceMotion is not supported")})});return b},t.Quaternion=function(a,c,d,e){var f;this.set=function(a,b,c,d){this.x=a||0,this.y=b||0,this.z=c||0,this.w=d||1},this.copy=function(a){this.x=a.x,this.y=a.y,this.z=a.z,this.w=a.w},this.setFromEuler=function(){var a,b,c,d,e,f,g,h,i,k,l,m;return function(n){return n=n||{},c=(n.alpha||0)*j,a=(n.beta||0)*j,b=(n.gamma||0)*j,f=c/2,d=a/2,e=b/2,g=Math.cos(d),h=Math.cos(e),i=Math.cos(f),k=Math.sin(d),l=Math.sin(e),m=Math.sin(f),this.set(k*h*i-g*l*m,g*l*i+k*h*m,g*h*m+k*l*i,g*h*i-k*l*m),this.normalize(),this}}(),this.setFromRotationMatrix=function(){var a;return function(c){return a=c.elements,this.set(.5*Math.sqrt(1+a[0]-a[4]-a[8])*b(a[7]-a[5]),.5*Math.sqrt(1-a[0]+a[4]-a[8])*b(a[2]-a[6]),.5*Math.sqrt(1-a[0]-a[4]+a[8])*b(a[3]-a[1]),.5*Math.sqrt(1+a[0]+a[4]+a[8])),this}}(),this.multiply=function(a){return f=t.Quaternion.prototype.multiplyQuaternions(this,a),this.copy(f),this},this.rotateX=function(a){return f=t.Quaternion.prototype.rotateByAxisAngle(this,[1,0,0],a),this.copy(f),this},this.rotateY=function(a){return f=t.Quaternion.prototype.rotateByAxisAngle(this,[0,1,0],a),this.copy(f),this},this.rotateZ=function(a){return f=t.Quaternion.prototype.rotateByAxisAngle(this,[0,0,1],a),this.copy(f),this},this.normalize=function(){return t.Quaternion.prototype.normalize(this)},this.set(a,c,d,e)},t.Quaternion.prototype={constructor:t.Quaternion,multiplyQuaternions:function(){var a=new t.Quaternion;return function(b,c){var d=b.x,e=b.y,f=b.z,g=b.w,h=c.x,i=c.y,j=c.z,k=c.w;return a.set(d*k+g*h+e*j-f*i,e*k+g*i+f*h-d*j,f*k+g*j+d*i-e*h,g*k-d*h-e*i-f*j),a}}(),normalize:function(a){var b=Math.sqrt(a.x*a.x+a.y*a.y+a.z*a.z+a.w*a.w);return 0===b?(a.x=0,a.y=0,a.z=0,a.w=1):(b=1/b,a.x*=b,a.y*=b,a.z*=b,a.w*=b),a},rotateByAxisAngle:function(){var a,b,c=new t.Quaternion,d=new t.Quaternion;return function(e,f,g){return a=(g||0)/2,b=Math.sin(a),d.set((f[0]||0)*b,(f[1]||0)*b,(f[2]||0)*b,Math.cos(a)),c=t.Quaternion.prototype.multiplyQuaternions(e,d),t.Quaternion.prototype.normalize(c)}}()},t.RotationMatrix=function(a,b,c,d,e,f,g,h,i){var k;this.elements=new Float32Array(9),this.identity=function(){return this.set(1,0,0,0,1,0,0,0,1),this},this.set=function(a,b,c,d,e,f,g,h,i){this.elements[0]=a||1,this.elements[1]=b||0,this.elements[2]=c||0,this.elements[3]=d||0,this.elements[4]=e||1,this.elements[5]=f||0,this.elements[6]=g||0,this.elements[7]=h||0,this.elements[8]=i||1},this.copy=function(a){this.elements[0]=a.elements[0],this.elements[1]=a.elements[1],this.elements[2]=a.elements[2],this.elements[3]=a.elements[3],this.elements[4]=a.elements[4],this.elements[5]=a.elements[5],this.elements[6]=a.elements[6],this.elements[7]=a.elements[7],this.elements[8]=a.elements[8]},this.setFromEuler=function(){var a,b,c,d,e,f,g,h,i;return function(k){return k=k||{},c=(k.alpha||0)*j,a=(k.beta||0)*j,b=(k.gamma||0)*j,d=Math.cos(a),e=Math.cos(b),f=Math.cos(c),g=Math.sin(a),h=Math.sin(b),i=Math.sin(c),this.set(f*e-i*g*h,-d*i,e*i*g+f*h,e*i+f*g*h,f*d,i*h-f*e*g,-d*h,g,d*e),this.normalize(),this}}(),this.setFromQuaternion=function(){var a,b,c,d;return function(e){return a=e.w*e.w,b=e.x*e.x,c=e.y*e.y,d=e.z*e.z,this.set(a+b-c-d,2*(e.x*e.y-e.w*e.z),2*(e.x*e.z+e.w*e.y),2*(e.x*e.y+e.w*e.z),a-b+c-d,2*(e.y*e.z-e.w*e.x),2*(e.x*e.z-e.w*e.y),2*(e.y*e.z+e.w*e.x),a-b-c+d),this}}(),this.multiply=function(a){return k=t.RotationMatrix.prototype.multiplyMatrices(this,a),this.copy(k),this},this.rotateX=function(a){return k=t.RotationMatrix.prototype.rotateByAxisAngle(this,[1,0,0],a),this.copy(k),this},this.rotateY=function(a){return k=t.RotationMatrix.prototype.rotateByAxisAngle(this,[0,1,0],a),this.copy(k),this},this.rotateZ=function(a){return k=t.RotationMatrix.prototype.rotateByAxisAngle(this,[0,0,1],a),this.copy(k),this},this.normalize=function(){return t.RotationMatrix.prototype.normalize(this)},this.set(a,b,c,d,e,f,g,h,i)},t.RotationMatrix.prototype={constructor:t.RotationMatrix,multiplyMatrices:function(){var a,b,c=new t.RotationMatrix;return function(d,e){return a=d.elements,b=e.elements,c.set(a[0]*b[0]+a[1]*b[3]+a[2]*b[6],a[0]*b[1]+a[1]*b[4]+a[2]*b[7],a[0]*b[2]+a[1]*b[5]+a[2]*b[8],a[3]*b[0]+a[4]*b[3]+a[5]*b[6],a[3]*b[1]+a[4]*b[4]+a[5]*b[7],a[3]*b[2]+a[4]*b[5]+a[5]*b[8],a[6]*b[0]+a[7]*b[3]+a[8]*b[6],a[6]*b[1]+a[7]*b[4]+a[8]*b[7],a[6]*b[2]+a[7]*b[5]+a[8]*b[8]),c}}(),normalize:function(a){var b=a.elements,c=b[0]*b[4]*b[8]-b[0]*b[5]*b[7]-b[1]*b[3]*b[8]+b[1]*b[5]*b[6]+b[2]*b[3]*b[7]-b[2]*b[4]*b[6];return b[0]/=c,b[1]/=c,b[2]/=c,b[3]/=c,b[4]/=c,b[5]/=c,b[6]/=c,b[7]/=c,b[8]/=c,a.elements=b,a},rotateByAxisAngle:function(){var a,b,c=new t.RotationMatrix,d=new t.RotationMatrix,e=!1;return function(f,g,h){return d.identity(),e=!1,a=Math.sin(h),b=Math.cos(h),1===g[0]&&0===g[1]&&0===g[2]?(e=!0,d.elements[4]=b,d.elements[5]=-a,d.elements[7]=a,d.elements[8]=b):1===g[1]&&0===g[0]&&0===g[2]?(e=!0,d.elements[0]=b,d.elements[2]=a,d.elements[6]=-a,d.elements[8]=b):1===g[2]&&0===g[0]&&0===g[1]&&(e=!0,d.elements[0]=b,d.elements[1]=-a,d.elements[3]=a,d.elements[4]=b),e?(c=t.RotationMatrix.prototype.multiplyMatrices(f,d),c=t.RotationMatrix.prototype.normalize(c)):c=f,c}}()},t.Euler=function(a,b,c){this.set=function(a,b,c){this.alpha=a||0,this.beta=b||0,this.gamma=c||0},this.copy=function(a){this.alpha=a.alpha,this.beta=a.beta,this.gamma=a.gamma},this.setFromRotationMatrix=function(){var a,b,c,d;return function(e){a=e.elements,a[8]>0?(b=Math.atan2(-a[1],a[4]),c=Math.asin(a[7]),d=Math.atan2(-a[6],a[8])):a[8]<0?(b=Math.atan2(a[1],-a[4]),c=-Math.asin(a[7]),c+=c>=0?-g:g,d=Math.atan2(a[6],-a[8])):a[6]>0?(b=Math.atan2(-a[1],a[4]),c=Math.asin(a[7]),d=-h):a[6]<0?(b=Math.atan2(a[1],-a[4]),c=-Math.asin(a[7]),c+=c>=0?-g:g,d=-h):(b=Math.atan2(a[3],a[0]),c=a[7]>0?h:-h,d=0),0>b&&(b+=i),b*=k,c*=k,d*=k,this.set(b,c,d)}}(),this.setFromQuaternion=function(){var a,b,c;return function(d){var e=d.w*d.w,f=d.x*d.x,j=d.y*d.y,l=d.z*d.z,m=e+f+j+l,n=d.w*d.x+d.y*d.z,o=1e-6;if(n>(.5-o)*m)a=2*Math.atan2(d.y,d.w),b=h,c=0;else if((-.5+o)*m>n)a=-2*Math.atan2(d.y,d.w),b=-h,c=0;else{var p=e-f+j-l,q=2*(d.w*d.z-d.x*d.y),r=e-f-j+l,s=2*(d.w*d.y-d.x*d.z);r>0?(a=Math.atan2(q,p),b=Math.asin(2*n/m),c=Math.atan2(s,r)):(a=Math.atan2(-q,-p),b=-Math.asin(2*n/m),b+=0>b?g:-g,c=Math.atan2(-s,-r))}0>a&&(a+=i),a*=k,b*=k,c*=k,this.set(a,b,c)}}(),this.rotateX=function(a){return t.Euler.prototype.rotateByAxisAngle(this,[1,0,0],a),this},this.rotateY=function(a){return t.Euler.prototype.rotateByAxisAngle(this,[0,1,0],a),this},this.rotateZ=function(a){return t.Euler.prototype.rotateByAxisAngle(this,[0,0,1],a),this},this.set(a,b,c)},t.Euler.prototype={constructor:t.Euler,rotateByAxisAngle:function(){var a=new t.RotationMatrix;return function(b,c,d){return a.setFromEuler(b),a=t.RotationMatrix.prototype.rotateByAxisAngle(a,c,d),b.setFromRotationMatrix(a),b}}()},t.DeviceOrientation=function(b){this.options=b||{};var c=0,d=200,e=0,f=10;if(this.alphaOffsetScreen=0,this.alphaOffsetDevice=void 0,"game"===this.options.type){var g=function(b){return null!==b.alpha&&(this.alphaOffsetDevice=new t.Euler(b.alpha,0,0),this.alphaOffsetDevice.rotateZ(-o),++e>=f)?void a.removeEventListener("deviceorientation",g,!1):void(++c>=d&&a.removeEventListener("deviceorientation",g,!1))}.bind(this);a.addEventListener("deviceorientation",g,!1)}else if("world"===this.options.type){var h=function(b){return b.absolute!==!0&&void 0!==b.webkitCompassAccuracy&&null!==b.webkitCompassAccuracy&&+b.webkitCompassAccuracy>=0&&+b.webkitCompassAccuracy<50&&(this.alphaOffsetDevice=new t.Euler(b.webkitCompassHeading,0,0),this.alphaOffsetDevice.rotateZ(o),this.alphaOffsetScreen=o,++e>=f)?void a.removeEventListener("deviceorientation",h,!1):void(++c>=d&&a.removeEventListener("deviceorientation",h,!1))}.bind(this);a.addEventListener("deviceorientation",h,!1)}},t.DeviceOrientation.prototype={constructor:t.DeviceOrientation,start:function(b){b&&"[object Function]"==Object.prototype.toString.call(b)&&l.orientation.callbacks.push(b),m||(n?a.screen.orientation.addEventListener("change",d,!1):a.addEventListener("orientationchange",d,!1)),l.orientation.active||(a.addEventListener("deviceorientation",e,!1),l.orientation.active=!0)},stop:function(){l.orientation.active&&(a.removeEventListener("deviceorientation",e,!1),l.orientation.active=!1)},listen:function(a){this.start(a)},getFixedFrameQuaternion:function(){var a=new t.Euler,b=new t.RotationMatrix,c=new t.Quaternion;return function(){var d=l.orientation.data||{alpha:0,beta:0,gamma:0},e=d.alpha;return this.alphaOffsetDevice&&(b.setFromEuler(this.alphaOffsetDevice),b.rotateZ(-this.alphaOffsetScreen),a.setFromRotationMatrix(b),a.alpha<0&&(a.alpha+=360),e-=a.alpha),a.set(e,d.beta,d.gamma),c.setFromEuler(a),c}}(),getScreenAdjustedQuaternion:function(){var a;return function(){return a=this.getFixedFrameQuaternion(),a.rotateZ(-o),a}}(),getFixedFrameMatrix:function(){var a=new t.Euler,b=new t.RotationMatrix;return function(){var c=l.orientation.data||{alpha:0,beta:0,gamma:0},d=c.alpha;return this.alphaOffsetDevice&&(b.setFromEuler(this.alphaOffsetDevice),b.rotateZ(-this.alphaOffsetScreen),a.setFromRotationMatrix(b),a.alpha<0&&(a.alpha+=360),d-=a.alpha),a.set(d,c.beta,c.gamma),b.setFromEuler(a),b}}(),getScreenAdjustedMatrix:function(){var a;return function(){return a=this.getFixedFrameMatrix(),a.rotateZ(-o),a}}(),getFixedFrameEuler:function(){var a,b=new t.Euler;return function(){return a=this.getFixedFrameMatrix(),b.setFromRotationMatrix(a),b}}(),getScreenAdjustedEuler:function(){var a,b=new t.Euler;return function(){return a=this.getScreenAdjustedMatrix(),b.setFromRotationMatrix(a),b}}(),isAbsolute:function(){return l.orientation.data&&l.orientation.data.absolute===!0?!0:!1},getLastRawEventData:function(){return l.orientation.data||{}},_alphaAvailable:!1,_betaAvailable:!1,_gammaAvailable:!1,isAvailable:function(a){switch(a){case this.ALPHA:return this._alphaAvailable;case this.BETA:return this._betaAvailable;case this.GAMMA:return this._gammaAvailable}},ALPHA:"alpha",BETA:"beta",GAMMA:"gamma"},t.DeviceMotion=function(a){this.options=a||{}},t.DeviceMotion.prototype={constructor:t.DeviceMotion,start:function(b){b&&"[object Function]"==Object.prototype.toString.call(b)&&l.motion.callbacks.push(b),m||(n?a.screen.orientation.addEventListener("change",d,!1):a.addEventListener("orientationchange",d,!1)),l.motion.active||(a.addEventListener("devicemotion",f,!1),l.motion.active=!0)},stop:function(){l.motion.active&&(a.removeEventListener("devicemotion",f,!1),l.motion.active=!1)},listen:function(a){this.start(a)},getScreenAdjustedAcceleration:function(){var a=l.motion.data&&l.motion.data.acceleration?l.motion.data.acceleration:{x:0,y:0,z:0},b={};switch(o){case p:b.x=-a.y,b.y=a.x;break;case q:b.x=-a.x,b.y=-a.y;break;case r:case s:b.x=a.y,b.y=-a.x;break;default:b.x=a.x,b.y=a.y}return b.z=a.z,b},getScreenAdjustedAccelerationIncludingGravity:function(){var a=l.motion.data&&l.motion.data.accelerationIncludingGravity?l.motion.data.accelerationIncludingGravity:{x:0,y:0,z:0},b={};switch(o){case p:b.x=-a.y,b.y=a.x;break;case q:b.x=-a.x,b.y=-a.y;break;case r:case s:b.x=a.y,b.y=-a.x;break;default:b.x=a.x,b.y=a.y}return b.z=a.z,b},getScreenAdjustedRotationRate:function(){var a=l.motion.data&&l.motion.data.rotationRate?l.motion.data.rotationRate:{alpha:0,beta:0,gamma:0},b={};switch(o){case p:b.beta=-a.gamma,b.gamma=a.beta;break;case q:b.beta=-a.beta,b.gamma=-a.gamma;break;case r:case s:b.beta=a.gamma,b.gamma=-a.beta;break;default:b.beta=a.beta,b.gamma=a.gamma}return b.alpha=a.alpha,b},getLastRawEventData:function(){return l.motion.data||{}},_accelerationXAvailable:!1,_accelerationYAvailable:!1,_accelerationZAvailable:!1,_accelerationIncludingGravityXAvailable:!1,_accelerationIncludingGravityYAvailable:!1,_accelerationIncludingGravityZAvailable:!1,_rotationRateAlphaAvailable:!1,_rotationRateBetaAvailable:!1,_rotationRateGammaAvailable:!1,isAvailable:function(a){switch(a){case this.ACCELERATION_X:return this._accelerationXAvailable;case this.ACCELERATION_Y:return this._accelerationYAvailable;case this.ACCELERATION_Z:return this._accelerationZAvailable;case this.ACCELERATION_INCLUDING_GRAVITY_X:return this._accelerationIncludingGravityXAvailable;case this.ACCELERATION_INCLUDING_GRAVITY_Y:return this._accelerationIncludingGravityYAvailable;case this.ACCELERATION_INCLUDING_GRAVITY_Z:return this._accelerationIncludingGravityZAvailable;case this.ROTATION_RATE_ALPHA:return this._rotationRateAlphaAvailable;case this.ROTATION_RATE_BETA:return this._rotationRateBetaAvailable;case this.ROTATION_RATE_GAMMA:return this._rotationRateGammaAvailable}},ACCELERATION_X:"accelerationX",ACCELERATION_Y:"accelerationY",ACCELERATION_Z:"accelerationZ",ACCELERATION_INCLUDING_GRAVITY_X:"accelerationIncludingGravityX",ACCELERATION_INCLUDING_GRAVITY_Y:"accelerationIncludingGravityY",ACCELERATION_INCLUDING_GRAVITY_Z:"accelerationIncludingGravityZ",ROTATION_RATE_ALPHA:"rotationRateAlpha",ROTATION_RATE_BETA:"rotationRateBeta",ROTATION_RATE_GAMMA:"rotationRateGamma"},a.FULLTILT=t}}(window);
#map{
width: 200px; height: 200px; position: absolute; right: 20px; bottom: 20px;
}
#street-view{
width: 100%; height: 100%; position: absolute; top: 0; left: 0;
}
#debug{
position: absolute; top: 0; left: 0; padding: 10px; border: 1px solid white; color: white;
}
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js"></script>
<div id="street-view"></div>
<div id="map"></div>
<div id="debug">
alpha: <span id="alpha"></span> |
beta: <span id="beta"></span> |
gamma: <span id="gamma"></span>
</div>

Fabric.js clipping individual objects dynamically

I am dynamically adding a rect element to crop/clip (using clipTo) a selected element,
It works perfect at the first time but when i add a second element to the canvas and begin to crop the second element the first element looses the crop/clip. Below is my code, there are 2 buttons 1 to start crop/clip (places a dynamic rect over the element to be cropped) second to do the cropping/clipping.
$('#crop').on('click', function (event) {
var left = el.left - object.left;
var top = el.top - object.top;
left *= 1;
top *= 1;
var width = el.width * 1;
var height = el.height * 1;
object.clipTo = function (ctx)
{
ctx.rect(-(el.width/2)+left, -(el.height/2)+top, parseInt(width*el.scaleX), parseInt(el.scaleY*height));
}
for(var i=0; i<$("#layers li").size();i++)
{
canvas.item(i).selectable= true;
}
disabled = true;
canvas.remove(canvas.getActiveObject());
lastActive = object;
canvas.renderAll();
});
$('#startCrop').on('click',function(){
canvas.remove(el);
if(canvas.getActiveObject())
{
object=canvas.getActiveObject();
if (lastActive && lastActive !== object) {
lastActive.clipTo = null;
}
el = new fabric.Rect
({
fill: 'rgba(0,0,0,0.3)',
originX: 'left',
originY: 'top',
stroke: '#ccc',
strokeDashArray: [2, 2],
opacity: 1,
width: 1,
height: 1,
borderColor: '#36fd00',
cornerColor: 'green',
hasRotatingPoint:false
});
el.left=canvas.getActiveObject().left;
selection_object_left=canvas.getActiveObject().left;
selection_object_top=canvas.getActiveObject().top;
el.top=canvas.getActiveObject().top;
el.width=canvas.getActiveObject().width*canvas.getActiveObject().scaleX;
el.height=canvas.getActiveObject().height*canvas.getActiveObject().scaleY;
canvas.add(el);
canvas.setActiveObject(el);
for(var i=0; i<$("#layers li").size();i++)
{
canvas.item(i).selectable= false;
}
}
else{
alert("Please select an object or layer");
}
});
Is this what you're looking for? http://jsfiddle.net/86bTc/4/
You set the lastActive.clipTo = null;
try this code
function crop()
{
if (!fabric.Canvas.supports('toDataURL')) {
alert('This browser doesn\'t provide means to serialize canvas to an image');
}
else {
var obj = canvas.getActiveObject();
fabric.Image.fromURL(canvas.toDataURL({
format: 'png',
left: obj.left + 1,
top: obj.top + 1,
width: obj.width * obj.scaleX,
height: obj.height * obj.scaleY,
}), function (img) {
canvas.remove(obj);
canvas.remove(ao);
canvas.add(img);
canvas.renderAll();
})
}
}
;
function Select() {
ao = canvas.getActiveObject();
if (!ao)
return;
canvas.bringToFront(ao);
ao.selectable = false;
canvas.add(new fabric.Rect({
left: 200,
top: 200,
width: 200,
height: 200,
fill: 'transparent',
stroke: '#000000',
hasRotatingPoint: false,
strokeDashArray: [5, 5],
cornerSize: 8,
}));
}

What's wrong with loading this JSON?

What's wrong with loading this JSON?
Select a new object, set its ID, add and save it. Trying to reload the JSON object results in an empty canvas.
http://jsfiddle.net/Sugv4/14/
function loadCanvas() {
canvas.clear();
window.alert(js);
canvas.loadFromDatalessJSON(js)
canvas.renderAll();
}
Try put this in Javascript code:
var canvas;
$(function () {
canvas = window._canvas = new fabric.Canvas('c');
fabric.Labeledrect = fabric.util.createClass(fabric.Rect, {
type: 'labeledRect',
initialize: function (options) {
options || (options = {});
this.callSuper('initialize', options);
this.set('label', options.label);
this.set('id', options.id);
},
toObject: function () {
return fabric.util.object.extend(this.callSuper('toObject'), {
label: this.get('label'),
id: this.get('id')
});
},
_render: function (ctx) {
this.callSuper('_render', ctx);
ctx.font = '10px Helvetica';
ctx.fillStyle = '#333';
ctx.fillText(this.label, -this.width / 2, -this.height / 2 + 10);
ctx.fillText(this.id, -this.width / 2, -this.height / 2 + 30);
}
});
fabric.Labeledrect.fromObject = function (object, callback) {
return new fabric.Labeledrect(object);
}
fabric.Labeledrect.async = true;
});
function voegObjectToe() {
var myObjects = document.getElementById("myObjects");
var kenmerk = myObjects.options[myObjects.selectedIndex].text;
//nieuw object
var rect = new fabric.Labeledrect({
left: canvas.width / 2,
top: canvas.height / 2
});
if (kenmerk == 'Camper') {
rect.set({
width: 80,
height: 50,
fill: '#faa',
label: 'Camper',
id: document.getElementById("myObject").value
});
} else if (kenmerk == 'Caravan') {
rect.set({
width: 80,
height: 60,
fill: '#3ac',
label: 'Caravan',
id: document.getElementById("myObject").value
});
} else if (kenmerk == 'Auto') {
rect.set({
width: 70,
height: 40,
fill: '#bbb',
label: 'Auto',
id: document.getElementById("myObject").value
});
} else if (kenmerk == "Boot") {
rect.set({
width: 150,
height: 60,
fill: '#8d1',
label: 'Boot',
id: document.getElementById("myObject").value
});
}
canvas.add(rect);
rect.set({
label: kenmerk + ' ' + rect.width * 7 + ' cm',
rx: 8,
ry: 8
});
canvas.renderAll();
}
function saveCanvas() {
js = JSON.stringify(canvas.toDatalessJSON());
}
function loadCanvas() {
//window.alert(js);
canvas.clear();
canvas.loadFromDatalessJSON(js);
canvas.renderAll();
}