html 5 pattern repeat for canvas - html5-canvas

<canvas id="textureCanvas" width="3" height="1">what kind of cheap ass browser are you using? (I'm joking... something went wrong)</canvas>
window.onload = function () {
var mainCanvas = document.getElementById('mainCanvas');
var textureCanvas = document.getElementById('textureCanvas');
var mainContext = mainCanvas.getContext('2d');
var textureContext = textureCanvas.getContext('2d');
textureContext.fillStyle = 'grey';
textureContext.fillRect(0, 0, 1, 1);
textureContext.fillStyle = 'lightgrey';
textureContext.fillRect(1, 0, 1, 1);
textureContext.fillStyle = 'grey';
textureContext.fillRect(2, 0, 1, 1);
var pattern = mainCanvas.createPattern(textureCanvas, 'repeat');
mainCanvas.fillStyle = pattern;
mainCanvas.fillRect(0, 0, 198, 99);
};
I'm trying to use the first canvas as a pattern in the second canvas. It's an example from the Dummies guide. It's just a blank page that appears. I tried setting the background for the mainCanvas as green and it does show up. I guess I am a dummy.

The problem is that you are referring to mainCanvas and not mainContext when drawing on the mainCanvas. (I'm assuming you have a canvas element with and id of mainCanvas)
Change your code to:
var mainCanvas = document.getElementById('mainCanvas');
var textureCanvas = document.getElementById('textureCanvas');
var mainContext = mainCanvas.getContext('2d');
var textureContext = textureCanvas.getContext('2d');
textureContext.fillStyle = 'grey';
textureContext.fillRect(0, 0, 1, 1);
textureContext.fillStyle = 'lightgrey';
textureContext.fillRect(1, 0, 1, 1);
textureContext.fillStyle = 'grey';
textureContext.fillRect(2, 0, 1, 1);
var pattern = mainContext.createPattern(textureCanvas, 'repeat'); // <====
mainContext.fillStyle = pattern; // <====
mainContext.fillRect(0, 0, 198, 99); // <====
Example

Related

How to use line with width of three.js with morphTargets to animate one line moving to another

question reference
I want to implement an animation.
The animation should be a line move to another line. There will be some deformation in the process of the line moving
There is a correspondence between the points of the two lines.
I can use the basic line of three.js to animate one line moving to another.
<script type="module">
import * as THREE from '../../build/three.module.js'
import { OrbitControls } from '../jsm/controls/OrbitControls.js'
function main() {
var scene = new THREE.Scene()
const geometry = new THREE.BufferGeometry().setAttribute('position',
new THREE.Float32BufferAttribute([-2, 0, 0, -0.5, 0, -0.5, 0, 0, -2], 3))
const geometry1 = new THREE.BufferGeometry().setAttribute('position',
new THREE.Float32BufferAttribute([5, 0, 0, 1, 1, 1, 0, 0, 5], 3))
geometry.morphAttributes.position = [
geometry1.attributes.position,
]
var material = new THREE.LineBasicMaterial({
color: 0x0000ff,
})
var mesh = new THREE.Line(geometry, material)
mesh.morphTargetInfluences[0] = 0
scene.add(mesh)
/**
*
*/
var width = window.innerWidth
var height = window.innerHeight
var k = width / height
var s = 10
var camera = new THREE.OrthographicCamera(
-s * k,
s * k,
s,
-s,
-1500,
1500
)
camera.position.set(10, 10, 10)
camera.lookAt(10, 0, 0)
/**
*
*/
var renderer = new THREE.WebGLRenderer()
// window.renderer = renderer;
renderer.setSize(width, height)
renderer.setClearColor(0xb9d3ff, 1)
document.body.appendChild(renderer.domElement)
// renderer.render(scene, camera);
new OrbitControls(camera, renderer.domElement)
var clock = new THREE.Clock()
const axes = new THREE.AxesHelper(10)
scene.add(axes)
let flag = false
let index = 0
function render() {
renderer.render(scene, camera)
requestAnimationFrame(render)
if (index <0) {
flag = true
} else if (index > 1) {
flag = false
}
if (flag) {
index += 0.01
} else {
index -= 0.01
}
mesh.morphTargetInfluences[0] = index
console.log(flag, index)
}
render()
}
main()
</script>
Now I want to use the LineGeometry of three.js because this line has a width property. How to use the morphtargets with LineGeometry?
If the LineGeometry can't do it,any other bufferGeometry to replace LineGeometry?
Three.js 136.
<script type="module">
import * as THREE from '../../build/three.module.js'
import { OrbitControls } from '../jsm/controls/OrbitControls.js'
import { Line2 } from '../jsm/lines/Line2.js'
import { LineMaterial } from '../jsm/lines/LineMaterial.js'
import { LineGeometry } from '../jsm/lines/LineGeometry.js'
function main() {
var scene = new THREE.Scene()
const geometry2 = new LineGeometry()
geometry2.setPositions([-3, 0, 0, -0.5, 0, -0.5, 0, 0, -2])
console.log(geometry2)
const geometry1 = new LineGeometry()
geometry1.setPositions([-3, 0, 0, -1, 0, -1, 0, 0, -3])
geometry2.morphAttributes.position = [geometry1.attributes.position]
let matLine = new LineMaterial({
color: '#ffdb2d',
linewidth: 5, // in world units with size attenuation, pixels otherwise
})
let line = new Line2(geometry2, matLine)
line.morphTargetInfluences[0] = 0
scene.add(line)
/**
*/
var width = window.innerWidth
var height = window.innerHeight
var k = width / height
var s = 5
var camera = new THREE.OrthographicCamera(
-s * k,
s * k,
s,
-s,
-1500,
1500
)
camera.position.set(5, 5, 5)
camera.lookAt(5, 0, 0)
var renderer = new THREE.WebGLRenderer()
// window.renderer = renderer;
renderer.setSize(width, height)
renderer.setClearColor(0xb9d3ff, 1)
document.body.appendChild(renderer.domElement)
// renderer.render(scene, camera);
new OrbitControls(camera, renderer.domElement)
var clock = new THREE.Clock()
const axes = new THREE.AxesHelper(10)
scene.add(axes)
let flag = false
let index = 0
function render() {
renderer.render(scene, camera)
requestAnimationFrame(render)
if (index < 0) {
flag = true
} else if (index > 1) {
flag = false
}
if (flag) {
index += 0.01
} else {
index -= 0.01
}
line.morphTargetInfluences[0] = index
matLine.resolution.set(window.innerWidth, window.innerHeight) // resolution of the viewport
}
render()
}
main()
</script>
Use TubeGeometry:
const curve = new THREE.CatmullRomCurve3([new THREE.Vector3(-2, 0, 0), new THREE.Vector3(-0.5, 0, -0.5), new THREE.Vector3(0, 0, -2)])
var tubeGeometry = new THREE.TubeGeometry(curve, 100, 0.05, 50, false);
const curve1 = new THREE.CatmullRomCurve3([new THREE.Vector3(0, 0, 5,), new THREE.Vector3( 1, 1, 1,), new THREE.Vector3(5, 0, 0,)])
var tubeGeometry1 = new THREE.TubeGeometry(curve1, 100, 0.05, 50, false);
tubeGeometry.morphAttributes.position = [
tubeGeometry1.attributes.position,
]
var tubeMaterial = new THREE.MeshBasicMaterial({
side:THREE.DoubleSide,
color:'#ffffff',
});
var tube = new THREE.Mesh(tubeGeometry, tubeMaterial);
tube.morphTargetInfluences[0] = 0
scene.add(tube)
In the render function:
tube.morphTargetInfluences[0] += 0.01

SkiaSharp does not fill triangle with StrokeAndFill

I am trying to draw and fill a triangle. I referred an android - question How to draw filled triangle on android Canvas and did the following. It draws the triangle but it doesn’t fill it. How to get it filled? Also, is it possible to get it filled with a different color than the line color?
Xamarin Forms
private void OnPainting(object sender, SKPaintSurfaceEventArgs e)
{
var surface = e.Surface;
var canvas = surface.Canvas;
canvas.Clear(SKColors.White);
var pathStroke2 = new SKPaint
{
IsAntialias = true,
Style = SKPaintStyle.StrokeAndFill,
Color = new SKColor(244, 0, 110, 200),
StrokeWidth = 5
};
var path2 = new SKPath { FillType = SKPathFillType.EvenOdd };
path2.MoveTo(0, 0);
path2.LineTo(0, 140);
path2.MoveTo(0, 140);
path2.LineTo(140, 140);
path2.MoveTo(140, 140);
path2.LineTo(0, 0);
path2.Close();
canvas.DrawPath(path2, pathStroke2);
}
you don't need to use both LineTo() and MoveTo() - I suspect doing so is breaking the fill algorithm. Instead, just use
path2.MoveTo(0, 0);
path2.LineTo(0, 140);
path2.LineTo(140, 140);
path2.LineTo(0, 0);
path2.Close();
Removing unwanted MoveTo lines solved it, as per the comment from Jason.
Following is complete code.
private void OnPainting(object sender, SKPaintSurfaceEventArgs e)
{
var surface = e.Surface;
var canvas = surface.Canvas;
canvas.Clear(SKColors.White);
var w = e.Info.Width;
var h = e.Info.Height;
SKColor[] colors;
colors = new SKColor[] {
new SKColor(244, 0, 110, 200), new SKColor(244, 0, 110, 220),
new SKColor(244, 0, 110, 240),new SKColor(244, 0, 110, 240),
new SKColor(244, 0, 100,240),
new SKColor(244, 0, 100),
new SKColor(255, 0, 70)
};
SKShader shaderLeft = SKShader.CreateLinearGradient(new SKPoint(0, 0), new SKPoint(w, h), colors, null, SKShaderTileMode.Clamp);
var paint = new SKPaint() { Shader = shaderLeft };
canvas.DrawPaint(paint);
var path2 = new SKPath { FillType = SKPathFillType.EvenOdd };
path2.MoveTo(0, 0);
path2.LineTo(0, 140);
path2.LineTo(140, 140);
path2.LineTo(0, 0);
path2.Close();
var pathStroke2 = new SKPaint
{
IsAntialias = true,
Style = SKPaintStyle.StrokeAndFill,
Color = new SKColor(0, 0, 0, 30),
StrokeWidth = 5
};
using (var cf = SKColorFilter.CreateBlendMode(new SKColor(244, 0, 110, 200), SKBlendMode.DstIn))
{
var transparency = SKColors.White.WithAlpha(127);
pathStroke2.ColorFilter = cf;
// ... draw ...
canvas.DrawPath(path2, pathStroke2);
pathStroke2.ColorFilter = null;
}
var pathStroke3 = new SKPaint
{
IsAntialias = true,
Style = SKPaintStyle.StrokeAndFill,
Color = new SKColor(0, 0, 0, 30),
StrokeWidth = 5
};
var path3 = new SKPath { FillType = SKPathFillType.EvenOdd };
path3.MoveTo(170, 0);
path3.LineTo(170, 140);
path3.LineTo(300, 140);
path3.LineTo(170, 0);
path3.Close();
canvas.DrawPath(path3, pathStroke3);
}

Wrong location of texture on the second triangle of BufferGeometry square

I'm trying to add texture to a THREE.BufferGeometry. This is a working fiddle of what I'm accomplished so far.
This is my code:
var Test = new function () {
var scene = new THREE.Scene(),
camera = new THREE.PerspectiveCamera(10, window.innerWidth / window.innerHeight, 1, 1000),
renderer = new THREE.WebGLRenderer()
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true
camera.position.set(-5, 5, 5);
camera.rotation.order = 'YXZ';
camera.rotation.y = -Math.PI / 4;
camera.rotation.x = Math.atan(-1 / Math.sqrt(2));
scene.add(camera)
scene.add(new THREE.AmbientLight(0x222222));
var light = new THREE.PointLight(0xffffff, 0.7);
camera.add(light);
this.init = function () {
$('body').append(renderer.domElement);
Test.render();
}
this.render = function () {
requestAnimationFrame(Test.render);
renderer.render(scene, camera);
}
this.getScene = function getScene() {
return scene
}
}
var CreateSimpleMesh = new function () {
var grassGeometry = new THREE.BufferGeometry(),
grassVertexPositions = [],
imageArray = [
[0, 0],
[1, 0],
[1, 1],
[0, 1]
],
image = new Image()
this.init = function () {
image.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3wwLAi03pl5F1AAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAEkklEQVR42u3dTWzTdRzH8XfXdW03t3XPbmyMlLkNZA9kcwuKBBVBEjXEGDExEAwH44GDJpp4QYnCQcIZoiZGUaKeCFHjIBB5UnnSKW5zj7AVWvfvxsbWre22Dg+1SmHA/iwbHD7v2+/fZYfvK/+n9vCzrDmx7hrqvilBIxCIuk2JGsHsNth0hcvf9dB/1iBkBLFnOkgrc+HeWEr6oow7gwy1DuJt8NB/zs+oJ4DFmoAjx4GrMoviF92klqRryiY69dqxuHXICBIyghgnfFS/X0feyoLbg/y8+ccbjkwy0hNgpCfA5e+7qdxaS/6qQk16mrmWZFL4fDGZNTnYM+wEuodp2fUHg39eof2j5juDpJW7mLd2PlmP5ODMT2FyPMJIT4AL+9rpPeKlbXeTQExUv2dF/HwfclGxtYbjLx0i+PfonS9Zyz5ZGX/XtyWQXp7B4jer6D3iZWJkQlOe6Y3bGR178rwU8zf1ieAEwcsjXNjXDkD+ap0dM+3iVx0APDjFleaWIA3L98etnQXJlL6+mOL1JZroDPIe9HDhy3aSC1NY8HLJ3b+HjA2ECfeHQe/1M8I4/8E5rA4r1dvrsNqt0z9D1pxYF4UYGmPor0HadjfR/U0nWKB8S4WmazLPgYs072wEC1S+W0vqwvS7e1NPSksiuy6XpTvqAPAduqTpmr1nfN1B84eNcA0efnspuY/nz/xNfXI8eq2KjOopy0ydn7XS8XELAIvfqqbw2WJzX52cfeMk819wk74kE1uqjYnhcQabB2jf0xR90anM0pRNFMMAaN7ZGL1sXdcT364lyWW/NUj/GT/9Z/xT/nNbmo3yLUs05VnMcuPvIQPn+7l0oJsrv/oJ94VIsCXgLEghuz6XBetLsGc7NLXZfGm88UBGRRYZFbos3av0e4hAlEAEogQiECUQgSiBCEQJRAlEIEogAlECEYgSiECUQJRABKIEIhAlEIEogQhECUQJRCBKIAJRAhGIEohAlECUQASiBCIQJRCBKIEIRAlECUQgSiACUQIRiBKIQJRAlEAEogQiECUQgSiBCETdu6bcFGxyLELX3ja8P3gI+YM4cpwUPFOEe2MZCTYZmi3QPYxxzIdx3MfV5gHg/20JpwXy+7azGEd9/62DvlE6P20l0DVM9fY6TdhkJ185fPeXLP8vvRhHfViTE6nZtYxVh5+jZtcyrMmJ9B710nfa0IRNlrIglYWvlvHY50+aB/Ed9ADg3lBKdn0eVruV7Po83BtKAfA2eDRhky3/4ilKNi/iAXeaeZCrLYMA5DyaF3c8th5qGdCE5/IpK9wXBMBZEL/Xd2wd8oc0tbkEiYQiADftZBxbR8LaenVOQayO2OAj8VDhGFSipjaXIPZsZ/RR1zsSdzy2duRop885BUlf5Io+/v7UG/84/O86rdylqc0lSP7TRQB07W2j77TB5FiEvtMGXXvbop+vLtLUZrGbNicG+O2dUxjHfTf9ce6KfJbuqNfUTNawfP9tP7/+a5Qpv5iq2laLe1MZjjwnFqsFR54T96Yyqt6r1XTvxRmi7qN7iBKIEohA1DT7B5cwUaoY0hehAAAAAElFTkSuQmCC'
var texture = new THREE.Texture();
texture.image = image;
image.onload = function () {
texture.needsUpdate = true;
};
// first triangle
grassVertexPositions.push([0, 0, 0])
grassVertexPositions.push([1, 0, 0])
grassVertexPositions.push([0, 1, 0])
// second triangle
grassVertexPositions.push([1, 1, 0])
grassVertexPositions.push([0, 1, 0])
grassVertexPositions.push([1, 0, 0])
var grassVertices = new Float32Array(grassVertexPositions.length * 3),
normals = new Float32Array(grassVertexPositions.length * 3),
colors = new Float32Array(grassVertexPositions.length * 3),
uvs = new Float32Array(grassVertexPositions.length * 2)
for (var i = 0; i < grassVertexPositions.length; i++) {
var index = 3 * i
grassVertices[index + 0] = grassVertexPositions[i][0]
grassVertices[index + 1] = grassVertexPositions[i][1]
grassVertices[index + 2] = grassVertexPositions[i][2]
}
uvs[0] = imageArray[0][0]
uvs[1] = imageArray[0][1]
uvs[2] = imageArray[1][0]
uvs[3] = imageArray[1][1]
uvs[4] = imageArray[3][0]
uvs[5] = imageArray[3][1]
uvs[6] = imageArray[1][0]
uvs[7] = imageArray[1][1]
uvs[8] = imageArray[2][0]
uvs[9] = imageArray[2][1]
uvs[10] = imageArray[3][0]
uvs[11] = imageArray[3][1]
grassGeometry.addAttribute('position', new THREE.BufferAttribute(grassVertices, 3))
grassGeometry.addAttribute('normal', new THREE.BufferAttribute(normals, 3))
grassGeometry.addAttribute('color', new THREE.BufferAttribute(colors, 3))
grassGeometry.addAttribute('uv', new THREE.BufferAttribute(uvs, 2))
grassGeometry.computeVertexNormals()
//var textureLoader = new THREE.TextureLoader();
//textureLoader.load('/img/testface.png', function (texture) {
var grassMaterial = new THREE.MeshLambertMaterial({map: texture}),
grassMesh = new THREE.Mesh(grassGeometry, grassMaterial)
grassMesh.rotation.x = -Math.PI / 2;
Test.getScene().add(grassMesh)
var helper = new THREE.WireframeHelper(grassMesh, 0xff00ff); // alternate
helper.material.linewidth = 1;
Test.getScene().add(helper);
console.log(grassMesh.geometry.attributes)
//});
}
}
$(document).ready(function () {
Test.init()
CreateSimpleMesh.init()
});
The problem is that texture on first triangle of the rectangle is correct but on the second triangle something strange is happening with the texture.
This is how it should look like
This is how it look now
Try these texture coordinates (same as x and y of vertex coordinates):
uvs[0] = 0
uvs[1] = 0
uvs[2] = 1
uvs[3] = 0
uvs[4] = 0
uvs[5] = 1
uvs[6] = 1
uvs[7] = 1
uvs[8] = 0
uvs[9] = 1
uvs[10] = 1
uvs[11] = 0

Drawing custom shapes in Babylon.js

I have been searching all over the web for a way to draw custom 3d shapes in babylon.js. I would be grateful if somebody could provide a working example. For instance, a 3d irregular pentagon, triangle fan, or a wedge.
you can find a lot of info about parametric shapes in Babylon.js here:
http://doc.babylonjs.com/page.php?p=24847
And mainly for the ribbon here:
http://doc.babylonjs.com/page.php?p=25088
Here is a wedge using the ribbon object:
var createScene = function() {
var scene = new BABYLON.Scene(engine);
scene.clearColor = new BABYLON.Color3(0.8, 0.8, 0.8);
var camera = new BABYLON.ArcRotateCamera("Camera", 3 *Math.PI / 2, Math.PI / 2, 20, BABYLON.Vector3.Zero(), scene);
camera.attachControl(canvas, false);
// lights
var light = new BABYLON.HemisphericLight("hemi", new BABYLON.Vector3(0, 1, 0), scene);
light.groundColor = new BABYLON.Color3(0.2, 0.2, 0.5);
light.intensity = 0.6;
var light2 = new BABYLON.PointLight("light2", new BABYLON.Vector3(-20, 0, -20), scene);
light2.diffuse = BABYLON.Color3.White();
light2.specular = BABYLON.Color3.Green();
light2.intensity = 0.6;
// material
var mat = new BABYLON.StandardMaterial("mat1", scene);
mat.alpha = 1.0;
mat.diffuseColor = new BABYLON.Color3(0.5, 0.5, 1.0);
//mat.backFaceCulling = false;
mat.wireframe = true;
// tubular ribbon
path1 = [];
path2 = [];
path1.push( new BABYLON.Vector3(0, 0, 0) );
path2.push( new BABYLON.Vector3(0, 2, 0) );
path1.push( new BABYLON.Vector3(1, 0, 0) );
path2.push( new BABYLON.Vector3(1, 2, 0) );
path1.push( new BABYLON.Vector3(0, 0, 1) );
path2.push( new BABYLON.Vector3(0, 2, 1) );
var ribbon = BABYLON.Mesh.CreateRibbon("ribbon", [path1, path2], false, true, 0, scene);
ribbon.material = mat;
scene.registerBeforeRender(function(){
light2.position = camera.position;
});
return scene;};

Bitmap too small for its content

I'm creating graphics by the code and placing them into a Bitmap. But they are higher than this Bitmap container.
import flash.display.*;
function getLine(){
var containerWidh:Number =enter code here 300;
var containerHeight:Number = 300;
var borderWidt:Number = 1;
var spriteWrap:Sprite = new Sprite();
var innerContainer:Sprite = new Sprite();
innerContainer.x = 0;
innerContainer.y = 0;
var line1:Shape = new Shape();
line1.graphics.lineStyle(5, 0x6F4356, 1, false, StageScaleMode.SHOW_ALL, CapsStyle.ROUND);
line1.graphics.moveTo(50, 5);
line1.graphics.lineTo(50, 800);
line1.graphics.endFill();
var line2:Shape = new Shape();
line2.graphics.lineStyle(5, 0x6F4356, 1, false, StageScaleMode.SHOW_ALL, CapsStyle.ROUND);
line2.graphics.moveTo(200, 290);
line2.graphics.lineTo(200, 300);
line2.graphics.endFill();
innerContainer.addChild(line1);
innerContainer.addChild(line2);
spriteWrap.addChild(innerContainer);
return spriteWrap;
}
var spriteWrap:Sprite = getLine();
var wrapForBitmap:Sprite = new Sprite();
var drawBitmap:BitmapData = new BitmapData(300, 300, true, 0x00ffaa);
var goOnStage:Bitmap = new Bitmap(drawBitmap);
wrapForBitmap.graphics.beginBitmapFill(drawBitmap);
wrapForBitmap.graphics.lineStyle(1, 0x6F7E84);
wrapForBitmap.graphics.drawRect(0, 0, 300, 300);
wrapForBitmap.graphics.endFill();
wrapForBitmap.x = 10;
wrapForBitmap.y = 10;
drawBitmap.draw(spriteWrap, new Matrix(1, 0, 0, 1, 0, 0));
wrapForBitmap.addChild(goOnStage);
stage.addChild(wrapForBitmap);
Yes of course. Than I redraw my Bitmap using my Sprite
MySprite.graphics.clear();
MySprite.graphics.beginBitmapFill(MyBitmap, new Matrix(1, 0, 0, 1, new_XPos, new_YPos), false, false);
MySprite.graphics.endFill();
Your Shape line1 is higher than your Bitmap's height (300):
line1.graphics.moveTo(50, 5); // begins at x = 50 and y = 5
line1.graphics.lineTo(50, 800); // begins at x = 50 and y = 800
With the following code, you will draw a line from the top to the bottom of your Bitmap:
line1.graphics.moveTo(50, 0);
line1.graphics.lineTo(50, 300);
If you want line1 to be visible without changing it's height, you have to change your Bitmap's height (800) by modifying the second argument of your BitmapData method:
var drawBitmap:BitmapData = new BitmapData(300, 800, true, 0x00ffaa);
You should modify at the same time your rectangle's height:
wrapForBitmap.graphics.drawRect(0, 0, 300, 800);

Resources