Creating cube with user input using three.js - three.js

I am trying to get a user input from a form and create a cube out of it. Right now it doesn't update the image at all. This is also my first post on here so it's probably going to look like crap.
I'm looking to do this at runtime and have it change based off a single part of the from being changed one at a time.
<script type="text/javascript">
var Warehouse = {
length: 4,
width: 4,
height: 4,
columnBaySpacingL: 0,
columnBaySpacingW: 0,
exteriorConstruction: "",
numberOfDockDoors: 0,
squareFootage: 0,
numberOfParkingSpc: 0
};//end of warehouse object
//create object
Warehouse.length = myForm.elements["LOW"].value;
Warehouse.width = myForm.elements["WOW"].value;
Warehouse.height = myForm.elements["HOW"].value;
Warehouse.columnBaySpacingL = myForm.elements["CBSL"].value;
Warehouse.columnBaySpacingW = myForm.elements["CBSW"].value;
Warehouse.exteriorConstruction = myForm.elements["EXT"].value;
Warehouse.numberOfDockDoors = myForm.elements["NDD"].value;
Warehouse.squareFootage = myForm.elements["SOA"].value;
Warehouse.numberOfParkingSpc = myForm.elements["NPS"].value;
//Warehouse.length = getElementsByName("LOW").value;
//Warehouse.width = getElementById("WOW").value;
//Warehouse.height = getElementById("HOW").value;
//Global vars for Three.js
var container, stats;
var CANVAS_WIDTH = 200;
var CANVAS_HEIGHT = 200;
var camera, scene, renderer;
var cube, plane;
var targetRotation = 0;
var targetRotationOnMouseDown = 0;
var mouseX = 0;
var mouseXOnMouseDown = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
init(Warehouse);
animate();
//Three.js functions
function init(Warehouse) {
//container = document.createElement('div');
container = document.getElementById('canvas');
document.body.appendChild(container);
// var info = document.createElement('div');
// var info = document.getElementById('canvas');
// info.style.position = 'absolute';
// info.style.top = '10px';
// info.style.width = '100%';
// info.style.textAlign = 'center';
// info.innerHTML = 'Drag to spin the warehouse';
// container.appendChild(info);
camera = new THREE.PerspectiveCamera(70, CANVAS_WIDTH / CANVAS_HEIGHT, 1, 1000);
camera.position.y = 150;
camera.position.z = 500;
scene = new THREE.Scene();
// Warehouse
var geometry = new THREE.BoxGeometry(Warehouse.length, Warehouse.width, Warehouse.height);
for (var i = 0; i < geometry.faces.length; i += 2) {
var hex = Math.random() * 0xffffff;
geometry.faces[i].color.setHex(hex);
geometry.faces[i + 1].color.setHex(hex);
}//end for loop
var material = new THREE.MeshBasicMaterial({ vertexColors: THREE.FaceColors, overdraw: 0.5 });
cube = new THREE.Mesh(geometry, material);
cube.position.y = 150;
scene.add(cube);
//Plane
var geometry = new THREE.PlaneBufferGeometry(200, 200);
geometry.rotateX(- Math.PI / 2);
var material = new THREE.MeshBasicMaterial({ color: 0x0e0e0, overdraw: 0.5 });
plane = new THREE.Mesh(geometry, material);
scene.add(plane);
renderer = new THREE.CanvasRenderer();
renderer.setClearColor(0xf0f0f0);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(CANVAS_WIDTH, CANVAS_HEIGHT);
container.appendChild(renderer.domElement);
// stats = new Stats();
// container.appendChild(stats.dom);
document.addEventListener('mousedown', onDocumentMouseDown, false);
document.addEventListener('touchstart', onDocumentTouchStart, false);
document.addEventListener('touchmove', onDocumentTouchMove, false);
window.addEventListener('resize', onWindowResize, false);
}//end init
function onWindowResize() {
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}//end on WindowResize
function onDocumentMouseDown(event) {
event.preventDefault();
document.addEventListener('mousemove', onDocumentMouseMove, false);
document.addEventListener('mouseup', onDocumentMouseUp, false);
document.addEventListener('mouseout', onDocumentMouseOut, false);
mouseXOnMouseDown = event.clientX - windowHalfX;
targetRotationOnMouseDown = targetRotation;
}// end onDocumentMouseDown
function onDocumentMouseMove(event) {
mouseX = event.clientX - windowHalfX;
targetRotation = targetRotationOnMouseDown + (mouseX - mouseXOnMouseDown) * 0.02;
}//end onDocumentMouseMove
function onDocumentMouseUp(event) {
document.removeEventListener('mousemove', onDocumentMouseMove, false);
document.removeEventListener('mouseup', onDocumentMouseUp, false);
document.removeEventListener('mouseout', onDocumentMouseOut, false);
}//end onDocumentMouseUp
function onDocumentMouseOut(event) {
document.removeEventListener(' mousemove', onDocumentMouseMove, false);
document.removeEventListener('mouseup', onDocumentMouseUp, false);
document.removeEventListener('mouseout', onDocumentMouseOut, false);
}//end onDocumentMouseOut
function onDocumentTouchStart(event) {
if (event.touches.length === 1) {
event.preventDefault();
mouseXOnMouseDown = event.touches[0].pageX - windowHalfX;
targetRotationOnMouseDown = targetRotation;
}//end if
}//end onDocumentTouchStart
function onDocumentTouchMove(event) {
if (event.touches.length === 1) {
event.preventDefault();
mouseX = event.touches[0].pageX - windowHalfX;
targetRotation = targetRotationOnMouseDown + (mouseX - mouseXOnMouseDown) * 0.05;
}//end if
}//end onDocumentTouchStart
function animate() {
requestAnimationFrame(animate);
// stats.begin();
render();
// stats.end();
}//end animate
function render() {
plane.rotation.y = cube.rotation.y += (targetRotation - cube.rotation.y) * 0.05;
renderer.render(scene, camera);
}//end render
//Save Button
<div class="panel-body" name="All++GROUP++" style="float: left; width: 50%;">
<form name="myForm">
<div class="platform-form-group ng-scope group" name="WareHouseInfromation++GROUP++">
<button class="promptCollapsebutton" type="button" onclick="ToggleGroupVisibility(this)">-</button><b>Warehouse Information</b>
<!--Grouping for entire prompt-->
<div class="platform-form-row form-group" name="LOW++PROMPT++">
<div class="promptLabel">
LOW
</div>
<div class="promptDescription" name="LOW++DESCRIPTION++">
Length of Warehouse ( Lnft ):
</div>
<div class="promptValue">
<input class="auto-style3" max="16" min="1" name="LOW" step="1" type="number">
</div>
</div>
<div class="platform-form-row form-group" name="WOW++PROMPT++">
<div class="promptLabel">
WOW
</div>
<div class="promptDescription" name="WOW++DESCRIPTION++">
Width of Warehouse ( Lnft ):
</div>
<div class="promptValue">
<input class="auto-style3" max="16" min="1" name="WOW" step="1" type="number">
</div>
</div>
<div class="platform-form-row form-group" name="HOW++PROMPT++">
<div class="promptLabel">
HOW
</div>
<div class="promptDescription" name="HOW++DESCRIPTION++">
Height of Warehouse ( Lnft ):
</div>
<div class="promptValue">
<input class="auto-style3" max="16" min="1" name="HOW" step="1" type="number">
</div>
</div>
<div class="platform-form-row form-group" name="CBSL++PROMPT++">
<div class="promptLabel">
CBSL
</div>
<div class="promptDescription" name="CBSL++DESCRIPTION++">
Column Bay Spacing - Length ( Lnft ):
</div>
<div class="promptValue">
<input class="auto-style3" max="16" min="1" name="CBSL" step="1" type="number">
</div>
</div>
<div class="platform-form-row form-group" name="CBSW++PROMPT++">
<div class="promptLabel">
CBSW
</div>
<div class="promptDescription" name="CBSW++DESCRIPTION++">
Column Bay Spacing - Width ( Lnft ):
</div>
<div class="promptValue">
<input class="auto-style3" max="16" min="1" name="CBSW" step="1" type="number">
</div>
</div>
<div class="platform-form-row form-group" name="EXT++PROMPT++">
<div class="promptLabel">
EXT
</div>
<div class="promptDescription" name="EXT++DESCRIPTION++">
Exterior Construction:
</div>
<div class="promptValue">
<select class="auto-style3" name="EXT" oninput="theInputChanged()">
<option value="0">No exterior</option>
<option value="1">Metal siding</option>
<option value="2">Tiltup</option>
<option value="3">Concrete block</option>
<option value="4">Insulated Panels</option>
</select>
</div>
</div>
<div class="platform-form-row form-group" name="NDD++PROMPT++">
<div class="promptLabel">
NDD
</div>
<div class="promptDescription" name="NDD++DESCRIPTION++">
Number of Dock Doors ( Each ):
</div>
<div class="promptValue">
<input class="auto-style3" max="16" min="1" name="NDD" step="1" type="number">
</div>
</div>
<div class="platform-form-row form-group" name="SOA++PROMPT++">
<div class="promptLabel">
SOA
</div>
<div class="promptDescription" name="SOA++DESCRIPTION++">
Square Footage of Office Area:
</div>
<div class="promptValue">
<input class="auto-style3" max="16" min="1" name="SOA" step="1" type="number">
</div>
</div>
<div class="platform-form-row form-group" name="NPS++PROMPT++">
<div class="promptLabel">
NPS
</div>
<div class="promptDescription" name="CBSW++DESCRIPTION++">
Number of Parking Spaces ( Each ):
</div>
<div class="promptValue">
<input class="auto-style3" max="16" min="1" name="NPS" step="1" type="number">
</div>
</div>
</div>
</form>
</div>

Simple fix, just created a new function that separates the canvas initialization and the shape formation. This then updates with a model for the shape.

Related

Mysterious transparent box blocking mesh renderring

I have a React-Three-Fiber map project i'm working on, but running into a weird bug that I can't isolate.
On desktops the little map works perfectly, but once on Android, a transparent roughly 50(?)px size box in the middle of the viewport shows up and blocks and additional renderring in it until I pan the map past it.
Here's a video of what its doing:
https://youtu.be/4L1I9cZX1OM
Heres the code i'm using:
function App({moduleData}) {
const [floor, setFloor] = useState(1);
const [currentFloor, setCurrentFloor] = useState(floor);
const [riverwalkMap, setRiverwalkMap] = useState(moduleData.floor1.map_image.src);
const [currentPinSet, setCurrentPinSet] = useState('floor1');
const [pinInfo, setPinInfo] = useState()
const [zoomLevel, setZoomLevel] = useState(15);
const [pinHtml, setPinHtml] = useState("");
const [showMap, setShowMap] = useState(true);
const [pinHeader, setPinHeader] = useState("Unit: ");
const [open, setOpen] = useState(false);
const closeModal = () => setOpen(false);
function setPinColor(pinColor){
switch (pinColor){
case "green":
return 'pin_green.png'
case "red":
return 'pin_red.png'
case "yellow":
return 'pin_yellow.png'
default:
return 'pin_green.png'
}
}
function Scene({mapImage}){
const riverwalkMap = useLoader(TextureLoader, mapImage);
return(
<>
<mesh>
<planeGeometry args={[70,50]}/>
<meshBasicMaterial map={riverwalkMap} toneMapped={false}/>
</mesh>
</>
)
}
function Pin({props,pinInfo}){
const [active, setActive] = useState(0);
const [showPopup, setShowPopup] = useState(false);
const [hovered, setHovered] = useState(false);
useEffect(()=>{
document.body.style.cursor = hovered ? 'pointer' : 'auto'
},[hovered])
const { spring } = useSpring({
spring: active,
onChange: () => {
invalidate()
},
config: {mass:5, tension: 400, friction: 50, precision: 0.0001}
})
function returnPinClass(pin){
console.log('pin is: ' + pin);
switch (pin){
case 'available':
return '<span class="greenText">Available</span>';
default:
return '<span class="redText">Sold</span>';
}
}
function returnPinImage(pin){
console.log('pin image is: ' + pin);
return `<img src=${pin.src} alt=${pin.alt}/>`;
}
function setHtml(){
setPinHeader(`<h2>Unit: ${pinInfo.popup_title}</h2>`);
setPinHtml(`
<div class="popupContentBlock">
<div class="contentBlocks">
<div class="contentBlockLeft">
<div class="pdfViewer">
<iframe src="${pinInfo.pdf_file}"></iframe>
</div>
<div class="fractionalDiv">
Download PDF
</div>
</div>
</div>
</div>
`);
}
const scale = spring.to([0,1], [.6,1.25]);
const pinTexture = useLoader(TextureLoader, setPinColor(pinInfo.pin_color));
return(
<>
<a.mesh {...props}
scale-x={scale}
scale-y={scale}
scale-z={scale}
onPointerOver={(e)=> {
setActive(Number(!active));
}}
onPointerOut={(e)=>{
setActive(Number(!active));
}}
onClick={e => {
setHtml();
setOpen(o => !o);
// setShowMap(false);
}}
onPointerMissed={() => {setShowPopup(false)}}
position={[pinInfo.pin_position.x_pos,pinInfo.pin_position.y_pos,0]}
>
<planeGeometry args={[5,5]}/>
<meshBasicMaterial map={pinTexture} toneMapped={false} transparent={true}/>
</a.mesh>
</>
)
}
function setFloorButton(floor) {
setFloor(floor)
floorHeading(floor)
changePins(floor)
setCurrentFloor(floor)
}
function floorHeading(sentFloor) {
switch (sentFloor) {
case 1:
changeMap(moduleData.floor1)
return ReactHtmlParser(moduleData.floor1.heading);
case 2:
changeMap(moduleData.floor2)
return ReactHtmlParser(moduleData.floor2.heading);
case 3:
changeMap(moduleData.floor3)
return ReactHtmlParser(moduleData.floor3.heading);
case 4:
changeMap(moduleData.floor4)
return ReactHtmlParser(moduleData.floor4.heading);
default:
return 'No Floor Selected';
}
}
function changeMap(floorData) {
setRiverwalkMap(floorData.map_image.src);
}
function changePins(sentFloor){
setCurrentPinSet('floor'+sentFloor);
}
function closePop(){
setOpen(false);
}
function drawPins(currentSet){
switch (currentSet){
case 'floor1':
return moduleData.floor1.pins;
case 'floor2':
return moduleData.floor2.pins;
case 'floor3':
return moduleData.floor3.pins;
case 'floor4':
return moduleData.floor4.pins;
}
}
// THREE JS STUFF
// Drop Pins Programmatically
console.log(moduleData);
return (
<div className="cms-react-boilerplate__container">
<div className={"mapInfo"}>
<h1>Floor {currentFloor}</h1>
<p>Floors:</p>
<div className={"buttonSelector"}>
<button onClick={(e) => {
setFloorButton(1);
setPinHtml('');
}}>1</button>
<button onClick={(e) => {
setFloorButton(2);
setPinHtml('');
}}>2</button>
<button onClick={(e) => {
setFloorButton(3);
setPinHtml('');
}}>3</button>
<button onClick={(e) => {
setFloorButton(4);
setPinHtml('');
}}>4</button>
</div>
</div>
<div className={"mapGrid"}>
<div className={"mapDiv"} style={{ border: "2px solid black" }}>
<Canvas linear flat frameloop="demand" orthographic
camera={{position: [0, 0, 20], zoom: zoomLevel, up: [0, 0, 1], far: 10000}}
>
{showMap ? <Suspense fallback={null}>
{
drawPins(currentPinSet).map(e =>
<Pin pinInfo={e}/>
)}
<Scene mapImage={riverwalkMap}/>
</Suspense> : null}
<MapControls enableRotate={false}/>
</Canvas>
</div>
<div className={'infoLeft'} >
{!showMap ?
<div className={"infoGridBlock"}>
{ReactHtmlParser(pinHeader)}
<div className="closeButton" onClick={() => {
setShowMap(true);
setPinHtml('');
}}>
<p>✖</p>
</div>
</div>
: null }
<Popup open={open} closeOnDocumentClick onClose={closeModal} lockScroll={true}>
<div className={"modalBlock"} role="dialog">
<div className={"popupContentDiv"}>
<div className={"popupHeaderLeft"}>{ReactHtmlParser(pinHeader)}</div>
<div className={"popupHeaderRight"}><a onClick={closePop} aria-label="Close Popup">×</a></div>
</div>
{ReactHtmlParser(pinHtml)}
</div>
</Popup>
</div>
</div>
</div>
);
}
export default App;
What i've tried: I tried messing with some CSS but the closest i've gotten is if I force the React-Three-Fiber Canvas tag to have a unset height and width on mobile everything will render but no clickable elements will work.
Thank you for any help!

Capturing multiple image in Vue Js

I have a problem capturing multiple images to my function in vue and pass to the controller. I am trying to modify my blade file which works well when using just the normal form. I am trying to modify to vue but I have a problem with image section. Please assist me on how to achieve this.
my form:
<label for="">Description</label>
<textarea name="description" class="form-control" v-model="description"> </textarea>
<label for="">Images</label>
<input type="file" #change="fieldChange" class="form-control input-sm" name="images[]"
multiple>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
The vue section
data(){
return {
id:'',
price:'',
title:'',
description:'',
location:'',
images:[],
}
},
methods:{
fieldChange(e){
let selectedFiles=e.target.files;
if(!selectedFiles.length){
return false;
}
for(let i=0;i<selectedFiles.length;i++){
this.images.push(selectedFiles[i]);// am able to console the images
}
},
saveImageData(){
var self=this;
axios.post('/senddata',{
title:this.title,
description:this.description,
location:this.location,
images:this.images.file.name,
price:this.price,
})
},
My Laravel function
public function store(Request $request)
{
$product=Products::create([
'title'=>$request['title'],
'description'=>$request['description'],
'price'=>$request['price'],
'location'=>$request['location']
]);
$images= $request->file('images');
foreach ($images as $image){
$move=$image->move(public_path().'/images2/',$image->getClientOriginalName());
if($move){
$imagedata=Images::create([
'title'=>$image->getClientOriginalName(),
'filename'=>$image->getClientOriginalName()
]);
$product->images()->attach([$imagedata->id]);
}
Here is the working code for vuejs part - https://picupload.netlify.app/
https://github.com/manojkmishra/dw_take5/blob/master/src/components/ImageUploader.vue
Vue part
<template>
<div class="uploader"
#dragenter="OnDragEnter"
#dragleave="OnDragLeave"
#dragover.prevent
#drop="onDrop"
:class="{ dragging: isDragging }">
<div class="upload-control" v-show="images.length">
<label for="file">Select files</label>
<button #click="upload">Upload</button>
</div>
<div v-show="!images.length">
<i class="fa fa-cloud-upload"></i>
<p>Drag your images here</p><div>OR</div>
<div class="file-input">
<label for="file">Select files</label>
<input type="file" id="file" #change="onInputChange" multiple>
</div>
</div>
<div class="images-preview" v-show="images.length">
<div class="img-wrapper" v-for="(image, index) in images" :key="index">
<img :src="image" :alt="`Image Uplaoder ${index}`">
<div class="details">
<span class="name" v-text="files[index].name"></span>
<span class="size" v-text="getFileSize(files[index].size)"> </span>
</div>
</div>
</div>
<div v-show="images.length" class="progress">
<div
class="progress-bar progress-bar-info progress-bar-striped"
role="progressbar" :aria-valuenow="progress"
aria-valuemin="0" aria-valuemax="100"
:style="{ width: progress + '%' }"
>
{{ progress}}%
</div>
</div>
</div>
</template>
<script>
import axios from 'axios'
export default
{ data: () => ({ isDragging: false, dragCount: 0, files: [],images: [] ,progress:0}),
methods: {
OnDragEnter(e) { e.preventDefault();
this.dragCount++;
this.isDragging = true;
return false;
},
OnDragLeave(e) { e.preventDefault();
this.dragCount--;
if (this.dragCount <= 0) this.isDragging = false;
},
onInputChange(e) { const files = e.target.files;
Array.from(files).forEach(file => this.addImage(file));
},
onDrop(e) {console.log('ondrop-evnt e=',e)
e.preventDefault();
e.stopPropagation();
this.isDragging = false;
const files = e.dataTransfer.files;
Array.from(files).forEach(file => this.addImage(file));
},
addImage(file) {console.log('addimage file=',file)
if (!file.type.match('image.*')) { this.$toastr.e(`${file.name} is not an image`);
return;
}
this.files.push(file);
const img = new Image(),
reader = new FileReader();
reader.onload = (e) => this.images.push(e.target.result);
reader.readAsDataURL(file);
console.log('addimage this.images=',this.images)
},
getFileSize(size) { const fSExt = ['Bytes', 'KB', 'MB', 'GB'];
let i = 0;
while(size > 900) { size /= 1024; i++; }
return `${(Math.round(size * 100) / 100)} ${fSExt[i]}`;
},
upload() { //this.progress = '0';
const formData = new FormData();
this.files.forEach(file =>
{ formData.append('images[]', file, file.name); });
console.log('upload triggered FormData=',formData)
// resp=axios.post('http://127.0.0.1:8000/sendemail1',this.formData);
// axios.post('http://127.0.0.1:8000/api/imagesupload', formData,
axios.post('https://uat.oms.dowell.com.au/api/imagesupload', formData,
{onUploadProgress:uploadEvent=>{ this.progress=Math.round(uploadEvent.loaded/uploadEvent.total*100);
console.log('upld prges:'+ Math.round(uploadEvent.loaded/uploadEvent.total*100)+'%')
}
})
//axios.post('https://uat.oms.dowell.com.au/api/imagesupload', formData)
.then(response => {
this.$toastr.s('All images uplaoded successfully');
this.images = [];
this.files = [];
this.progress = 0;
})
.catch(() => {
this.$toastr.e('Could not upload the files!');
this.images = [];
this.files = [];
this.progress = 0;
});
}
}
}
</script>
Another version with vuetify
https://github.com/manojkmishra/take5-front-admin/blob/master/src/components/img/imgup.vue
Here is laravel part
public function imagesupload(Request $request){
if (count($request->images)) {
foreach ($request->images as $image) {
$image->store('images');
}
}
return response()->json(["message" => "Done"]);
}
Another way in laravel is here
https://github.com/manojkmishra/take5-api/blob/master/app/Http/Controllers/PicController.php

Display original (conditional) brushed unbrushed crossfilter bars with dc.js with different colors

Say we have the following crossfilter / dc.js app:
While this is nice, the user loses "reference" the population when brushing. I would like for charts x, y, z, and a to keep the "underlying" bars when other charts are brushed. Perhaps in a different color like so:
I believe this may require updating the dc.renderAll() function, but I am not sure even how to start.
Here is all the code to reproduce this app with the .csv data hosted as a gist.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Data Exploration Tool MVP</title>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"/>
<link rel="stylesheet" href="http://unpkg.com/dc#3/dc.css"/>
<style>
#data-count {
margin-top: 0;
text-align: left;
float: none;
}
table {
table-layout: fixed;
}
td {
width: 1%;
}
</style>
</head>
<body>
<div class="container-fluid" style="margin: 10px;">
<div class="row">
<h2>Data Exploration Tool</h2>
<div class="col-md-3 well well-sm">
<div class="dc-data-count" id="data-count">
<span class="filter-count"></span>
selected out of
<span class="total-count"></span>
points |
Reset All<br>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<!-- First row of charts -->
<div class="row">
<div class="col-md-3">
<div id="chart-11" style="width:100%;">
<div id="chart-11-title"></div>
<div class="reset" style="visibility: hidden;">range: <span class="filter"></span>
reset
</div>
</div>
</div>
<div class="col-md-3">
<div id="chart-12" style="width:100%;">
<div id="chart-12-title"></div>
<div class="reset" style="visibility: hidden;">selected: <span class="filter"></span>
reset
</div>
</div>
</div>
<div class="col-md-3">
<div id="chart-13" style="width:100%;">
<div id="chart-13-title"></div>
<div class="reset" style="visibility: hidden;">selected: <span class="filter"></span>
reset
</div>
</div>
</div>
<div class="col-md-3">
<div id="chart-14" style="width:100%;">
<div id="chart-14-title"></div>
<div class="reset" style="visibility: hidden;">selected: <span class="filter"></span>
reset
</div>
</div>
</div>
</div>
<!-- Second row of chart -->
<div class="row">
<div class="col-md-3">
<div id="chart-21" style="width:100%;">
<div id="chart-21-title"></div>
<div class="reset" style="visibility: hidden;">selected: <span class="filter"></span>
reset
</div>
</div>
</div>
<div class="col-md-3">
<div id="chart-22" style="width:100%;">
<div id="chart-22-title"></div>
<div class="reset" style="visibility: hidden;">range: <span class="filter"></span>
reset
</div>
</div>
</div>
<div class="col-md-3">
<div id="chart-23"style="width:100%;">
<div id="chart-23-title"></div>
<div class="reset" style="visibility: hidden;">selected: <span class="filter"></span>
reset
</div>
</div>
</div>
<div class="col-md-3">
<div id="chart-24"style="width:100%;">
<div id="chart-24-title"></div>
<div class="reset" style="visibility: hidden;">selected: <span class="filter"></span>
reset
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.9.1/d3.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crossfilter/1.3.12/crossfilter.js"></script>
<script src="http://unpkg.com/dc#3/dc.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js"></script>
<script type="text/javascript">
'use strict';
dc.config.defaultColors(d3.schemeSet1);
var
chart_11 = dc.barChart("#chart-11"),
chart_12 = dc.barChart("#chart-12"),
chart_13 = dc.barChart("#chart-13"),
chart_21 = dc.barChart("#chart-21"),
chart_22 = dc.barChart("#chart-22"),
chart_23 = dc.barChart("#chart-23"),
data_count = dc.dataCount(".dc-data-count");
d3.csv("https://gist.githubusercontent.com/JasonAizkalns/32ece5c815f9ac5d540c41dc0825bbab/raw/362050300ddcb99f195044c00d9f26b0d7d489ca/data.csv").then(function(data) {
var var_names = ["x", "y", "z", "a", "b", "c"];
$("#chart-11-title").append(["<h5>", var_names[0], "<br>Subtitle</h5>"].join(""));
$("#chart-12-title").append(["<h5>", var_names[1], "<br>Subtitle</h5>"].join(""));
$("#chart-13-title").append(["<h5>", var_names[2], "<br>Subtitle</h5>"].join(""));
$("#chart-21-title").append(["<h5>", var_names[3], "<br>Subtitle</h5>"].join(""));
$("#chart-22-title").append(["<h5>", var_names[4], "<br>Subtitle</h5>"].join(""));
$("#chart-23-title").append(["<h5>", var_names[5], "<br>Subtitle</h5>"].join(""));
var c11_bin = 10,
c12_bin = 10,
c13_bin = 500,
c21_bin = 100,
c22_bin = 20,
c23_bin = 1000;
var ndx = crossfilter(data),
chart_11_dim = ndx.dimension(function(d) { return +d[var_names[0]]; }),
chart_12_dim = ndx.dimension(function(d) { return +d[var_names[1]]; }),
chart_13_dim = ndx.dimension(function(d) { return +d[var_names[2]]; }),
chart_21_dim = ndx.dimension(function(d) { return +d[var_names[3]]; }),
chart_22_dim = ndx.dimension(function(d) { return +d[var_names[4]]; }),
chart_23_dim = ndx.dimension(function(d) { return +d[var_names[5]]; }),
chart_11_grp = chart_11_dim.group(function(d) { return Math.floor(d / c11_bin) * c11_bin }).reduceCount(),
chart_12_grp = chart_12_dim.group(function(d) { return Math.floor(d / c12_bin) * c12_bin }).reduceCount(),
chart_13_grp = chart_13_dim.group(function(d) { return Math.floor(d / c13_bin) * c13_bin }).reduceCount(),
chart_21_grp = chart_21_dim.group(function(d) { return Math.floor(d / c21_bin) * c21_bin }).reduceCount(),
chart_22_grp = chart_22_dim.group(function(d) { return Math.floor(d / c22_bin) * c22_bin }).reduceCount(),
chart_23_grp = chart_23_dim.group(function(d) { return Math.floor(d / c23_bin) * c23_bin }).reduceCount();
var all = ndx.groupAll();
data_count.dimension(ndx)
.group(all);
var chart_11_min = +chart_11_dim.bottom(1)[0][var_names[0]],
chart_11_max = +chart_11_dim.top(1)[0][var_names[0]],
chart_12_min = +chart_12_dim.bottom(1)[0][var_names[1]],
chart_12_max = +chart_12_dim.top(1)[0][var_names[1]],
chart_13_min = +chart_13_dim.bottom(1)[0][var_names[2]],
chart_13_max = +chart_13_dim.top(1)[0][var_names[2]],
chart_21_min = +chart_21_dim.bottom(1)[0][var_names[3]],
chart_21_max = +chart_21_dim.top(1)[0][var_names[3]],
chart_22_min = +chart_22_dim.bottom(1)[0][var_names[4]],
chart_22_max = +chart_22_dim.top(1)[0][var_names[4]],
chart_23_min = +chart_23_dim.bottom(1)[0][var_names[5]],
chart_23_max = +chart_23_dim.top(1)[0][var_names[5]];
var breathing_room = 0.05;
chart_11
.dimension(chart_11_dim)
.group(chart_11_grp)
.round(dc.round.floor)
.alwaysUseRounding(true)
.x(d3.scaleLinear().domain([chart_11_min - ((chart_11_max - chart_11_min) * breathing_room), chart_11_max + ((chart_11_max - chart_11_min) * breathing_room)]))
.xUnits(function(start, end, xDomain) { return (end - start) / c11_bin; })
.controlsUseVisibility(true);
chart_12
.dimension(chart_12_dim)
.group(chart_12_grp)
.round(dc.round.floor)
.alwaysUseRounding(true)
.x(d3.scaleLinear().domain([chart_12_min - ((chart_12_max - chart_12_min) * breathing_room), chart_12_max + ((chart_12_max - chart_12_min) * breathing_room)]))
.xUnits(function(start, end, xDomain) { return (end - start) / c12_bin; })
.controlsUseVisibility(true);
chart_13
.dimension(chart_13_dim)
.group(chart_13_grp)
.round(dc.round.floor)
.alwaysUseRounding(true)
.x(d3.scaleLinear().domain([chart_13_min - ((chart_13_max - chart_13_min) * breathing_room), chart_13_max + ((chart_13_max - chart_13_min) * breathing_room)]))
.xUnits(function(start, end, xDomain) { return (end - start) / c13_bin; })
.controlsUseVisibility(true);
chart_21
.dimension(chart_21_dim)
.group(chart_21_grp)
.round(dc.round.floor)
.alwaysUseRounding(true)
.x(d3.scaleLinear().domain([chart_21_min - ((chart_21_max - chart_21_min) * breathing_room), chart_21_max + ((chart_21_max - chart_21_min) * breathing_room)]))
.xUnits(function(start, end, xDomain) { return (end - start) / c21_bin; })
.controlsUseVisibility(true);
chart_22
.dimension(chart_22_dim)
.group(chart_22_grp)
.round(dc.round.floor)
.alwaysUseRounding(true)
.x(d3.scaleLinear().domain([chart_22_min - ((chart_22_max - chart_22_min) * breathing_room), chart_22_max + ((chart_22_max - chart_22_min) * breathing_room)]))
.xUnits(function(start, end, xDomain) { return (end - start) / c22_bin; })
.controlsUseVisibility(true);
chart_23
.dimension(chart_23_dim)
.group(chart_23_grp)
.round(dc.round.floor)
.alwaysUseRounding(true)
.x(d3.scaleLinear().domain([chart_23_min - ((chart_23_max - chart_23_min) * breathing_room), chart_23_max + ((chart_23_max - chart_23_min) * breathing_room)]))
.xUnits(function(start, end, xDomain) { return (end - start) / c23_bin; })
.controlsUseVisibility(true);
dc.renderAll();
});
</script>
</div>
</body>
</html>
So yeah, neither dc.js nor crossfilter directly supports this use case, not that people don't want it.
Crossfilter only supports one active filter and gives you no way to find out what the totals were when no filters were applied.
EDIT: there is now an official example with code cleaned up in response to the follow up code review question. The below discussion still describes the technique well, but the code is less repetitive in the example.
Thanks for the reproducible example to start with. I put your original code in a fiddle.
It's a little tedious, but one way to get the affect you are after is to change each chart into a composite of two bar charts. We'll make the second subchart red and hide it until something is filtered. (More precisely, we'll hide it whenever there is nothing filtered.)
And we'll make the first (blue) subchart always show the initial values, not affected by any filters.
Creating a composite chart looks like this:
var chart_11 = dc.compositeChart("#chart-11"),
chart_12 = dc.compositeChart("#chart-12"),
chart_13 = dc.compositeChart("#chart-13"),
chart_21 = dc.compositeChart("#chart-21"),
chart_22 = dc.compositeChart("#chart-22"),
chart_23 = dc.compositeChart("#chart-23");
chart_11
.compose([
dc.barChart(chart_11)
.dimension(chart_11_dim)
.group(chart_11_grp_copy)
.controlsUseVisibility(true)
,
dc.barChart(chart_11)
.dimension(chart_11_dim)
.group(chart_11_grp)
.colors('red')
.controlsUseVisibility(true)
.brushOn(false)
]);
(Yes it seems you have to apply controlsUseVisibility to every child chart - looks like a bug.)
The heart of the problem is how to make the underlying blue chart not change. We can use a
fake group for this. The idea is this object acts like a group except it just returns what the group had on page load:
function static_copy_group(group) {
var all = group.all().map(kv => ({key: kv.key, value: kv.value}));
return {
all: function() {
return all;
}
}
}
var chart_11_grp_copy = static_copy_group(chart_11_grp),
chart_12_grp_copy = static_copy_group(chart_12_grp),
chart_13_grp_copy = static_copy_group(chart_13_grp),
chart_21_grp_copy = static_copy_group(chart_21_grp),
chart_22_grp_copy = static_copy_group(chart_22_grp),
chart_23_grp_copy = static_copy_group(chart_23_grp);
Yes, that's a deep copy of group.all() because crossfilter updates everything in place.
Finally, here's the code to hide the second chart when nothing is filtered:
function any_filters() {
return [chart_11, chart_12, chart_13, chart_21, chart_22, chart_23]
.some(chart => chart.filters().length);
}
function hide_second_chart(chart) {
chart.select('.sub._1')
.attr('visibility', any_filters() ? 'visible' : 'hidden')
}
[chart_11, chart_12, chart_13, chart_21, chart_22, chart_23].forEach(function(chart) {
chart.on('pretransition', hide_second_chart)
})
Example fiddle.

isotope filter using value on divs with data-*

Im trying to filter divs by data attribute rather than class using isotope... im not sure how isotope works and there appears to be nothing in the documentation that references filtering data attributes and not just classes?!
Im sure i will slap my self with the answer...
but this is as far as I have got:
var $grid = $('.isotope').isotope({
itemSelector: '.isotope-item'
});
$('#item-filter-select').on('change', function () {
var el = this.value;
$grid.isotope({ filter: el });
});
<div id="filters">
<h4>Geschenkideen</h4>
<select id="item-filter-select">
<option value="*" >Show All</option>
<option value="clothes" >Clothing</option>
<option value="jewelry" >Jewelry</option>
<option value="misc" >Miscellaneous</option>
</select>
</div>
<div class="isotope">
<div class="isotope-item" data-price="23" data-type="misc">
<img src="http://unit60.com/vendo/img/shop/1.jpg" />23
</div>
<div class="isotope-item" data-price="400" data-type="misc">
<img src="http://unit60.com/vendo/img/shop/2.jpg" />400
</div>
<div class="isotope-item" data-price="12" data-type="jewelry">
<img src="http://unit60.com/vendo/img/shop/3.jpg" />12
</div>
<div class="isotope-item clothes" data-price="8" data-type="clothes">
<img src="http://unit60.com/vendo/img/shop/4.jpg" />8
</div>
<div class="isotope-item" data-price="144" data-type="misc">
<img src="http://unit60.com/vendo/img/shop/5.jpg" />144
</div>
<div class="isotope-item" data-price="70" data-type="misc">
<img src="http://unit60.com/vendo/img/shop/6.jpg" />70
</div>
<div class="isotope-item" data-price="445" data-type="jewlery">
<img src="http://unit60.com/vendo/img/shop/3.jpg" />445
</div>
<div class="isotope-item" data-price="64" data-type="misc">
<img src="http://unit60.com/vendo/img/shop/2.jpg" />64
</div>
<div class="isotope-item" data-price="21" data-type="misc">
<img src="http://unit60.com/vendo/img/shop/5.jpg" />21
</div>
<div class="isotope-item" data-price="82.50" data-type="misc">
<img src="http://unit60.com/vendo/img/shop/1.jpg" />82.50
</div>
<div class="isotope-item" data-price="25" data-type="jewelry">
<img src="http://unit60.com/vendo/img/shop/3.jpg" />25
</div>
<div class="isotope-item" data-price="100" data-type="misc">
<img src="http://unit60.com/vendo/img/shop/6.jpg" />100
</div>
<div class="isotope-item" data-price="30" data-type="misc">
<img src="http://unit60.com/vendo/img/shop/2.jpg" />30
</div>
</div>
codepen:
http://codepen.io/unit60/pen/vXyAzj
HELLLLP!!! :)
ok... I have one answer that works, probably not the most elegant but here we go:
var $grid = $('.isotope').isotope({
itemSelector: '[data-type]'
});
$('#item-filter-select').change( function () {
var el = this.value;
var fel;
if(el!='*'){
fel = "[data-type='" + el + "']"
}else{
fel = "*"
}
$grid.isotope({ filter: fel });
});
Yay... I changed the code a bit so that I could combine filters:
var filters = {};
$('.item-filter-select').on( 'change',function() {
var $this = $('option:selected');
var $parent = $(this);
var level = $(this).parent().find('select option:selected');
// get group key
var $buttonGroup = $parent.parents('.select-group');
var filterGroup = $buttonGroup.attr('data-filter-group');
// set filter for group
filters[ filterGroup ] = level.data('value');
// combine filters
var filterValue = concatValues( filters );
$grid.isotope({ filter: filterValue });
});
// flatten object by concatting values
function concatValues( obj ) {
var value = '';
for ( var prop in obj ) {
value += obj[ prop ];
}
return value;
}
Updated codepen: http://codepen.io/unit60/pen/ORbdWE

put canvas in custom div?

I started developing from an example that shows to integrate three.js + greensock.
Link: http://www.kadrmasconcepts.com/blog/2012/05/29/greensock-three-js/
I am trying to put canvas used by three.js + greensock to a div inside my page designed. But canvas always gets appended to bottom of screen. I tried to do getelementbyid and access my div object but did not work.
Current:
https://www.dropbox.com/s/kowowsjvdnwkl0f/bart.png?dl=0
As current implementation shows canvas is below blue panel but want it to be inside red panel (div).
Can someone help me fix it. I am attaching my code below...Thank you very much in advance!
php
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Horse Demo</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="author" content="Jason Kadrmas" />
<!-- Bootstrap Core CSS -->
<link href="bower_components/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- MetisMenu CSS -->
<link href="bower_components/metisMenu/dist/metisMenu.min.css" rel="stylesheet">
<!-- Timeline CSS -->
<link href="css/timeline.css" rel="stylesheet">
<!-- Custom CSS -->
<link href="css/sb-admin-2.css" rel="stylesheet">
<!-- Morris Charts CSS -->
<link href="bower_components/morrisjs/morris.css" rel="stylesheet">
<!-- Custom Fonts -->
<link href="bower_components/font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css">
<!-- jQuery -->
<script src="bower_components/jquery/dist/jquery.min.js"></script>
<!-- Bootstrap Core JavaScript -->
<script src="bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
<!-- Metis Menu Plugin JavaScript -->
<script src="bower_components/metisMenu/dist/metisMenu.min.js"></script>
<!-- Morris Charts JavaScript -->
<script src="bower_components/raphael/raphael-min.js"></script>
<script src="bower_components/morrisjs/morris.min.js"></script>
<script src="js/morris-data.js"></script>
<!-- Custom Theme JavaScript -->
<script src="js/sb-admin-2.js"></script>
<link href='http://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic' rel='stylesheet' type='text/css'>
<link href='css/simple.css' rel='stylesheet' type='text/css'>
<script type="text/javascript" src="js/lib/plugins/CSSPlugin.min.js"></script>
<script type="text/javascript" src="js/lib/easing/EasePack.min.js"></script>
<script type="text/javascript" src="js/lib/TimelineLite.min.js"></script>
<script type="text/javascript" src="js/lib/TweenLite.min.js"></script>
<!--<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.min.js"></script>-->
<script type="text/javascript" src="js/lib/Three.js"></script>
<script type="text/javascript" src="js/ThreeScene.js"></script>
</head>
<body>
<div class="wrapper">
<!-- <div class="navbar-inner">
<div class="container">
<span class="btn-navheader">Timeline Demo - Horse</span>
Reset
Pause
Start
</div>
</div>-->
<!-- Navigation -->
<nav class="navbar navbar-default navbar-static-top" role="navigation" style="margin-bottom: 0">
<div class="navbar-header">
<a class="navbar-brand">Balloon Task v1.0</a>
</div>
<!-- /.navbar-header -->
</nav>
<div class="container-fluid">
<div class="row">
<div class="col-lg-3 col-md-6">
<div class="panel panel-primary">
<div class="panel-heading">
<div class="row">
<div class="col-xs-6 text-left">
<div class="">Balloon Number</div>
</div>
<div class="col-xs-6 text-right">
<div class="huge">1/30</div>
</div>
</div>
</div>
<a href="#">
<div class="panel-footer">
<span class="pull-left">View Details</span>
<div class="clearfix"></div>
</div>
</a>
</div>
</div>
<div class="col-lg-9 col-md-18">
<div class="panel panel-red">
<div class="panel-heading">
<div class="row">
<div id="taskcanvas" class="canvas">
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row bottom-container">
<div class="col-md-12">
<span>Timeline Demo - Horse</span>
Reset
Pause
Start
</div>
</div>
</div>
</div>
<!-- /#wrapper -->
<script language="javascript" type="text/javascript">
var width = 500,
height = 500,
camera,
scene,
renderer,
SHADOW_MAP_WIDTH = 2048,
SHADOW_MAP_HEIGHT = 2048,
dominoGeometry,
dominoMaterial,
dominoPos = -180,
tweens = [],
type = 0,
d = 8,
basicScene,
tl = new TimelineLite({onComplete: complete});
init();
function init() {
basicScene = new THREE.BasicScene({width: width, height: height});
TweenLite.ticker.addEventListener("tick", render);
initObjects();
}
// Horse morph variables.
var horse;
var paused = true;
var theta = 0;
var duration = 2100;
var keyframes = 15, interpolation = duration / keyframes;
var lastKeyframe = 0, currentKeyframe = 0;
function render() {
basicScene.renderer.render(basicScene.scene, basicScene.camera);
if (horse && !paused) {
// Alternate morph targets
var time = Date.now() % duration;
var keyframe = Math.floor(time / interpolation);
if (keyframe != currentKeyframe) {
horse.morphTargetInfluences[ lastKeyframe ] = 0;
horse.morphTargetInfluences[ currentKeyframe ] = 1;
horse.morphTargetInfluences[ keyframe ] = 0;
lastKeyframe = currentKeyframe;
currentKeyframe = keyframe;
}
horse.morphTargetInfluences[ keyframe ] = (time % interpolation) / interpolation;
horse.morphTargetInfluences[ lastKeyframe ] = 1 - horse.morphTargetInfluences[ keyframe ];
}
}
function initObjects() {
dominoGeometry = new THREE.CubeGeometry(100, 100, 100, 1, 1, 1);
dominoMaterial = new THREE.MeshPhongMaterial();
dominoMaterial.color = new THREE.Color().setRGB(1, 1, 1);
dominoMaterial.ambient = new THREE.Color().setRGB(0.0196078431372549, 0.0196078431372549, 0.0196078431372549);
dominoMaterial.specular = new THREE.Color().setRGB(0.06666666666666667, 0.06666666666666667, 0.06666666666666667);
var light = new THREE.DirectionalLight();
light.intensity = 0.7;
light.castShadow = true;
light.position.set(-320, 350, 100);
basicScene.add(light);
// Floor
var geometry = new THREE.PlaneGeometry(1800, 800, 3, 3);
var material = new THREE.MeshPhongMaterial({color: 0xffffff, wireframe: false});
material.ambient = new THREE.Color().setRGB(0.0196078431372549, 0.0196078431372549, 0.0196078431372549);
material.specular = new THREE.Color().setRGB(0.06666666666666667, 0.06666666666666667, 0.06666666666666667);
var mesh = new THREE.Mesh(geometry, material);
mesh.receiveShadow = true;
mesh.position.set(0, -50, 0);
basicScene.add(mesh);
initDominoes();
initHorse();
}
function initDominoes() {
var mesh, i;
for (i = 0; i < 4; i++) {
mesh = new THREE.Mesh(dominoGeometry, dominoMaterial);
mesh.position.set(dominoPos, 0, 0);
mesh.rotationAutoUpdate = false;
mesh.castShadow = true;
mesh.receiveShadow = false;
mesh.scale.set(0.1, 1, 0.4);
basicScene.add(mesh);
dominoPos += 50;
tweens.push(TweenLite.to(mesh.rotation, 2, {y: Math.PI * 2, ease: Bounce.easeOut, delay: d * 0.1 + i * 0.2}));
}
}
function initHorse() {
var loader = new THREE.JSONLoader(true);
loader.load("models/horse.js", function (geometry) {
horse = new THREE.Mesh(geometry, new THREE.MeshLambertMaterial({color: 0x0aa8a5, morphTargets: true}));
horse.scale.set(0.75, 0.75, 0.75);
horse.position.set(-600, -50, 0);
horse.rotation.y = Math.PI / 2;
basicScene.add(horse);
// Click handlers
$('.start').on('click', start).show();
$('.pause').on('click', pause).show();
$('.reset').on('click', complete).show();
// Horse
tweens.push(TweenLite.to(horse.position, d, {x: 900}));
tweens.push(TweenLite.to(horse.position, d * 0.1, {y: 150, delay: d * 0.07, ease: Sine.easeOut}));
tweens.push(TweenLite.to(horse.position, d * 0.12, {y: -50, delay: d * 0.18, ease: Sine.easeIn}));
tl.insertMultiple(tweens);
tl.pause();
});
}
function pause() {
paused = true;
tl.pause();
}
function start() {
paused = false;
tl.play();
}
function complete() {
pause();
tl.progress(0);
}
</script>
</body>
</html>
JS:
THREE.BasicScene = function( args ) {
var container = document.getElementById( "taskcanvas" );
var _this = this;
this.width = args.width;
this.height = args.height;
// Setup scene, camera, and renderer
this.scene = new THREE.Scene();
this.camera = initCamera( this.scene );
this.renderer = initRenderer();
container.appendChild( this.renderer.domElement );
container = document.body.appendChild( container );
container.appendChild( this.renderer.domElement );
function initCamera( scene ) {
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.z = 380;
camera.aspect = _this.width / _this.height;
camera.updateProjectionMatrix();
scene.add( camera );
return camera;
}
function initRenderer() {
var renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( _this.width, _this.height );
renderer.shadowCameraNear = 3;
renderer.shadowCameraFar = _this.camera.far;
renderer.shadowCameraFov = 50;
renderer.shadowMapBias = 0.0039;
renderer.shadowMapDarkness = 0.3;
renderer.shadowMapWidth = SHADOW_MAP_WIDTH;
renderer.shadowMapHeight = SHADOW_MAP_HEIGHT;
renderer.shadowMapEnabled = true;
renderer.shadowMapSoft = true;
return renderer;
}
};
THREE.BasicScene.prototype = {
add: function( obj ) {
this.scene.add( obj );
}
};
CSS:
canvas {
background-image: -webkit-linear-gradient(top, #cee4ff, #fff3e1);
background-image: linear-gradient(to bottom, #cee4ff, #fff3e1);
background-image: -moz-linear-gradient(top, #cee4ff, #fff3e1); //FF3.6+
background-image: -ms-linear-gradient(top, #cee4ff, #fff3e1); //IE10
background-image: -o-linear-gradient(top, #cee4ff, #fff3e1); //Opera 11.10+
}
You might have moved container out by accident
container = document.body.appendChild( container );
container.appendChild( this.renderer.domElement );
Will cause the container to be on body, which will show up at the bottom.
#Vinay had the right answer, you can give the renderer constructor a canvas so you can make your own canvas in the container, then pass that canvas directly to the renderer.

Resources