Hello my dear fellows,
I've been trying to recreate the effect: image scales up as the mouse get closer to the center of the image found on https://www.davidwilliambaum.com/
I have been very unsuccessfull so far, as I am not sure how to approach the problem.
I started a codepen with some ideas : https://codepen.io/dindon-studio/pen/RwLwRKM
As you can see I first get the center coordinate of the image, and then i try some dirty formula to scales it up with the mouse distance.
But it is very buggy and not convincing at all.
Does anyone got a better approach?
Deep thanks for you help!
var mX, mY, distance, element
element = $('.project')
function calculateDistance(elem, mouseX, mouseY) {
return Math.floor(Math.sqrt(Math.pow(mouseX - (elem.offset().left+(elem.width()/2)), 2) + Math.pow(mouseY - (elem.offset().top+(elem.height()/2)), 2))); }
$(document).mousemove(function(e) {
mX = e.pageX;
mY = e.pageY;
distance = calculateDistance(element, mX, mY);
if (distance< 500 && distance >50){
var scaling = 1 + (1/distance) *100
gsap.to(".project", {duration: 0.01, scale: scaling,ease: "power2.in",});
}
});
I build off from your codepen and made some adjustments: https://codepen.io/Mookiie/pen/qBPBmNe
The higher the scalingFactor the closer the mouse needs to be for a size change.
function calculateCenter(image) {
var rect1 = image.getBoundingClientRect();
var x = rect1.left + rect1.width * 0.5;
var y = rect1.top + rect1.height * 0.5;
return { x: x, y: y }
}
function getDistance(x1, y1, x2, y2){
let y = x2 - x1;
let x = y2 - y1;
return Math.sqrt(x * x + y * y);
}
function distanceFromCenter(image, mouseX, mouseY) {
var imageCenter = calculateCenter(image);
return getDistance(imageCenter.x, imageCenter.y, mouseX, mouseY)
}
function adjustImage(image, mX, mY) {
var distance = distanceFromCenter(image, mX, mY);
const baseScale = 1
const maxScaling = 1.5;
const scalingFactor = 1;
const adjustedScaling = maxScaling - ((distance / 1000) * scalingFactor)
const scaling = adjustedScaling >= baseScale ? adjustedScaling : baseScale
gsap.to(image, {duration: 0.01, scale: scaling, ease: "power2.in",});
}
$(document).mousemove(function(e) {
const mX = e.pageX;
const mY = e.pageY;
const images = $("img")
images.each(function() {
adjustImage(this, mX, mY)
})
});
Related
I am trying to use the HTML5 canvas features. I set up a rectangle on the canvas and it is rotated. It is not returning back a true when I click inside the rotated rectangle. Perhaps I am just tripping up on understanding the solution. What am I doing incorrectly? I have the code below.
I am using the solution referenced in:
Mouse position within rotated rectangle in HTML5 Canvas
<?php
$canvas_width=800;
$canvas_height=1336;
echo <<<_END
<canvas id="myCanvas" width=$canvas_width height=$canvas_height style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.
</canvas>
<script>
//Get the canvas element by using the getElementById method.
canvas = document.getElementById('myCanvas');
HEIGHT = canvas.height;
WIDTH = canvas.width;
CANVAS_LEFT = 9;
CANVAS_RIGHT = canvas.width+CANVAS_LEFT;
CANVAS_TOP = 9;
CANVAS_BOTTOM = canvas.height+CANVAS_TOP;
lastMouseX = 0; // The last seen mouse X coordinate
lastMouseY = 0; // the last seen mouse Y coordinate
rectangleDrawAndRotated=false;
mouseX =0;
mouseY=0;
offsetX = 0;
offsetY = 0;
originX=0;
originY=0;
width=0;
height=0;
//Get a 2D drawing context for the canvas.
ctx = canvas.getContext('2d');
myimage=new Image()
myimage.src='/Farm_planner/images/The_Farm_at_Dover_Vineyards_Google_Maps.png'
myimage.onload=function()
{
ctx.drawImage(myimage,1,1,800,1336)
}
// When true, moving the mouse draws on the canvas
isDrawing = false;
x = 0;
y = 0;
// event.offsetX, event.offsetY gives the (x,y) offset from the edge of the canvas.
// Add the event listeners for mousedown, mousemove, and mouseup
canvas.addEventListener('mousedown', e => {
x = e.offsetX;
y = e.offsetY;
isDrawing = true;
console.log("mouse down",x,y,width,height);
if (rectangleDrawAndRotated ===true){
originX = x + width/2;
originY = y + height/2;
getMouse(e);
// get the locations of the mouse and assign to mouseX and mouseY
clickState=false;
console.log(clickState,mouseX, mouseY,x,y);
if (clickedOnRectangle(x,y)) clickState=true;
console.log(clickState,mouseX, mouseY,x,y);
}
});
canvas.addEventListener('mousemove', e => {
if (isDrawing === true) {
// drawLine(ctx, x, y, e.offsetX, e.offsetY);
// x = e.offsetX;
// y = e.offsetY;
}
});
window.addEventListener('mouseup', e => {
if (isDrawing === true) {
drawLine(ctx, x, y, e.offsetX, e.offsetY);
isDrawing = false;
mouseX =0;
mouseY=0;
rectangleDrawAndRotated=true;
console.log("mouse up",x,y,width,height);
}
});
function drawLine(ctx, x1, y1, x2, y2) {
// ctx.beginPath();
// ctx.strokeStyle = 'black';
ctx.lineWidth = 3;
// ctx.moveTo(x1, y1);
// ctx.lineTo(x2, y2);
// ctx.stroke();
// ctx.closePath();
width=x2-x1;
height=y2-y1;
xCoord=x1;
yCoord=y1;
drawRectangle(x1,y1,width,height) ;
rotateDrawing(x1,y1,width,height);
lastMouseX = 0; // The last seen mouse X coordinate
lastMouseY = 0; // the last seen mouse Y coordinate
}
function drawRectangle(xCoord,yCoord,width,height) {
// ctx.strokeRect(xCoord,yCoord,width,height);
ctx.rect(xCoord,yCoord,width,height);
originX = xCoord + width/2;
originY = yCoord + height/2;
r=45*(Math.PI / 180);
}
function clickedOnRectangle(x,y) {
// dtermine if the user clicked on the area of the rectangle that has been rotated
// Our origin of rotation is the center of the rectangle
// Our rectangle has its upper-left corner defined by x,y, its width
// defined in w, height in h, and rotation(in radians) in r.
// translate mouse point values to origin
dx = mouseX - originX;
dy = mouseY - originY;
// distance between the point and the center of the rectangle
var h1 = Math.sqrt(dx*dx + dy*dy);
var currA = Math.atan2(dy,dx);
// Angle of point rotated around origin of rectangle in opposition
var newA = currA - r;
// New position of mouse point when rotated
var x2 = Math.cos(newA) * h1;
var y2 = Math.sin(newA) * h1;
console.log(x,y,width,height,mouseX,mouseY,originX,originY,dx,dy,h1,currA,r,newA,x2,y2)
// Check relative to center of rectangle
if (x2 > -0.5 * width && x2 < 0.5 * width && y2 > -0.5 * height && y2 < 0.5 * height){
console.log('true');
return true;
}
}
// Sets mouseX and mouseY variables taking into account padding and borders
function getMouse(e) {
var element = canvas;
var offsetX = 0;
var offsetY = 0;
// Calculate offsets
if (element.offsetParent) {
do {
offsetX += element.offsetLeft;
offsetY += element.offsetTop;
} while ((element = element.offsetParent));
}
// Calculate the mouse location
mouseX = e.pageX - offsetX;
mouseY = e.pageY - offsetY;
// Calculate the change in mouse position for the last
// time getMouse was called
changeInX = mouseX - lastMouseX;
changeInY = mouseY - lastMouseY;
// Store the current mouseX and mouseY positions
lastMouseX = mouseX;
lastMouseY = mouseY;
}
function rotateDrawing(xCoord,yCoord,width,height)
{
ctx.setTransform(1,0,0,1,0,0);
ctx.translate(xCoord+.5*width,yCoord+.5*height );
r=45*(Math.PI / 180); // 45 degrees as radian
ctx.rotate(r); //
ctx.fillStyle = "red";
ctx.fillRect(-.5*width, -.5*height, width, height);
console.log(xCoord,yCoord,width,height)
}
</script>
_END;
Yes, you are tripping on the solution, treat your rectangle as a polygon and you don't have to worry about doing rotation, also you can have more complex shapes than rectangles.
I'm using the ray-casting algorithm:
https://github.com/substack/point-in-polygon/blob/master/index.js
With that, all we need to do is check if the mouse is inside the polygon, that is all.
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext("2d");
const rect = canvas.getBoundingClientRect();
const poly = [[89, 9], [13, 19], [19, 56], [98, 36], [89, 9]]
function draw(p) {
p.map(x => ctx.lineTo(x[0], x[1]));
ctx.stroke();
}
function inside(p, vs) {
var inside = false;
for (var i = 0, j = vs.length - 1; i < vs.length; j = i++) {
var xi = vs[i][0], yi = vs[i][1];
var xj = vs[j][0], yj = vs[j][1];
var intersect = ((yi > p[1]) != (yj > p[1])) && (p[0] < (xj - xi) * (p[1] - yi) / (yj - yi) + xi);
if (intersect) inside = !inside;
}
return inside;
};
draw(poly)
canvas.addEventListener('mousemove', function(evt) {
ctx.clearRect(100, 0, canvas.width, canvas.height);
let x = inside([ evt.clientX - rect.left, evt.clientY - rect.top ], poly)
ctx.fillText(x, 110, 20);
}, false);
<canvas id="canvas"></canvas>
I did it on mousemove so you can see the change right away...
but same can be applied to any event you like
I am trying to troubleshoot some of the performance issues I am encountering in a simple pixel painter app I am making. When the mouse is held down and a div is being hovered over, that div should change its background color. Which it does! The issue is that when moving the mouse rapidly certain divs are skipped along semi-regulars intervals. This suggests to me some sort of sampling problem.
I would be interested in knowing what the maximum frequency of event firings are for a web browser and whether this is specified in some standard (related to, say, ES6).
The situation for those who are interested:
More likely is that your painting code is still running when the next event comes in and that is dragging down your cpu. You need to cache just the mouse enter in the handler, and then do the painting work asynchronously to the events. Co-operative multitasking style.
As far as I know there is not any standard for the rate at wich the events can be fired. As what I experienced that depends on a lot of factors incuding the current users machine power.
Look, I made the drawing in this canvas of two lines of dots at a fixed Y position and at the current X position. The upper one was updated whith a while loop as frequent as the script could, the other one was drawn with the mouseMoved event. As you can see, the result is pretty much the same (even the dots in the MouseMove one are sometimes more often)
dots frecuency comparison
The time it takes for the event handler affects a lot, in fact I made the method to wait 1 second and then draw and the result was dots spaced for 5cm moving the mouse at the same speed.
So while the cpu is busy in an event handler it's more likely to not attend to new event triggers. My only recomendation is to stop the event propagation so it does not consume any resources and return false so the browser does not do any default behaviour.
Using a <canvas> can help you achieve a smoother behavior:
const scale = window.devicePixelRatio || 1;
const unit = 8;
const scaledUnit = unit * scale;
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const offsetLeft = canvas.offsetLeft;
const offsetTop = canvas.offsetTop;
let drawing = false;
canvas.setAttribute('width', canvas.offsetWidth * scale);
canvas.setAttribute('height', canvas.offsetHeight * scale);
canvas.onmousedown = (e) => {
drawing = true;
paintPixel(Math.floor((e.pageX - offsetLeft) / unit), Math.floor((e.pageY - offsetTop) / unit));
};
canvas.onmouseup = (e) => {
drawing = false;
};
canvas.onmousemove = (e) => {
if (drawing) {
paintPixel(Math.floor((e.pageX - offsetLeft) / unit), Math.floor((e.pageY - offsetTop) / unit));
}
};
canvas.onmouseleave = (e) => {
paint = false;
};
function paintPixel(x, y) {
ctx.fillRect(x * scaledUnit, y * scaledUnit, scaledUnit, scaledUnit);
}
body {
margin: 0;
font-size: 0;
}
#canvas {
width: 100%;
height: 100vh;
}
<canvas id="canvas"></canvas>
However, to completely avoid those gaps, you would have to draw a line from one cursor position to the next instead of painting an individual "pixel".
I would use Bresenham's line algorithm to calculate all the points between consecutive events. Something like this:
const scale = window.devicePixelRatio || 1;
const unit = 8;
const scaledUnit = unit * scale;
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const offsetLeft = canvas.offsetLeft;
const offsetTop = canvas.offsetTop;
let drawing = false;
let lastX = null;
let lastY = null;
canvas.setAttribute('width', canvas.offsetWidth * scale);
canvas.setAttribute('height', canvas.offsetHeight * scale);
canvas.onmousedown = (e) => {
drawing = true;
lastX = Math.floor((e.pageX - offsetLeft) / unit);
lastY = Math.floor((e.pageY - offsetTop) / unit);
paintPixel(lastX, lastY);
};
canvas.onmouseup = (e) => {
drawing = false;
};
canvas.onmousemove = (e) => {
if (drawing) {
const x = Math.floor((e.pageX - offsetLeft) / unit);
const y = Math.floor((e.pageY - offsetTop) / unit);
const w = Math.abs(x - lastX);
const h = Math.abs(y - lastY);
if (w === 0 && h === 0) {
paintPixel(x, y);
} else if (w > h) {
lineLandscape(lastX, lastY, x, y);
} else {
linePortrait(lastX, lastY, x, y);
}
lastX = x;
lastY = y;
}
};
canvas.onmouseleave = (e) => {
paint = false;
};
function paintPixel(x, y) {
ctx.fillRect(x * scaledUnit, y * scaledUnit, scaledUnit, scaledUnit);
}
function lineLandscape(x0, y0, x1, y1) {
if (x0 > x1) {
[x0, x1] = [x1, x0];
[y0, y1] = [y1, y0];
}
const dx = x1 - x0;
const dy = Math.abs(y1 - y0);
const yi = y0 > y1 ? -1 : 1;
let D = 2 * dy - dx;
let y = y0;
for (let x = x0; x <= x1; ++x) {
paintPixel(x, y);
if (D > 0) {
y += yi;
D -= 2 * dx;
}
D += 2 * dy;
}
}
function linePortrait(x0, y0, x1, y1) {
if (y0 > y1) {
[x0, x1] = [x1, x0];
[y0, y1] = [y1, y0];
}
const dx = Math.abs(x1 - x0);
const dy = y1 - y0;
const xi = x0 > x1 ? -1 : 1;
let D = 2 * dx - dy;
let x = x0;
for (let y = y0; y <= y1; ++y) {
paintPixel(x, y);
if (D > 0) {
x += xi;
D -= 2 * dy;
}
D += 2 * dx;
}
}
body {
margin: 0;
font-size: 0;
}
#canvas {
width: 100%;
height: 100vh;
}
<canvas id="canvas"></canvas>
You can also adapt that algorithm to work with your approach if you really need to use <div>s.
I'm trying to create a smooth brush in HTML5, an example is below.
This is what I tried, it's something. But it's not as smooth as the image above.
Editor.Drawing.Context.globalAlpha = 0.3;
var amount = 3;
for(var t = -amount; t <= amount; t += 3) {
for(var n = -amount; n <= amount; n += 3) {
Editor.Drawing.Context.drawImage(Editor.Drawing.ClipCanvas, -(n-1), -(t-1));
}
}
And it looks like this.
Using brushes
Choose a brush, this can be an image with predefined brushes or you can make one using an off-screen canvas and draw a radial gradient into it. For simplicity I made a simple image brush such as these:
Then for each new point drawn to the canvas:
Calculate the diff between the previous and current point
Calculate the length of the line so we can use an absolute step value independent of length
Iterate over the length using a normalized value and the previously calculated step value
The step value can be anything that looks good as a result - it largely depends on the smoothness of the brush as well as its general size (smoother brushes will require smaller steps to blend into each other).
For this demo I used brush-width, the smaller values that are used, the more brushes will be drawn along the line, nicer result, but can also slow down the program, so find a value that compromises quality and speed.
For example:
This will be called every time a new point is registered when drawing:
function brushLine(ctx, x1, y1, x2, y2) {
var diffX = Math.abs(x2 - x1), // calc diffs
diffY = Math.abs(y2 - y1),
dist = Math.sqrt(diffX * diffX + diffY * diffY), // find length
step = 20 / (dist ? dist : 1), // "resolution"
i = 0, // iterator for length
t = 0, // t [0, 1]
b, x, y;
while (i <= dist) {
t = Math.max(0, Math.min(1, i / dist));
x = x1 + (x2 - x1) * t;
y = y1 + (y2 - y1) * t;
b = (Math.random() * 3) | 0;
ctx.drawImage(brush, x - bw * 0.5, y - bh * 0.5); // draw brush
i += step;
}
}
Demo
var brush = new Image();
brush.onload = ready;
brush.src = "//i.stack.imgur.com/HsbVA.png";
function ready() {
var c = document.querySelector("canvas"),
ctx = c.getContext("2d"),
isDown = false, px, py,
bw = this.width, bh = this.height;
c.onmousedown = c.ontouchstart = function(e) {
isDown = true;
var pos = getPos(e);
px = pos.x;
py = pos.y;
};
window.onmousemove = window.ontouchmove = function(e) {
if (isDown) draw(e);
};
window.onmouseup = window.ontouchend = function(e) {
e.preventDefault();
isDown = false
};
function getPos(e) {
e.preventDefault();
if (e.touches) e = e.touches[0];
var r = c.getBoundingClientRect();
return {
x: e.clientX - r.left,
y: e.clientY - r.top
}
}
function draw(e) {
var pos = getPos(e);
brushLine(ctx, px, py, pos.x, pos.y);
px = pos.x;
py = pos.y;
}
function brushLine(ctx, x1, y1, x2, y2) {
var diffX = Math.abs(x2 - x1),
diffY = Math.abs(y2 - y1),
dist = Math.sqrt(diffX * diffX + diffY * diffY),
step = bw / (dist ? dist : 1),
i = 0,
t = 0,
b, x, y;
while (i <= dist) {
t = Math.max(0, Math.min(1, i / dist));
x = x1 + (x2 - x1) * t;
y = y1 + (y2 - y1) * t;
b = (Math.random() * 3) | 0;
ctx.drawImage(brush, x - bw * 0.5, y - bh * 0.5);
i += step
}
}
}
body {background: #777}
canvas {background: #fff;cursor:crosshair}
<canvas width=630 height=500></canvas>
You can use this technique to simulate a variety of brushes.
Tip: with a small modification you can also variate the width depending on velocity to increase realism (not shown).
I have a JSfiddle set up here. I'm drawing a canvas grid and want to allow a user to select a color and 'paint' the grid cells like pixel art. Can someone point me in the right direction?
http://jsfiddle.net/g51bx1nb/
var c_canvas = document.getElementById("c");
var context = c_canvas.getContext("2d");
for (var x = 0.5; x < 501; x += 20) {
context.moveTo(x, 0);
context.lineTo(x, 381);
}
for (var y = 0.5; y < 381; y += 20) {
context.moveTo(0, y);
context.lineTo(500, y);
}
context.strokeStyle = "#ddd";
context.stroke();
Well this should get you closer.
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
function getNearestSquare(position) {
var x = position.x;
var y = position.y;
if (x < 0 || y < 0) return null;
x = (Math.floor(x / 20) * 20) + 0.5
y = (Math.floor(y / 20) * 20) + 0.5
return {x: x, y: y};
}
$(c_canvas).click(function(evt) {
var pos = getNearestSquare(getMousePos(c_canvas, evt));
if (pos != null) {
context.fillStyle="#FF0000";
context.fillRect(pos.x,pos.y,20,20);
}
});
I tried this out on your fiddle, adding this JS code gives you an on click event that'll let you click and paint an area the size of one of your squares red, you just need to use the fill style as a variable that the user can change.
Edit:
I added the logic to find the top left.
I have a simple sword image (drawn pointing up) that is in an 'open world' game setting, so the player can move around the world to all coordinates. I would like the sword to point at the mouse.
My issue (I think) is that the world coordinates and webpage coordinates do not match up. For example, the player could be at location (6000, 6000), while the mouse coordinates would only be between 0 and 1600 (or whatever the width of the screen is). On top of that, the webpage won't always exist in the same place.
Thoughts so far:
So I need to calculate the position of the mouse relative to the canvas, or vice versa.
Formula I was using. This worked in an older project of mine for XNA:
var xdir = mouse.x - swordcenter.x;
var ydir = mouse.y - swordcenter.y;
var theta = (Math.atan2( ydir, xdir ) - Math.PI/2.0) * (180.0/Math.PI);
I feel like the solution should be simpler than what I'm thinking, but no formula has been working so far. Any ideas?
So the question I suppose is why isn't this working? And my best guess is because of the difference in coordinates. I can't figure out how to factor it in.
Edit: I have figured out how to factor it in. With the following code, the mouse position is put in to game coordinates. So if the mouse hovers over the player, then the mouse pos and player pos are equal. However, the image still spins rapidly with the mouse movement.
document.addEventListener('mousemove', function(e){
mouse.x = e.clientX || e.pageX;
mouse.y = e.clientY || e.pageY;
var view = document.getElementById('viewport');
var rect = view.getBoundingClientRect();
mouse.x -= rect.left;
mouse.y -= rect.top;
var camX = clamp(x - canvas.width/2, -1000, 1000 - canvas.width);
var camY = clamp(y - canvas.height/2, -1000, 1000 - canvas.height);
mouse.x += camX;
mouse.y += camY;
}, false);
Edit 2: Here is how I get the angle:
var getAngle = function() {
var xdir = mouse.x - x;//where x and y are the sword center
var ydir = mouse.y - y;
var theta = Math.atan2( ydir, xdir ) * (180.0/Math.PI);
return theta;
}
Edit 3: Here is how I draw the image:
var draw = function(ctx) {
ctx.fillRect(x-15, y-15, 30, 30);//background player rect
ctx.save();
ctx.translate(x, y);//x and y is the center of the sword/player
ctx.rotate(getAngle());
//this correctly draws the sword on top of the player rect, except for rotation
ctx.drawImage(stanceTexture, -stanceTexture.width/2, -stanceTexture.height/2);
ctx.restore();
};
After all the additional math done to compute the correct "in-game" mouse location, it turns out that my canvas context wanted radians as well. Much confuse. Every other post I found regarding this turns the value back into degrees (WRONG) so I hope this helps someone else out. So here is the complete answer,
document.addEventListener('mousemove', function(e){
mouse.x = e.clientX || e.pageX;
mouse.y = e.clientY || e.pageY;
var view = document.getElementById('viewport');
var rect = view.getBoundingClientRect();
mouse.x -= rect.left;
mouse.y -= rect.top;
var camX = clamp(x - canvas.width/2, world.minX, world.maxX - canvas.width);
var camY = clamp(y - canvas.height/2, world.minY, world.maxX - canvas.height);
mouse.x += camX;
mouse.y += camY;
}, false);
var getAngle = function() {
var xdir = mouse.x - x;//where x and y are the sword center
var ydir = mouse.y - y;
//Note: I only subtract Math.PI/2 to flip the image 180 degrees.
// The value to subtract will depend on the original angle of your image
var theta = Math.atan2( ydir, xdir ) - Math.PI/2.0;
return theta;
}
var draw = function(ctx) {
ctx.fillRect(x-15, y-15, 30, 30);//background player rect
ctx.save();
ctx.translate(x, y);//x and y is the center of the sword/player
ctx.rotate(getAngle());
//this correctly draws the sword on top of the player rect, except for rotation
ctx.drawImage(stanceTexture, -stanceTexture.width/2, -stanceTexture.height/2);
ctx.restore();
};
You don't need trigonometry for that.
Basic vector calculus is enough:
const sword_length = 10;
var sword_x_start = 0;
var sword_y_start = 0;
var mouse_x = ...; // current mouse position
var mouse_y = ...;
var dx = (mouse_x - sword_x_start);
var dy = (mouse_y - sword_y_start);
// sword to mouse distance
var length = Math.sqrt( dx*dx + dy*dy );
// unit vector, see: http://en.wikipedia.org/wiki/Unit_vector
// in sword to mouse direction:
var unit_v_x = dx / length;
var unit_v_y = dy / length;
// and now coordinates of the sword pointing to mouse:
var sword_x_end = sword_x_start + unit_v_x * sword_length ;
var sword_y_end = sword_y_start + unit_v_y * sword_length ;