I'm working on a paint application and I'm trying to centre the canvas onto the middle of the screen . Any attempts I made the detection was off(still at the top left of the screen) but it was visually appearing in the centre of the screen.
Basically it wont draw onto the canvas when I moved it to the centre of the screen.
Any help would be much appreciated , Thanks....
I HAVE MY CODE BELOW ...
It's not clear from your question how you're centring it, but you need to account for any offset of elements which contain your canvas when you attempt to map the mouse position to a position on the canvas. You can do this by including the offsetLeft and offsetTop values (see docs) of the containing element when you do your calculations.
The following will work if you're offsetting the position of the div which wraps the canvas (which I've given an id to make it easier to reference):
function move(e) {
// Get the div containing the canvas. Would be more efficient to set this once on document load
var container = document.getElementById('container');
if((e.button == 0) && (mouseIsDown)) {
g.beginPath();
document.onselectstart = function(){ return false; }
//g.fillStyle = "red";
// Account for the offset of the parent when drawing to the canvas
g.arc((e.x - container.offsetLeft) - brush, (e.y - container.offsetTop) - brush, brush, 0, Math.PI * 2);
g.fill();
g.closePath();
}
}
And a simplistic demo using your fiddle here.
Related
I am taking help of sample code of Transform tutorial for rotation and position change. I am facing couple of problems.
I want to perform rotation on door and window. Currently axis of rotation pass through center. How can I change to rotate a object from axis passing through its side.
For position change > when I change position lets say for a window in any direction, it moves but it is visible on wall. I want it hide when window collide with wall.
1/ Here is a code snippet that illustrates how to rotate elements (fragments), for a more complete sample take a look at this article: Rotate Components Control for the Viewer
rotateFragments (model, fragIdsArray, axis, angle, center) {
var quaternion = new THREE.Quaternion()
quaternion.setFromAxisAngle(axis, angle)
fragIdsArray.forEach((fragId, idx) => {
var fragProxy = this.viewer.impl.getFragmentProxy(
model, fragId)
fragProxy.getAnimTransform()
var position = new THREE.Vector3(
fragProxy.position.x - center.x,
fragProxy.position.y - center.y,
fragProxy.position.z - center.z)
position.applyQuaternion(quaternion)
position.add(center)
fragProxy.position = position
fragProxy.quaternion.multiplyQuaternions(
quaternion, fragProxy.quaternion)
if (idx === 0) {
var euler = new THREE.Euler()
euler.setFromQuaternion(
fragProxy.quaternion, 0)
this.emit('rotate', {
dbIds: this.selection.dbIdArray,
fragIds: fragIdsArray,
rotation: euler,
model
})
}
fragProxy.updateAnimTransform()
})
}
2/ When you transform the geometry, you are just moving triangles around, there is no built-in logic that will hide components because they overlap, you will need to implement that yourself. You should be able to find Three.js code that computes if two meshes intersect (triangle-triangle intersection algorithm) and run that against the component you are moving and all walls that are around. Here is something that can put you on tracks: How to detect collision in three.js?
Hope that helps
I like the Polymer paper elements and I want to use a paper-slider element.
However, i would like it to be vertical. I've tried to apply css to rotate it;
transform: rotate(90deg);
This rotates the slider, but not the "input"; one must still click and drag the mouse horizontally in order to get the "knob" to move up and down.
This is very annoying and any help is rely appreciated!
tk-vslider is a tweaked paper-slider with rotate functionality. Use this instead of paper-slider to solve this issue. Install using bower "tkvslider": "0.5.5"
<tk-vslider rotate="true"></tk-vslider>
Tweaks.
if rotate == true then
div#sliderContainer is css rotated by 90deg
Event on-trackx of the div#sliderKnob is replaced by on-track
In the method tracktake e.dy instead of e.dx.
This might be a pretty hacky way to do it, but we're coming up a year since you requested this as feature and it doesn't look like it's much of a priority yet. I figure this will (for the most part) allow for continued updates of paper-slider from the Polymer team without depending on third parties that might not continue support (from what I can tell, the custom element tk-vslider mentioned here hasn't been updated to support Polymer 1.0).
First, the css. I found that if I rotated 90 degrees, the smaller values were at the top of the slider, which I found to be counter-intuitive. So instead I rotate by -90. Some weird stuff happens with the margins but this is what finally did it for me:
paper-slider {
width: 20vh;
margin: 10vh -10vh;
--webkit-transform: rotate(-90deg);
transform: rotate(-90deg);
}
I had my paper-slider inside my own custom element, so I put the following code in the ready callback, but I imagine you could put it anywhere you needed, as long as you can select the slider element. We're basically just going to override the method that paper-slider uses to respond to drag events. Here's how:
var slider = this.$.slider;
slider._trackX = function(e) {
if (!slider.dragging) {
slider._trackStart(e);
}
var dx = Math.min(slider._maxx, Math.max(slider._minx, (-1 * e.detail.dy)));
slider._x = slider._startx + dx;
var immediateValue = slider._calcStep(slider._calcKnobPosition(slider._x / slider._w));
slider._setImmediateValue(immediateValue);
// update knob's position
var translateY = ((slider._calcRatio(immediateValue) * slider._w) - slider._startx);
slider.translate3d(translateY + 'px', 0, 0, slider.$.sliderKnob);
};
Almost the entirety of this method is copied over from paper-slider source code, the only real change is that instead of grabbing the x coordinate in e.detail.dx we grab the y in e.detail.dy. The negative multiplier is only necessary if you want smaller values at the bottom of your slider, and you rotated your paper-slider by -90 degrees. Note that if the Polymer team ever changes the name of the method _trackX, it'll break this solution. I know this is a bit late but hopefully it'll help anyone else finding themselves in a similar situation (as I did).
UPDATE: Probably should have tested this solution a bit more, turns out there's another function that needs to be overwritten to handle click events (the other one only handles drag). I got it to work by adding this below my other method:
slider._bardown = function(event) {
slider._w = slider.$.sliderBar.offsetWidth;
var rect = slider.$.sliderBar.getBoundingClientRect();
var ratio = ((rect.bottom - event.detail.y) / slider._w);
var prevRatio = slider.ratio;
slider._setTransiting(true);
slider._positionKnob(ratio);
slider.debounce('expandKnob', slider._expandKnob, 60);
// if the ratio doesn't change, sliderKnob's animation won't start
// and `_knobTransitionEnd` won't be called
// Therefore, we need to manually update the `transiting` state
if (prevRatio === slider.ratio) {
slider._setTransiting(false);
}
slider.async(function() {
slider.fire('change');
});
// cancel selection
event.preventDefault();
}
The main change to this method is the line that calculates the ratio. Before it was var ratio = (event.detail.x - rect.left) / this._w;
<s-slider> has vertical property for vertical orientation https://github.com/StartPolymer/s-slider
zberry's answer didnt work for me anymore. However, I took his answer and updated it. The Polymer3 solution to make the paper-slider vertically responsive would look like this (given the same CSS zberry used):
let slider = this.shadowRoot.querySelector('paper-slider');
slider._trackX = function(event) {
if (!slider.dragging) {
slider._trackStart(event);
}
var dx =
Math.min(slider._maxx, Math.max(slider._minx, -1 * event.detail.dy));
slider._x = slider._startx + dx;
var immediateValue =
slider._calcStep(slider._calcKnobPosition(slider._x / slider._w * 100));
slider._setImmediateValue(immediateValue);
// update knob's position
var translateX =
((slider._calcRatio(slider.immediateValue) * slider._w) -
slider._knobstartx);
slider.translate3d(translateX + 'px', 0, 0, slider.$.sliderKnob);
};
slider._barclick = function(event) {
slider._w = slider.$.sliderBar.offsetWidth;
var rect = slider.$.sliderBar.getBoundingClientRect();
var ratio = (rect.bottom - event.detail.y) / slider._w * 100;
if (slider._isRTL) {
ratio = 100 - ratio;
}
var prevRatio = slider.ratio;
slider._setTransiting(true);
slider._positionKnob(ratio);
// if the ratio doesn't change, sliderKnob's animation won't start
// and `_knobTransitionEnd` won't be called
// Therefore, we need to manually update the `transiting` state
if (prevRatio === slider.ratio) {
slider._setTransiting(false);
}
slider.async(function() {
slider.fire('change', {composed: true});
});
// cancel selection
event.preventDefault();
// set the focus manually because we will called prevent default
slider.focus();
};
If you want to slide from top to down you have to fiddle with the directions
I am working on custom product designer which uses Fabric.js. I want to rotate all objects of canvas at once by pressing one button (rotate left, rotate right).
I have achieved this using this code :
stage.forEachObject(function(obj){
obj.setAngle(rotation).setCoords();
});
stage.renderAll();
But it has one bug that every element rotates with its own center point. I want that every element rotates with respect to whole canvas element.
Grouping and rotating the group did not work so well for me. Here is another solution based on this js fiddle.
rotateAllObjects (degrees) {
let canvasCenter = new fabric.Point(canvas.getWidth() / 2, canvas.getHeight() / 2) // center of canvas
let radians = fabric.util.degreesToRadians(degrees)
canvas.getObjects().forEach((obj) => {
let objectOrigin = new fabric.Point(obj.left, obj.top)
let new_loc = fabric.util.rotatePoint(objectOrigin, canvasCenter, radians)
obj.top = new_loc.y
obj.left = new_loc.x
obj.angle += degrees //rotate each object buy the same angle
obj.setCoords()
});
canvas.renderAll()
},
You could add all the objects to a group an then rotate the group. This way you can also set the center for rotation.
This is how it could be solved
function rotate(a) {
var group = new fabric.Group(canvas.getObjects());
//angle is var with scope out of this function,
//so you can use this function as rotate(90) and keep rotating
angle = (angle + a) % 360;
group.rotate(angle);
canvas.centerObject(group);
group.setCoords();
canvas.renderAll();
}
FabricJS rotate everything and maintain the relative position also.
You can download the files here - https://drive.google.com/file/d/1UV1nBdfBk6bg9SztyVoWyLJ4eEZJgZRf/view?usp=sharing
I have to move some pictures in my flash. So I have got a background image in my main MovieClip(which I get by Loader class). Inside the image I have rectangles. I'm going to put small image in this rectangle and move it. I need the small image slowly disappear while crossing the rectangle boundaries.
I tried to put another movieclip in rectangles and moved image in this movieclip. But while crossing the rectangle the image didnt disappear. The image just continued its motion without disappearing.
How can I make dissapearing of image while crossing rectangle boundaries?
Sorry for my English.
Get TweenLite. It's an animation "tweening" library that makes animation a breeze. There are others, but this is the one I use.
It depends on the methodology you employ to move and detect your overlaps of image & rectangles.
Let's imagine you have two squares (red square, and blue square) and you want red square to fade-out whenever it overlaps blue square. Is this controlled with the mouse, keyboard, or a pre-calculated move that performs a guaranteed eclipse? Is the fade a factor of the percentage of overlap, or a straight-up 0-to-100 timed transition the moment it comes in contact with blue square? It's not clear from the description you gave as to what exactly you expect your code to do. Please review SO's "Asking" section, to help improve the quality of your question so that you get the right answer you're looking for.
That said, here's one way you could resolve the issue:
import com.greensock.*;
// Create some sample red & blue squares
var red:Sprite = new Sprite();
red.graphics.beginFill(0xFF0000, 1);
red.graphics.drawRect(0, 0, 100, 100);
red.graphics.endFill();
addChild(red);
stage.addEventListener(MouseEvent.MOUSE_MOVE, updateRed);
var blue:Sprite = new Sprite();
blue.graphics.beginFill(0x0000FF, 1);
blue.graphics.drawRect(0, 0, 100, 100);
blue.graphics.endFill();
addChild(blue);
blue.x = 200;
blue.y = 100;
var overlap:Boolean = false; // global state tracker
function updateRed(e:MouseEvent):void {
// Position the red square every time the mouse moves
red.x = stage.mouseX - red.width/2; // center relative to red square's dimensions
red.y = stage.mouseY - red.height/2;
if (red.hitTestObject(blue) && overlap != true) {
// Make sure we only animate on the initial overlap
overlap = true;
TweenLite.to(red, 1, {alpha:0});
} else if (red.hitTestObject(blue) == false && overlap) {
// And converserly, on the initial exit
overlap = false;
TweenLite.to(red, 1, {alpha:1});
}
}
My website's landing page (http://www.chrisamaddeo.com/) has a full screen background. I want to make it move like an example of this website's header (http://www.kaiserair.com/) I have this code, HTML, which goes in the head of my website:
<!DOCTYPE html>
<html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<script>
$(document).ready(function() {
var movementStrength = 25;
var height = movementStrength / $(window).height();
var width = movementStrength / $(window).width();
$("#top-image").mousemove(function(e){
var pageX = e.pageX - ($(window).width() / 2);
var pageY = e.pageY - ($(window).height() / 2);
var newvalueX = width * pageX * -1 - 50;
var newvalueY = height * pageY * -1 - 25;
$('#top-image').css("background-position", newvalueX+"px "+newvalueY+"px");
});
I have this code, css and it doesn't work:
#top-image {
background:url('https://d3ui957tjb5bqd.cloudfront.net/images/screenshots/products/0/8/8905/red-rocks-park-o.jpg' -50px -25px;
position:fixed ;
top:0;
width:100%;
z-index:0;
}
My website is hosted with weebly and their html is a little different
Actually, i've just tried copying your code:
http://codepen.io/chrisboon27/pen/rEDIC
It does work, in that it moves the image.
I did have to add some some closing braces to your jQuery but maybe you just missed those when you pasted the code into this question.
Also, I looked at your site and noticed you are currently using background-size:cover. This takes your bg image and makes it fit within the div - you dont want that as you want some bg extending beyond the div - so i'n the css in the example I linked to you can see I used calc to make the bg-image size to 100% width + 50px. I used 50px as your code currently moves the background image position by up to 25px left or right, therefore you need it to be 50px total wider than the div.
EDIT:
If you use calc you should include a -webkit prefixed version too (unless you are using prefix-free or prefixr to add prefixes. Here is browser support: http://caniuse.com/calc
If you need to support more browsers you will need to set background-size via javascript
I'm finding that quite hard to follow without recreating it and seeing where those numbers come from. However I recently made something very similar with jQuery for someone else except it moves an img within a div. It probably wouldn't take much to switch it to move a background image though (though finding out the bg-image dimensions would be tricky - you might be better hard coding them in that instance).
html:
<div class="container"><img src="foo.jpg" class="draggable"/>
</div>
jQuery:
//for each item
$(".container").each(function(){
//get the container width
var conWidth = $(this).width();
//and its height
var imgHeight = $(this).find("img").height();
//get the nested img width
var conHeight = $(this).height();
//and its height
var imgWidth = $(this).find("img").width();
//figure out how much of the image is not visible horizontally
var excessWidth = imgWidth - conWidth;
//and how much is not visible vertically
var excessHeight = imgHeight - conHeight;
//how far is this container from the left of the page
var containerPositionLeft = this.offsetLeft;
//and from the top
var containerPositionTop = this.offsetTop;
//when moving mouse over container
$(this).mousemove(function(e){
//figure out how many pixels the mouse is from the left edge of the page
var mouseoffLeftPage = e.pageX;
//and how many from the top edge of the page
var mouseoffTopPage = e.pageY;
//figure out how many pixels the mouse is from the left edge of the page
var mouseoffLeftPx = mouseoffLeftPage - containerPositionLeft;
//and how many from the top edge of the page
var mouseoffTopPx = mouseoffTopPage - containerPositionTop;
//figure out the distance the mouse is from the left edge as a percentage (kind of - all the way to the right equals 1 not 100)
var mouseoffLeftPercent = mouseoffLeftPx/conWidth;
//do the same for height
var mouseoffTopPercent = mouseoffTopPx/conHeight;
//times the 'percentage' value by the amount of image hidden - so if your conatiner is 200px wide, your image 300px wide nd your mouse is half way across this value would be 0.5*100 which would give you 50 - which is exactly half the amount of image that is missing.
//note this gets set as a minus value as we will be using a minus number to shift the image around.
var setnewWidth = -(mouseoffLeftPercent * excessWidth);
//do the same for the height
var setnewHeight = -(mouseoffTopPercent * excessHeight);
//add the values as css (using transform(translate) as it's more performant and does subpixel rendering so looks smoother [or does it? it does in animations but seems as my js is not technically animating it it might not make a difference in that respect] - could set the top,left version as fallback for unsupporting browsers but ie9 supports transforms anyway so i dont care.)
$(this).find("img").css({"transform" : "translate("+ setnewWidth+"px ,"+setnewHeight+"px)" });
//$(this).find("img").css({"left" : setnewWidth+"px", "top" : setnewHeight+"px" });
});
});
Not a direct answer to what isn't working in your code, but shows an example (with comments on what is happening) of how it can be done - note that my version doesn't rely on you knowing any of the widths or heights of objects and can run on multiple items on one page - also it doesn't have to be placed at the very top of the page. It does assume the image is larger than its container though - if it isn't larger the image just moves around within it.
You could reduce the number of variables by doing more calculations in a row, I just wanted it to be as easy to read the logic as possible.
DEMO:
http://codepen.io/chrisboon27/pen/BhkJq
Simpler than that, you can just make sure the CSS position is set to "fixed" so wherever you are on the page it's always 0px from the top.